如何用Numpy正确绘制带density=True的直方图并匹配密度函数?
如何正确使用Numpy绘制
np.histogram(..., density=True)的结果? 问题出在plt.bar的宽度设置上——你忽略了直方图每个区间(bin)的实际宽度,导致密度缩放不匹配。
核心原因
当使用np.histogram(..., density=True)时,返回的数组h是每个bin的概率密度值,而非概率质量。概率密度的定义是:每个bin的面积(密度 × bin宽度)对应该区间的概率,所有bin的面积之和为1,和概率密度函数(PDF)的积分性质一致。
但你用plt.bar(bins[:-1], h)时,默认的bar宽度是1,而实际每个bin的宽度是bins[i+1] - bins[i](在你的例子中,1000个bin的宽度远小于1)。这会导致直方图的总面积被错误放大,自然和PDF的缩放不匹配。
修正方法
只需要给plt.bar指定正确的bin宽度即可:
import numpy as np import scipy.stats import matplotlib.pyplot as plt y = np.random.randn(10000) h, bins = np.histogram(y, bins=1000, density=True) bin_widths = bins[1:] - bins[:-1] plt.bar(bins[:-1], h, width=bin_widths) # 设置bar宽度为实际bin宽度 x = np.linspace(-10, 10, 100) f = scipy.stats.norm.pdf(x) plt.plot(x, f, color="green") plt.show()
为什么plt.hist(..., density=True)能正常匹配?
因为plt.hist内部已经自动处理了bin宽度的问题:它会根据bins的实际宽度调整每个bar的高度,并设置对应宽度,确保直方图的总面积归一为1,和PDF的积分性质对齐,所以不需要手动调整。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

