将更好的高斯拟合到数据点?

时间:2017-02-03 14:30:23

标签: python matplotlib plot gaussian data-fitting

我试图将高斯拟合到一组似乎遵循高斯分布的数据点。我已经检查了很多可能的方法来做到这一点,但我并不是很了解它们中的大多数。但是,我发现一个似乎有效的解决方案,但我得到的实际拟合看起来不像高斯而不是我的数据点。

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy import asarray as ar, exp, sqrt
from scipy.optimize import curve_fit


angles = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
data = [99, 610, 1271, 1804, 1823, 1346, 635, 125, 24]
angles = ar(angles)
data = ar(data)

n = len(x)
mean = sum(data*angles)/n
sigma = sqrt(sum(data*(angles-mean)**2)/n)

def gaus(x,a,mu,sigma):
    return a*exp(-(x-mu)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,angles,data,p0=[0.18,mean,sigma])


fig = plt.figure()
plt.plot(angles, data, "ob", label = "Measured")
plt.plot(angles,gaus(angles,*popt),'r',label='Fit')
plt.xlim(-10, 10)
plt.ylim(0, 2000)
plt.xticks(angles)
plt.title("$^{137}$Cs Zero Point")
plt.xlabel("Angle [$^\circ$]")
plt.ylabel("662 keV-Photon Count")
plt.grid()
plt.legend()
plt.show()

这是它产生的输出:

gaussian fit

正如你所看到的,拟合并没有描述一个漂亮而对称的“真实”高斯。 有什么方法可以让我得到一个“更好”的高斯,还是这样的好呢?

非常感谢!

2 个答案:

答案 0 :(得分:3)

我认为这里有两件不同的事情:

  

似乎遵循高斯分布

→如果您认为数据是正态分布的,那么您就属于统计和概率分布领域,并且可能想要test来查看他们是否同意特定分布(正常或其他)

使用情节

  

得到更好的"高斯情节

在您的代码中,您可以省略import numpy as np import matplotlib.pyplot as plt from scipy import asarray as ar, exp, sqrt from scipy.optimize import curve_fit angles = [-8, -6, -4, -2, 0, 2, 4, 6, 8] data = [99, 610, 1271, 1804, 1823, 1346, 635, 125, 24] angles = ar(angles) data = ar(data) n = len(data) ## <--- mean = sum(data*angles)/n sigma = sqrt(sum(data*(angles-mean)**2)/n) def gaus(x,a,mu,sigma): return a*exp(-(x-mu)**2/(2*sigma**2)) popt,pcov = curve_fit(gaus,angles,data)#,p0=[0.18,mean,sigma]) ## <--- leave out the first estimation of the parameters xx = np.linspace( -10, 10, 100 ) ## <--- calculate against a continuous variable fig = plt.figure() plt.plot(angles, data, "ob", label = "Measured") plt.plot(xx,gaus(xx,*popt),'r',label='Fit') ## <--- plot against the contious variable plt.xlim(-10, 10) plt.ylim(0, 2000) plt.xticks(angles) plt.title("$^{137}$Cs Zero Point") plt.xlabel("Angle [$^\circ$]") plt.ylabel("662 keV-Photon Count") plt.grid() plt.legend() plt.savefig('normal.png') plt.show() 中的第一个估算,并将拟合曲线绘制为连续的自变量:

print( popt )

[  1.93154077e+03  -9.21486804e-01   3.26251063e+00]

enter image description here

在这个例子中:

readFrom

请注意,参数的第一次估计是远离结果的数量级:0.18对1931.15。

答案 1 :(得分:-1)

最好的方法是简单地使用点的均值和方差。我的意思是如果您有权访问生成此直方图的基础数据,那么您应该使用meanvar函数计算其均值和方差。

直方图只是对基础数据的直观近似,基本上您通过拟合直方图而不是数据来估算迂回方式的均值和方差。

无论如何,如果你想继续上面的思路,你需要在角度上添加更多的点。最好的方法是做一些像

这样的事情
angles2 = np.arange(-8,8,.1);
plt.plot(angles2,gaus(angles2,*popt),'r',label='Fit')

可能因为你的数据点很少,你的健康状况看起来很糟糕。使用这种方法,您将看到连续分配应该是什么样的。