Fitting a better gaussian to data points?

好久不见. 提交于 2019-12-02 04:27:59

I think there are two different things here:

seem to follow a gaussian distribution

→ If you think that the data are normally distributed, you are in the realms of statistics and probability distributions, and may want to make a test to see if they agree with a particular distribution (normal or other).


And work with your plot:

get a "better" gaussian plot

In your code, you can leave out the first estimation in curve_fit and plot the fitted curve against a continuous independent variable:

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


In this example:

print( popt )

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

Note that the first estimation of the parameter is orders of magnitude away from the result: 0.18 vs. 1931.15.

The best way is to simply use the mean and variance of the points. I mean if you have access to the underlying data that generated this histogram, then you should calculate its mean and variance using the mean and var functions.

The histogram is just a visual approximation to the underlying data, and essentially you are estimating the mean and variance in a roundabout way by fitting the histogram instead of the data.

In any event, if you want to continue with your train of thought above, you need to add more points to angles. The best way to do this would be to do something like

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

It could be that your fit just looks bad because you have very few data points. Using this approach, you would see what the continuous dictribution should look like.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!