如何使用matplotlib使用pdf正确绘制标准化的直方图?

时间:2018-09-20 11:02:49

标签: python matplotlib histogram

我尝试使用numpy.random.normal documentation中的示例绘制归一化直方图。为此,我生成正态分布的随机样本。

mu_true = 0
sigma_true = 0.1 
s = np.random.normal(mu_true, sigma_true, 2000)

然后我使数据符合正态分布并计算pdf。

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

可以建议绘制真正归一化的直方图和pdf吗?

Seaborn distplot也不能解决问题。

import seaborn as sns
ax = sns.distplot(s)

enter image description here

2 个答案:

答案 0 :(得分:3)

是什么让您认为它没有被标准化?大概是因为每一列的高度都延伸到大于1的值。但是,这种想法是有缺陷的,因为在归一化的直方图/ pdf中,其下的总面积应加起来为1(而不是高度)。当您处理x中的小步长(如您所愿)时,小于1时,那么列高大于1就不足为奇了!

您可以在链接的scipy示例中清楚地看到这一点:x值要大得多(一个数量级),因此它们的y值也要小。如果更改分布以覆盖更大范围的值,您将看到相同的效果。尝试将sigma为10而不是0.1,看看会发生什么!

答案 1 :(得分:0)

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


"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()