我想使用matplotlib从矢量绘制标准化的直方图。我尝试了以下方法:
plt.hist(myarray, normed=True)
以及:
plt.hist(myarray, normed=1)
但两个选项都不会从[0,1]生成y轴,使得直方图的条形高度总和为1.我想生成这样的直方图 - 我该怎么做?
谢谢!
答案 0 :(得分:178)
如果您希望所有柱的总和等于1,请将每个仓的重量乘以总值:
weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)
希望有所帮助,虽然线程很老......
答案 1 :(得分:42)
如果你提出一个更完整的工作(或在这种情况下是非工作)的例子会更有帮助。
我尝试了以下内容:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(1000)
fig = plt.figure()
ax = fig.add_subplot(111)
n, bins, rectangles = ax.hist(x, 50, density=True)
fig.canvas.draw()
plt.show()
这确实会产生一个条形图直方图,y轴从[0,1]
开始。
此外,根据hist
文档(即来自ax.hist?
的{{1}}),我认为总和也很好:
ipython
在上述命令之后尝试一下:
*normed*:
If *True*, the first element of the return tuple will
be the counts normalized to form a probability density, i.e.,
``n/(len(x)*dbin)``. In a probability density, the integral of
the histogram should be 1; you can verify that with a
trapezoidal integration of the probability density function::
pdf, bins, patches = ax.hist(...)
print np.sum(pdf * np.diff(bins))
我按预期得到np.sum(n * np.diff(bins))
的返回值。请记住,1.0
并不意味着每个柱的值之和将是统一的,而不是柱上的积分是统一的。在我的情况下,normed=True
返回约np.sum(n)
。
答案 2 :(得分:17)
我知道这个答案为时已晚,因为问题是2010年,但我遇到了这个问题,因为我自己也遇到了类似的问题。正如答案中已经说明的那样,normed = True表示直方图下的总面积等于1,但高度之和不等于1.但是,为了方便直方图的物理解释,我想做一个总和等于1。
我在以下问题中找到了一个提示 - Python: Histogram with area normalized to something other than 1
但是我无法找到一种方法来制作模仿histtype =“step”特征hist()的条形图。这使我转向:Matplotlib - Stepped histogram with already binned data
如果社区认为可以接受,我想提出一个解决方案,综合上述帖子中的想法。
import matplotlib.pyplot as plt
# Let X be the array whose histogram needs to be plotted.
nx, xbins, ptchs = plt.hist(X, bins=20)
plt.clf() # Get rid of this histogram since not the one we want.
nx_frac = nx/float(len(nx)) # Each bin divided by total number of objects.
width = xbins[1] - xbins[0] # Width of each bin.
x = np.ravel(zip(xbins[:-1], xbins[:-1]+width))
y = np.ravel(zip(nx_frac,nx_frac))
plt.plot(x,y,linestyle="dashed",label="MyLabel")
#... Further formatting.
虽然在某些情况下我注意到直方图中最左边的“条形”或最右边的“条形”没有通过触摸Y轴的最低点而关闭,但这对我来说非常有效。在这种情况下,在乞讨或结束时添加元素0可以获得必要的结果。
想到我会分享我的经验。谢谢。
答案 3 :(得分:10)
这是使用np.histogram()
方法的另一个简单解决方案。
myarray = np.random.random(100)
results, edges = np.histogram(myarray, normed=True)
binWidth = edges[1] - edges[0]
plt.bar(edges[:-1], results*binWidth, binWidth)
您确实可以通过以下方式检查总和最多为1
> print sum(results*binWidth)
1.0
答案 4 :(得分:0)
自 matplotlib 3.0.2 起,normed=True
已弃用。为了获得所需的输出,我必须这样做:
import numpy as np
data=np.random.randn(1000)
bins=np.arange(-3.0,3.0,51)
counts, _ = np.histogram(data,bins=bins)
if density: # equivalent of normed=True
counts_weighter=counts.sum()
else: # equivalent of normed=False
counts_weighter=1.0
plt.hist(bins[:-1],bins=bins,weights=counts/counts_weighter)
尝试同时指定 weights
和 density
作为 plt.hist()
的参数对我不起作用。如果有人知道无需访问规范关键字参数即可使其工作的方法,请在评论中告诉我,我将删除/修改此答案。
如果您想要 bin 中心,则不要使用 bins[:-1]
作为 bin 边缘 - 您需要选择合适的方案来计算中心(可能会也可能不会简单地推导出)。