LudovicG
LudovicG

Reputation: 25

Why can't scipy.optimize.curve_fit fit my data using a numpy.sinc function?

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:

enter image description here

Upvotes: 1

Views: 1082

Answers (2)

Warren Weckesser
Warren Weckesser

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:

plot

Upvotes: 3

DavidG
DavidG

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()

enter image description here

Upvotes: 2

Related Questions