【问题标题】:Defining bin width/x-axis scale in Matplotlib histogram在 Matplotlib 直方图中定义 bin 宽度/x 轴比例
【发布时间】:2012-08-29 10:58:06
【问题描述】:

我正在使用 matplotlib 生成直方图。

我需要垃圾箱的宽度不等,因为我最感兴趣的是最低的垃圾箱。 现在我正在这样做:

plt.hist(hits_array, bins = (range(0,50,10) + range(50,550,50)))

这会创建我想要的(前 5 个 bin 的宽度为 10,其余 50 个),但是前五个 bin 当然比后面的更窄,因为所有 bin 都显示在同一轴上.

有没有办法影响 x 轴或直方图本身,这样我就可以在前 5 个 bin 之后打破比例,所以所有 bin 都显示为同样宽?

(我意识到这会产生扭曲的视图,我对此很好,但我不介意轴的两个不同比例部分之间有一点空间。)

任何帮助将不胜感激。 谢谢!

【问题讨论】:

    标签: matplotlib axis


    【解决方案1】:

    我在这里有一个类似的问题,答案是使用肮脏的黑客。 Matplotlib histogram with collection bin for high values

    所以使用下面的代码,你会得到你已经拥有的丑陋的直方图。

    def plot_histogram_04():
        limit1, limit2 = 50, 550
        binwidth1, binwidth2 = 10, 50    
        data = np.hstack((np.random.rand(1000) * limit1, np.random.rand(100) * limit2))
    
        bins = range(0, limit1, binwidth1) + range(limit1, limit2, binwidth2)
    
        plt.subplots(1, 1)
        plt.hist(data, bins=bins)
        plt.savefig('my_plot_04.png')
        plt.close()
    

    为了让箱子等宽,你确实必须让它们等宽!这意味着要处理您的数据,使它们都落在等宽的 bin 中,然后使用 xlabel。

    def plot_histogram_05():
        limit1, limit2 = 50, 550
        binwidth1, binwidth2 = 10, 50
    
        data = np.hstack((np.random.rand(1000) * limit1, np.random.rand(100) * limit2))
    
        orig_bins = range(0, limit1, binwidth1) + range(limit1, limit2 + binwidth2, binwidth2)
        data = [(i - limit1) / (binwidth2 / binwidth1) + limit1 
                if i >= limit1 else i for i in data]
        bins = range(0, limit2 / (binwidth2 / binwidth1) + limit1, binwidth1)
    
        _, ax = plt.subplots(1, 1)
        plt.hist(data, bins=bins)
    
        xlabels = np.array(orig_bins, dtype='|S3')
        N_labels = len(xlabels)
        print xlabels
        print bins
        plt.xlim([0, bins[-1]])
        plt.xticks(binwidth1 * np.arange(N_labels))
        ax.set_xticklabels(xlabels)
    
        plt.savefig('my_plot_05.png')
        plt.close()
    

    【讨论】:

      【解决方案2】:

      你可以使用bar,不需要拆分轴。这是一个例子,

      import matplotlib.pylab as plt
      import numpy as np
      
      data = np.hstack((np.random.rand(1000)*50,np.random.rand(100)*500))
      binwidth1,binwidth2=10,50
      bins=range(0,50,binwidth1)+range(50,550,binwidth2)
      
      fig,(ax) = plt.subplots(1, 1)
      
      y,binEdges=np.histogram(data,bins=bins)
      
      ax.bar(0.5*(binEdges[1:]+binEdges[:-1])[:5], y[:5],width=.8*binwidth1,align='center')
      ax.bar(0.5*(binEdges[1:]+binEdges[:-1])[5:], y[5:],width=.8*binwidth1,align='center')
      plt.show()
      

      如果您真的想拆分轴,请查看here

      【讨论】:

        【解决方案3】:
        import pandas as pd
        import numpy as np
        
        df= data
        
        bins = np.arange(0,0.1,0.001)
        df.hist(bins=bins,color='grey')
        

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
        • 我倾向于同意这个评论,但是这个答案非常好,完全按照要求做,如果你曾经使用过 bins 参数,也很容易理解。