Fitting gaussian to a curve in Python II
Question: I have two lists .

    
    
    import numpy
    x = numpy.array([7250, ... list of 600 ints ... ,7849])
    y = numpy.array([2.4*10**-16, ... list of 600 floats ... , 4.3*10**-16])
    

They make a U shaped curve. Now I want to fit a gaussian to that curve.

    
    
    from scipy.optimize import curve_fit
    n = len(x)
    mean = sum(y)/n
    sigma = sum(y - mean)**2/n
    
    def gaus(x,a,x0,sigma,c):
        return a*numpy.exp(-(x-x0)**2/(2*sigma**2))+c
    
    popt, pcov = curve_fit(gaus,x,y,p0=[-1,mean,sigma,-5])
    
    pylab.plot(x,y,'r-')
    pylab.plot(x,gaus(x,*popt),'k-')
    pylab.show()
    

I just end up with the noisy original U-shaped curve and a straight horizontal
line running through the curve.

I am not sure what the -1 and the -5 represent in the above code but I am sure
that I need to adjust them or something else to get the gaussian curve. I have
been playing around with possible values but to no avail.

Any ideas?


Answer: First of all, your variable `sigma` is actually variance, i.e. sigma squared
--- <http://en.wikipedia.org/wiki/Variance#Definition>. This confuses the
curve_fit by giving it a suboptimal starting estimate.

Then, your fitting ansatz, `gaus`, includes an amplitude `a` and an offset, is
this what you actually need? And the starting values are `a=-1` (negated bell
shape) and offset `c=-5`. Where do they come from?

Here's what I'd do:

  * fix your fitting model. Do you want just a gaussian, does it need to be normalized. If it does, then the amplitude `a` is fixed by `sigma` etc.
  * Have a look at the actual data. What's the tail (offset), what's the sign (amplitude sign).

If you're actually want just a gaussian without any bells and whistles, you
might not actually need `curve_fit`: a gaussian is fully defined by two first
moments, `mean` and `sigma`. Calculate them as you do, plot them over the data
and see if you're not all set.

