我正在尝试使用已经分箱的数据获得直方图。我一直在尝试使用它,但我似乎无法从示例bar()
中弄清楚如何使它成为像这样的阶梯直方图,而不是填充直方图。
4 回答
您可以通过抵消您的数据并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')
剧情:
最简单的解决方案是将分箱数据集转换为未分箱的加权数据集(元素数 == 箱数)。未分箱的数据集将由等于箱中心的数据值和等于每个箱中的值的权重组成。例如,假设您的分箱数据是,
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()
希望有帮助!
来自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
一点实际上是画线的。
出于某种原因,当我尝试时,最后一个垃圾箱没有正确关闭。如果显示最后一行,则从以前的答案中看不到,所以我决定制作自己的函数,它可以满足我的需求。
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
添加的20
and300
分别是我的 binsize 和 end 值,如果有人想使用它需要调整。x_input
并且y_input
是 的返回值np.histogram
。我的结果图(蓝色轮廓,用上面的函数绘制。红色,相同数据的条形图):