如何标准化直方图

1 投票
2 回答
15042 浏览
提问于 2025-04-16 23:07

我有一个直方图,它是用等间隔的对数区间来统计数组"d"的。

 max_val=np.log10(max(d))
 min_val=np.log10(min(d))
 logspace = np.logspace(min_val, max_val, 50) 


 hist(d,bins=logspace,label='z='+str(redshift),histtype='step')
 show()

问题是我想把它归一化,也就是说让它的面积等于1。使用选项Normed=True时,我没有得到想要的结果,这可能是因为我使用的是对数区间。因此,我尝试用这种方式来归一化直方图:

 H=hist(d,bins=logspace,label='z='+str(redshift),histtype='step')
 H_norm=H[0]/my_norm_constant

但是我不知道该如何将H_norm和区间一起绘制出来。

2 个回答

1

这个方法使用了一种常见的归一化方式,它会把每个柱子的高度调整到总和为1,而不管每个柱子的宽度是多少。

import matplotlib
import numpy as np

x = [0.1,0.2,0.04,0.05,0.05,0.06,0.07,0.11,0.12,0.12,0.1414,\
     0.1415,0.15,0.12,0.123,0,0.14,0.145,0.15,0.156,0.12,0.15,\
     0.156,0.166,0.151,0.124, 0.12,0.124,0.12,0.045,0.124]

weights = np.ones_like(x)/float(len(x))
p=plt.hist(x,
    bins=4,
    normed=False, 
    weights=weights,
    #histtype='stepfilled',
    color=[0.1,0.4,0.3]
)

plt.ylim(0,1)
plt.show()

这是最终的直方图图像:

2

我试过把normed设置为True,这样得到的面积是1:

from pylab import *
d = np.random.normal(loc=20, size=10000)
max_val=np.log10(max(d))
min_val=np.log10(min(d))
logspace = np.logspace(min_val, max_val, 50) 


r = hist(d,bins=logspace,histtype='step', normed=True)
print "area":, sum(np.diff(r[1])*r[0])

你可以运行一下这段代码,看看输出结果。如果结果不是1,那就检查一下你的numpy版本。我在运行代码时收到了这个警告信息:

C:\Python26\lib\site-packages\matplotlib\axes.py:7680: 用户警告: 这个版本修复了NumPy直方图函数在1.5版本之前的一个归一化错误, 这个错误出现在不均匀的区间宽度下。现在返回和绘制的值是一个密度值: n / (N * 区间宽度), 其中n是区间的计数,N是总点数。

如果你想自己绘制图表:

step(r[1][1:], r[0]/my_norm_constant)

撰写回答