Reputation: 177
I am trying to use curve_fit
to fit the following data to a logistic function, as seen bellow. My code for this is very simple:
X=[0,15,30,45,60,75,90,105,120,135,150,165,180]
Y=[0.037812, 0.037735, 0.037721, 0.037634, 0.037373, 0.037173, 0.036373, 0.035833, 0.035741, 0.035727, 0.035668, 0.035674, 0.035652]
def logistic(x,a,b,c,d):
return a / (1.0 + np.exp(-c * (x - d))) + b
popt, pcov = fit(logistic, X, Y)
plt.plot(X,Y, 'o',label='Data')
lin=np.linspace(0,180,1000)
plt.plot(lin,logistic(lin,*pop), '--')
But when I run it I get this error:
OptimizeWarning: Covariance of the parameters could not be estimated
and the plotted curve looks nothing like it should. Can anyone see why Python can't fit my data to a logistic curve?
Upvotes: 1
Views: 2732
Reputation: 4839
If your fit is bad, the most common fix is to specify reasonable starting points for the optimization via the p0
parameter (which defaults to all ones): https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html.
The fit in your picture actually looks like a local minimum (quickly become constant equal to the average value of the data), so better initial guesses for the parameters will probably help.
import numpy as np
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit as fit
def logistic(x, a, b, c, d):
return a / (1.0 + np.exp(-c * (x - d))) + b
def main():
X = [0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180]
Y = [0.037812, 0.037735, 0.037721, 0.037634, 0.037373, 0.037173, 0.036373, 0.035833, 0.035741, 0.035727, 0.035668, 0.035674, 0.035652]
p0 = (1., 1., 1./100, 75.)
popt, pcov = fit(logistic, X, Y, p0=p0)
plt.figure()
plt.plot(X, Y, 'o', label='Data')
lin = np.linspace(0, 180, 1000)
plt.plot(lin, logistic(lin, *popt), '--')
plt.show()
plt.close()
if __name__ == '__main__':
main()
Indeed, here's the fit I got just by changing the p0
parameter:
Upvotes: 1