Sine Curve fitting in Python

Question:

I want to fit in a one bump of sine cure in this sets of data

xData = np.array([1.7, 8.8, 15, 25, 35, 45, 54.8, 60, 64.7, 70])
yData = np.array([30, 20, 13.2, 6.2, 3.9, 5.2, 10, 14.8, 20, 27.5])

I have successfully fitted in a parabola using scipy.optimize.curve_fit function. But I don’t know how to fit a sine curve to the data.

Here’s what I did so far:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import scipy.interpolate as inp

xData = np.array([1.7, 8.8, 15, 25, 35, 45, 54.8, 60, 64.7, 70])
yData = np.array([30, 20, 13.2, 6.2, 3.9, 5.2, 10, 14.8, 20, 27.5])


def model_parabola(x, a, b, c):
    return a * (x - b) ** 2 + c


def model_sine(x, amp, omega, phase, c, z):
    return amp * np.sin(omega * (x - z) + phase) + c



poptsin, pcovsine = curve_fit(model_sine, xData, yData, p0=[np.std(yData) *2 **0.5, 2 * np.pi, 0, np.mean(yData), 0])
popt, pcov = curve_fit(model_parabola, xData, yData, p0=[2, 3, 4])

# for parabola
aopt, bopt, copt = popt
xmodel = np.linspace(min(xData), max(xData), 100)
ymodel = model_parabola(xmodel, aopt, bopt, copt)

print(poptsin)
# for sine curve
ampopt, omegaopt, phaseopt, ccopt, zopt = poptsin
xSinModel = np.linspace(min(xData), max(xData), 100)
ySinModel = model_sine(xSinModel, ampopt, omegaopt, phaseopt, ccopt, zopt)

y_fit = model_sine(xSinModel, *poptsin)

plt.scatter(xData, yData)
plt.plot(xmodel, ymodel, 'r-')
plt.plot(xSinModel, ySinModel, 'g-')

plt.show()

And this is the result:
Result

Asked By: Nob

||

Answers:

Try with the following:

def model_sine(x, amp, omega, phase, offset):
    return amp * np.sin(omega * x + phase) + offset


poptsin, pcovsine = curve_fit(model_sine, xData, yData, 
                  p0=[np.max(yData) - np.min(yData), np.pi/70, 3, np.max(yData)],
                  maxfev=5000)

You don’t need both phase and z; one should be enough.

I needed to increase the number of allowed function evaluations (maxfev); this would probably not be necessary if the data was completely normalised, although it’s still close enough to order of 1.

enter image description here

Answered By: 9769953

The usual method of fitting (such as in Python) involves an iterative process starting from "guessed" values of the parameters which must be not too far from the unknown exact values.

An unusual method exists not iterative and not requiring initial values to start the calculus. The application to the case of the sine function is shown below with a numerical example (Computaion with MathCad).

enter image description here

enter image description here

enter image description here

The above method consists in a linear fitting of an integral equation to which the sine function is solution. For general explanation see https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales .

Note : If some particular criteria of fitting is specified ( MLSE, MLSAE, MLSRE or other) one cannot avoid nonlinear regression. Then the approximate values of the parameters found above are very good values to start the iterative process in expecting a better reliability with an usual non-linear regression software.

Answered By: JJacquelin
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.