python 绘制直方图,使条形高度之和为1(概率)

n9vozmp4  于 2022-11-28  发布在  Python
关注(0)|答案(6)|浏览(228)

我想使用matplotlib从一个矢量中绘制一个归一化直方图。

plt.hist(myarray, normed=True)

以及:

plt.hist(myarray, normed=1)

但是两个选项都不从[0,1]产生y轴,从而直方图的条高度之和为1。

wqlqzqxt

wqlqzqxt1#

如果希望所有条的总和等于1,请按值的总数对每个条柱进行加权:

weights = np.ones_like(myarray) / len(myarray)
plt.hist(myarray, weights=weights)

希望这能有所帮助,虽然线程是相当古老的...
Python 2.x的注意事项:将转换添加到float(),作为除法运算符之一,否则,由于整数除法,您将以零结束

9gm1akwq

9gm1akwq2#

如果你提出一个更完整的工作(或者在本例中是非工作)示例,这会更有帮助。
我尝试了以下方法:

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文档(即ipythonax.hist?),我认为总和也很好:

*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并不意味着每个棒线上的值之和都是1,而是对棒线的积分是1。在我的例子np.sum(n)中,返回了大约7.2767

cbeh67ev

cbeh67ev3#

我知道这个答案太晚了,因为问题的日期是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轴的最低点而关闭。在这种情况下,在y轴的起点或末端添加一个元素0就达到了必要的结果。
我只是想分享一下我的经验。谢谢。

disbfnqx

disbfnqx4#

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

kpbwa7wx5#

  • 最简单的解决方案是使用seaborn.histplot,或将seaborn.displotkind='hist'结合使用,并指定stat='probability'
    *概率:或比例:标准化以使条高度和为1
    *密度:归一化,使得直方图的总面积等于1
  • datapandas.DataFramenumpy.ndarray、Map或序列
  • seabornmatplotlib的高级API
    *python 3.8.12matplotlib 3.4.3seaborn 0.11.2中进行测试

导入和数据

import seaborn as sns
import matplotlib.pyplot as plt

# load data
df = sns.load_dataset('penguins')

sns.histplot

  • 轴级图
# create figure and axes
fig, ax = plt.subplots(figsize=(6, 5))

p = sns.histplot(data=df, x='flipper_length_mm', stat='probability', ax=ax)

sns.displot

  • 图形层次图
p = sns.displot(data=df, x='flipper_length_mm', stat='probability', height=4, aspect=1.5)

6mw9ycah

6mw9ycah6#

从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)

尝试将weightsdensity同时指定为plt.hist()的参数对我来说不起作用。如果有人知道一种方法来让它在没有访问normed关键字参数的情况下工作,请在评论中告诉我,我会删除/修改这个答案。
如果你想要面元中心,那么不要使用bins[:-1],这是面元边缘--你需要选择一个合适的方案来计算中心(可能是也可能不是很容易推导出来的)。

相关问题