Fitting a better gaussian to data points?

前端 未结 2 535
我寻月下人不归
我寻月下人不归 2021-01-23 17:43

I am trying to fit a gaussian to a set of data points that seem to follow a gaussian distribution. I have already checked a lot of possible ways to do that, but I don\'t really

相关标签:
2条回答
  • 2021-01-23 18:35

    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.

    0 讨论(0)
  • 2021-01-23 18:40

    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.

    0 讨论(0)
提交回复
热议问题