【问题标题】:Matplotlib - Stepped histogram with already binned dataMatplotlib - 已分箱数据的阶梯直方图
【发布时间】:2012-07-03 01:34:21
【问题描述】:

我正在尝试获取包含已分箱数据的直方图。我一直在尝试为此使用bar(),但我似乎无法弄清楚如何使它成为阶梯直方图like this one from the examples,而不是填充直方图。

【问题讨论】:

    标签: python numpy matplotlib scipy


    【解决方案1】:

    您可以通过抵消您的数据并改用plot 来作弊:

    from matplotlib import pyplot
    import numpy as np
    
    #sample data:
    x = np.arange(30)
    y = np.cumsum(np.arange(30))
    #offset the x for horizontal, repeat the y for vertical:
    x = np.ravel(zip(x,x+1))
    y = np.ravel(zip(y,y))
    
    pyplot.plot(x,y)
    pyplot.savefig('plt.png')
    

    剧情:

    【讨论】:

    • 我想出了第二种方法。只需将ls = "steps" 设置为plot()。不过感谢您的回答!
    • @madtowneast,您应该为该评论获得更多支持。这是一个隐藏的功能。 matplotlib.org/api/…
    【解决方案2】:

    最简单的解决方案是将分箱数据集转换为未分箱的加权数据集(元素数 == 分箱数)。未分箱的数据集将包含等于 bin 中心的数据值和等于每个 bin 中的值的权重。例如,假设您的分箱数据是,

    binedges = [0.0, 1.0, 2.0, 3.0]
    ybinned = [11., 22., 33.]
    

    相应的加权数据集是,

    y =       [0.5, 1.5, 2.5]
    weights = [11., 22., 33.]
    

    请注意,使用 bin 中心的选择是任意的,您可以使用 bin 内的任何点。一旦你生成了 un-binned 数据集,你就可以使用正常的 matplotlib 直方图绘图(即 Axes.hist)。

    python 中的示例实现如下:

    def plot_binned_data(axes, binedges, data,
                   *args, **kwargs):
        #The dataset values are the bin centres
        x = (binedges[1:] + binedges[:-1]) / 2.0
        #The weights are the y-values of the input binned data
        weights = data
        return axes.hist(x, bins=binedges, weights=weights,
                   *args, **kwargs)
    

    您现在可以完全访问所有 Axes.Histogram 绘图选项,包括 histtype="step",以创建您想要的阶梯直方图。

    使用这个函数的一个例子是,

    import numpy
    import matplotlib.pyplot as plt
    
    #Create a dataset
    dataset = numpy.random.normal(size=100)
    #Bin the dataset
    binedges = numpy.linspace(-5.0, 5.0, num=10)
    y, binedges = numpy.histogram(dataset, binedges)
    
    #Plot the dataset
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    plot_binned_data(ax, binedges, y, histtype="step")
    plt.show()
    

    希望有帮助!

    【讨论】:

      【解决方案3】:

      来自http://matplotlib.sourceforge.net/examples/pylab_examples/histogram_demo_extended.html的随附来源

      这是他们绘制该图的方式:

      [剪辑]

      而你想要的位似乎是

      pylab.hist(x, bins=bins, histtype='step')
                                  ^
                              right here
      

      编辑:如果您想知道 hist() 的工作原理,请查看源代码 - 它在 matplotlib/axes.py 中从第 7407 行开始定义。

      查看第 7724 行,

      x = np.zeros( 2*len(bins), np.float )
      y = np.zeros( 2*len(bins), np.float )
      

      对于 N 个条形,bins 是 N+1 个值的 numpy.ndarray,是每个条形的边。他们将每个条的值配对(这是 fraxel 在下面使用 np.ravel 所做的)并将数据点向左移动半条以使它们居中

      x[0::2], x[1::2] = bins, bins
      x -= 0.5*(bins[1]-bins[0])
      

      设置每个条的高度,成对但偏移一个(相对于 x 值)以产生阶梯效果

      # n is an array of arrays containing the number of items per bar
      patches = []    # from line 7676
      for m, c in zip(n, color):
          y[1:-1:2], y[2::2] = m, m
          patches.append(self.fill(x, y, closed=False, edgecolor=c, fill=False))
      

      self.fill 位实际上是画线的原因。

      【讨论】:

      • 据我了解该示例数据尚未分箱。我已经有分箱数据,所以hist() 没有帮助
      • @Jonas Wielicki:给出的代码导致了他询问的图像。这怎么不适用?
      • @HughBothwell 他确实有分箱中的数据,而不是未分箱的。不过,通过您的编辑,它似乎对我有用。
      【解决方案4】:

      由于某种原因,当我尝试使用最后一个垃圾箱时,它没有正确关闭。如果显示最后一行,则从以前的答案中看不到,所以我决定制作自己的函数,它可以满足我的需求。

      def make_bar_contour_plot(ax,x_input,y_input):
      
          x = list(np.ravel(zip(x_input[:-1],x_input[:-1]+1)))[1:]
          x += [x[-1]+20] + [300] 
          y = list(np.ravel(zip(y_input,y_input))) +[0]
          ax.plot(x,y,ls='steps')
      
          return ax
      

      添加的20300分别是我的binsize和结束值,如果有人想使用这个需要调整。 x_inputy_input 是来自 np.histogram 的返回值。我的结果图(蓝色轮廓,用上面的函数绘制。红色,相同数据的条形图):

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-11
        • 1970-01-01
        • 2013-06-18
        • 2018-10-17
        • 1970-01-01
        • 2013-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多