Search code examples
pythonscipycurve-fittingcurvedata-fitting

Curvefit() not fitting my data correctly. How to give a good fit?


I am currently trying to fit by data using the curvefit() function in python. The shape should be a upside down 'hump' like shape. However this is giving me a parabola looking shape. Here is the code and a picture. Any help would be much appreciated![1]: https://i.sstatic.net/fmRBn.png

def model(x, a, p,q):
    return a*np.exp(p*x+q*x**2)

# Input data
x = np.array([11, 11, 11,15,15,15,20,20,20,25,25,25,29,29,29])
y = np.array([2.048, 1.56, 1.18, 2.6116,2.35,2.1036,2.97, 2.97, 2.97, 2.463,2.05,1.6679,1.825,1.0939,0.534])
[enter image description here][1]
# Fit
popt, pcov = curve_fit(model, x, y)

# prepare some data for a plot
xx = np.linspace(-20, 60)
yy = model(xx, *popt)

plt.plot(x, y, 'o', xx, yy)
plt.title('Exponential Fit')
plt.ylim(0,5)
plt.xlim(-5,30)
plt.grid()
plt.show()
print(popt)

Solution

  • curve_fit (like many iterative fitting and optimization methods) performs best when it is given a reasonable starting point. The default initial guess for curve_fit is all 1s, which is a very bad guess for your problem--warnings are generated, overflow occurs, and the returned pcov is an array of all inf values (did you check it?).

    With a little trial-and-error, I was able to get what looks like a reasonable fit by using p0=[0.1, 0.1, -0.001]:

    In [123]: popt, pcov = curve_fit(model, x, y, p0=[0.1, 0.1, -0.001])
    
    In [124]: popt
    Out[124]: array([ 0.0847053 ,  0.36886652, -0.00961928])
    
    In [125]: pcov
    Out[125]: 
    array([[ 2.96403174e-03, -3.64981635e-03,  8.97783126e-05],
           [-3.64981635e-03,  4.61677436e-03, -1.15963105e-04],
           [ 8.97783126e-05, -1.15963105e-04,  2.96960195e-06]])
    

    Here's the plot of your data and the fitted curve:

    plot