使用matplotlib绘制对数2D直方图

3
这是我的第一个Python程序,所以我的程序中可能有一些“有趣”的地方。该程序从给定目录中读取3列文件,然后为每个文件计算直方图,将结果添加到二维矩阵中,以创建类似于2D-Hist的东西。
我的困难在于我的第三个图中,我希望y轴数据按对数比例尺展示。此外,我想删除输入条目中的“零”条目。我尝试使用numpy.where(matrix)来实现这一点,但我不知道它是否真正实现了我想要的...
这是我的代码:
#!/usr/bin/python
# Filename: untitled.py
# encoding: utf-8

from __future__ import division
from matplotlib.colors import LogNorm
import matplotlib
import numpy as np
import matplotlib.pylab as plt
import os
import matplotlib.cm as cm

def main():

   dataFiles = [filename for filename in os.listdir(".") if (filename[-4:]==".log" and filename[0]!='.')]
   dataFiles.sort()

   p = []
   matrix1 = []
   matrix2 = []
   matrix3 = []

   for dataFile in dataFiles:
            p += [ eval(dataFile[11:16]) ]
            data = np.loadtxt(dataFile, skiprows=7)[:,1:4]

            matrix1 += [ data[:,0] ]
            matrix2 += [ data[:,1] ]
            matrix3 += [ data[:,2] ]

    matrixList = [matrix1, matrix2, matrix3]

    #make histograms out of the matrices
    matrix1Hist = [  np.histogram( matrixColumn, bins=30,  range=(np.min(np.where(matrix1 != 0)), np.max(matrix1)))[0]   for matrixColumn in matrix1 ]
    matrix2Hist = [  np.histogram( matrixColumn, bins=200, range=(np.min(np.where(matrix2 != 0)), np.max(matrix2)))[0]   for matrixColumn in matrix2 ]
    matrix3Hist = [  np.histogram( matrixColumn, bins=50,  range=(np.min(np.where(matrix3 != 0)), np.max(matrix3)))[0]   for matrixColumn in matrix3 ]

    # convert the matrixHistogramsto numpy arrays and swap axes
    matrix1Hist = np.array(matrix1Hist).transpose()
    matrix2Hist = np.array(matrix2Hist).transpose()
    matrix3Hist = np.array(matrix3Hist).transpose() 

    matrixHistList = [matrix1Hist, matrix2Hist, matrix3Hist]

    fig = plt.figure(0)
    fig.clf()

    for i,matrixHist in enumerate( [matrix1Hist, matrix2Hist, matrix3Hist] ):
            ax = fig.add_subplot(2, 2, i+1)
            ax.grid(True)
            ax.set_title('matrix'+str(i+1))
            if i < 2:
                   result = ax.imshow(matrixHist,
                                      cmap=cm.gist_yarg,
                                      origin='lower',
                                      aspect='auto', #automatically span matrix to available space
                                      interpolation='hanning',
                                      extent= [ p[0], p[-1], np.floor( np.min( matrixList[i])), np.ceil( np.max( matrixList[i])) ] ,
                                      )

            elif i == 2:
                    result = ax.imshow(matrixHist,
                                       cmap=cm.gist_yarg,
                                       origin='lower',
                                       aspect='auto', #automatically span matrix to available space
                                       interpolation='hanning',
                                       extent= [ p[0], p[-1], 1, np.log10(np.max( matrixList[i])) ] ,
                                       )


            ticks_at = [ 0 , abs(matrixHist).max()]
            fig.colorbar(result, ticks=ticks_at,format='%1.2g')


    plt.show()


if __name__ == '__main__':
    main()

你确定这是你的第一个Python程序吗?看着你的Python代码,它似乎写得非常好,而且LogNorm已经被导入但没有使用。我刚刚做了一些作业吗?;-) - Brendan
可能是使用hist2d在matplotlib中创建对数线性图的重复问题。 - danijar
1个回答

4
对于第一个问题,您有以下选项: 对于第二个问题 - 关于从数组中过滤零值 - 尝试: my_array = my_array[my_array != 0] my_array != 0 创建了一个由 TrueFalse 组成的逻辑数组,然后在切片中使用。但是,这将返回一个一维数组,这可能不是您想要的。要将值设置为其他值(并保持2D形状),请使用以下方法(值设置为 NaN)...

my_array[my_array != 0] = np.NaN


1
谢谢您的回答。当我试图找到解决此日志问题的方法时,我也找到了您在此处提供的链接,但是 set_yscale('log') 的解决方法不幸地不能与 imshow 一起使用。 - Eagle
2
啊,好的,“histogram”被呈现为彩色图?如果是这样,您可以将 cmap 改为一个对数比例尺。我不知道怎么做,但这是可以做到的… - Brendan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接