Python 如何在matplotlib中绘制直方图,使条形图的高度总和为1?

Python 如何在matplotlib中绘制直方图,使条形图的高度总和为1?,python,graph,numpy,matplotlib,scipy,Python,Graph,Numpy,Matplotlib,Scipy,我想使用matplotlib从向量中绘制一个标准化直方图。我尝试了以下方法: plt.hist(myarray, normed=True) 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.

我想使用matplotlib从向量中绘制一个标准化直方图。我尝试了以下方法:

plt.hist(myarray, normed=True)
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()
以及:

plt.hist(myarray, normed=1)

但这两个选项都不会从[0,1]生成y轴,从而直方图的条高总和为1。我想制作这样一个柱状图——我该怎么做呢?

如果您提出一个更完整的工作(或在本例中为非工作)示例,会更有帮助

我尝试了以下方法:

plt.hist(myarray, normed=True)
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?
来自
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)
返回了大约
7.2767

考虑到问题日期是2010年,我知道这个答案太晚了,但我遇到了这个问题,因为我自己也面临着类似的问题。如回答中所述,normed=True表示直方图下的总面积等于1,但高度之和不等于1。然而,为了便于对柱状图进行物理解释,我想让柱状图的高度之和等于1

我在下面的问题中发现了一个暗示-

但我无法找到一种方法使条形图模仿histtype=“step”功能hist()。这使我转向:

如果社区认为这是可以接受的,我想提出一个综合上述两个帖子的想法的解决方案

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轴的最低点而关闭。在这种情况下,在begging或y的末尾添加元素0可获得必要的结果


我只是想分享一下我的经验。谢谢。

如果您希望所有条的总和相等,请按值的总数对每个箱子进行加权:

weights = np.ones_like(myarray) / len(myarray)
plt.hist(myarray, weights=weights)
希望对你有所帮助,虽然线已经很旧了


注意:对于Python2.x:对于除法的一个运算符,将强制转换添加到
float()
,否则,由于整数除法,您将以零结束

这里是另一个使用
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

由于matplotlib 3.0.2,不推荐使用
normed=True
。要获得所需的输出,我必须执行以下操作:

将numpy导入为np
数据=np.random.randn(1000)
垃圾箱=np.arange(-3.0,3.0,51)
计数,柱状图(数据,箱=箱)
如果密度:#等于标准值=真
counts\u weighter=counts.sum()
否则:#等于normed=False
计数加权器=1.0
plt.hist(箱子[:-1],箱子=箱子,重量=计数/计数/称重器)
尝试同时指定
权重
密度
作为
plt.hist()
的参数对我无效。如果有人知道一种方法,可以在不访问normed关键字参数的情况下使其工作,那么请在评论中告诉我,我将删除/修改此答案


如果你想要垃圾箱中心,那么不要使用垃圾箱[:-1]垃圾箱边缘-你需要选择一个合适的方案来计算中心(可能是也可能不是简单推导出来的)。

答案很好。请注意,如果myarray是类似python的
array\u
而不是numpy数组,则需要将
len(myarray)
强制转换为
float
。此外,如果myarray是多维的&您只使用一维,例如myarray[0,:],那么您可以将len(myarray)替换为np.size(myarray[0,:]),这将以同样的方式工作。(否则,它说该对象不可调用。)我认为在plt.hist中也需要normed=True。同样在Python3中,您必须使用list(zip(…)。我知道这很旧,但为了将来的参考&任何访问此页面的人,这种轴排列称为“概率密度”轴!是的,这是一个概率密度图,我想他想要一个概率质量图。