使用MatPlotLib和Numpy将高斯拟合到直方图 - 错误的Y缩放?

时间:2014-05-03 16:51:29

标签: python numpy matplotlib

我编写了下面的代码以使高斯曲线适合直方图。它似乎有效,虽然Y缩放是不同的。我做错了什么?

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.mlab as mlab

list = [0,1,1,2,2,2,3,3,4]

plt.figure(1)
plt.hist(list)
plt.xlim((min(list), max(list)))

mean = np.mean(list)
variance = np.var(list)
sigma = np.sqrt(variance)
x = np.linspace(min(list), max(list),100)
plt.plot(x,mlab.normpdf(x,mean,sigma))

plt.show()

谢谢!

1 个答案:

答案 0 :(得分:12)

您需要对直方图进行标准化,因为您绘制的分布也已标准化:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.mlab as mlab

arr = np.random.randn(100)

plt.figure(1)
plt.hist(arr, normed=True)
plt.xlim((min(arr), max(arr)))

mean = np.mean(arr)
variance = np.var(arr)
sigma = np.sqrt(variance)
x = np.linspace(min(arr), max(arr), 100)
plt.plot(x, mlab.normpdf(x, mean, sigma))

plt.show()

请注意normed=True来电中的plt.hist。另请注意,我更改了样本数据,因为直方图看起来很奇怪,数据点太少。

如果您想要保留原始直方图而不是调整分布,则必须缩放分布,使得分布上的积分等于直方图的积分,即列表中的项目数乘以宽度的酒吧。这可以像

那样实现
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.mlab as mlab

arr = np.random.randn(1000)

plt.figure(1)
result = plt.hist(arr)
plt.xlim((min(arr), max(arr)))

mean = np.mean(arr)
variance = np.var(arr)
sigma = np.sqrt(variance)
x = np.linspace(min(arr), max(arr), 100)
dx = result[1][1] - result[1][0]
scale = len(arr)*dx
plt.plot(x, mlab.normpdf(x, mean, sigma)*scale)

plt.show()

请注意根据项目数乘以单个条形宽度计算的scale因子。