【问题标题】:Fitting a Gaussian to a histogram with MatPlotLib and Numpy - wrong Y-scaling?使用 MatPlotLib 和 Numpy 将高斯拟合到直方图 - 错误的 Y 缩放?
【发布时间】:2014-06-20 06:24:04
【问题描述】:

我编写了以下代码来将高斯曲线拟合到直方图。它似乎工作,虽然 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()

谢谢!

【问题讨论】:

  • 我会避免将您的列表命名为“列表”,因为它与类型列表冲突

标签: python numpy matplotlib


【解决方案1】:

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

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, density=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()

注意对plt.hist 的调用中的density=True。另请注意,我更改了您的示例数据,因为直方图看起来很奇怪,数据点太少。

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

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 因子是根据项目数乘以单个条的宽度计算得出的。

【讨论】:

  • 感谢您,它运行良好。有没有一种方法可以使直方图不归一化为分布,而我不能一开始就对分布进行归一化?我是 Python 的初学者,更不用说 MatPlotLib。
  • 您当然可以将分布乘以项目总数除以直方图中的 bin 数。这应该可以得到你想要的。
  • 麻烦您举个例子好吗?
  • 见我回答中的第二个例子。
  • list = np.random.randn(1000) 此代码正在重新定义 list() 关键字。这是一种糟糕的做法,并且会产生非常难以调试的问题。
猜你喜欢
  • 2016-07-05
  • 1970-01-01
  • 2015-08-11
  • 2013-11-19
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
相关资源
最近更新 更多