如何使用Matplotlib正确绘制带有概率密度函数的归一化直方图?

8
我尝试使用numpy.random.normal文档中的示例绘制归一化直方图。为此,我生成了正态分布的随机样本。
mu_true = 0
sigma_true = 0.1 
s = np.random.normal(mu_true, sigma_true, 2000)

然后我对数据进行正态分布拟合,并计算概率密度函数。
mu, sigma = stats.norm.fit(s)
points = np.linspace(stats.norm.ppf(0.01,loc=mu,scale=sigma),
                 stats.norm.ppf(0.9999,loc=mu,scale=sigma),100)
pdf = stats.norm.pdf(points,loc=mu,scale=sigma)

显示拟合的 PDF 和数据直方图。
plt.hist(s, 30, density=True);
plt.plot(points, pdf, color='r')
plt.show() 

我使用 density=True,但显然,pdf 和直方图并未归一化。

enter image description here

有什么建议可以绘制真正归一化的直方图和概率密度函数吗?Seaborn distplot也无法解决这个问题。
import seaborn as sns
ax = sns.distplot(s)

enter image description here

2个回答

6
你认为这个不是标准化的吗?可能是因为每一列的高度超过了1,但这种想法是错误的。在归一化的直方图/概率密度函数中,总面积应该加起来为1(而不是高度)。当你处理的x值很小(小于1)时,列的高度大于1并不奇怪!你可以在你提供的scipy示例中清晰地看到这一点:x值大得多(数量级上),所以相应的y值也较小。如果你改变分布范围的话,也会看到同样的效果。尝试将sigma从0.1改为10,看看会发生什么!

3
import numpy as np
from numpy.random import seed, randn
from scipy.stats import norm
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme()

"Try this, for  = 0"
seed(0)
points = np.linspace(-5,5,100)
pdf    = norm.pdf(points,0,1)
plt.plot(points, pdf, color='r')
plt.hist(randn(50), density=True);
plt.show() 

enter image description here

"or this, for  = 10"
seed(0)
points = np.linspace(5,15,100)
pdf    = norm.pdf(points,10,1)
plt.plot(points, pdf, color='r')
plt.hist(10+randn(50), density=True);
plt.show() 

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接