Reputation: 25
I can't use scipy.optimize.curve_fit
to fit data generated with numpy.sinc. Even when I do (or at least I think I do) the exact same thing as in the scipy documentation. Here is my simple try:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
xdata = np.arange(-10, 10, 0.1)
y = 100*np.sinc(xdata - 3) + 1
y_noise = np.random.normal(3, 2, 200)
ydata = y + y_noise
def func(x, a, h, k):
return(a*np.sinc(x - h) + k)
popt, pcov = curve_fit(func, xdata, ydata)
plt.plot(xdata, ydata)
plt.plot(xdata, func(xdata, *popt))
plt.show()
Here is the result:
Upvotes: 1
Views: 1082
Reputation: 114911
For many functions, it is essential that you give curve_fit
a "pretty good" initial guess for the parameters. Without it, the optimization routine finds a local minimum of its objective function that is actually a bad fit.
In your case, I got a nice fit by using:
k = ydata.argmax()
p0 = [ydata[k], xdata[k], ydata.mean()]
popt, pcov = curve_fit(func, xdata, ydata, p0=p0)
Here's the plot:
Upvotes: 3
Reputation: 25370
You can provide curve_fit
with an initial guess using p0=[...]
For example:
from scipy.optimize import curve_fit
xdata = np.arange(-10, 10, 0.1)
y = 100*np.sinc(xdata - 3) + 1
y_noise = np.random.normal(3, 2, 200)
ydata = y + y_noise
def func(x, a, h, k):
return(a*np.sinc(x - h) + k)
popt, pcov = curve_fit(func, xdata, ydata, p0=[100, 1, 1])
plt.plot(xdata, ydata)
plt.plot(xdata, func(xdata, *popt))
plt.show()
Upvotes: 2