Scipy curve_fit fails when fitting a curve with large values
I am trying to tie some horizontal wind data to a cosine curve to estimate the direction and speed of the winds at different heights (displaying the azimuth of speed), however, it seems that whenever I try to do this with values> ~ 1, the curve seems too flat and yield less than expected fit.
import numpy as np
import scipy.optimize as sc
azimuth = np.full((8), 60) #All values = 60 deg.
velocity = [5.6261001,6.6962662,3.9316666,-0.88413334,-5.4323335,-6.5153003,-3.2538002,1.0269333]
#Function that defines curve that data will be fitted to
def cos_Wave(x,a, b, c):
return a * np.cos(x-b) + c
azimuthData = np.deg2rad(azimuth)
coeffs, matcov = sc.curve_fit(cos_Wave, azimuthData, velocity, p0 = (1,0,0)
plt.scatter(azimuthData, velocity)
plt.plot(azimuthData, cos_Wave(azimuthData, *coeffs))
plt.show()
print(coeffs)
With output coeffs: [1., 0., 0.13705066] and attached graph:
Python CurveFit
I made a similar curve using the built-in IDL curve function and got more realistic values ββgiving [7.0348234, 0.59962606, 0.079354301] and providing a proper fit. Is there a reason why this is so? I guess it probably has something to do with the initial estimate (P0), however using the initial initial estimate in the IDL implementation still provides much more reasonable results.
source to share
There are a few things you need to fix:
import numpy as np
import scipy.optimize as sc
import matplotlib.pyplot as plt
azimuth = np.linspace(0, 360, 8) # deg values from 0 to 360
velocity = [5.6261001, 6.6962662, 3.9316666, -0.88413334, -5.4323335,
-6.5153003, -3.2538002, 1.0269333]
def cos_Wave(x, a, b, c):
"""Function that defines curve that data will be fitted to"""
return a * np.cos(x-b) + c
azimuthData = np.deg2rad(azimuth)
coeffs, matcov = sc.curve_fit(cos_Wave, azimuthData, velocity, p0=[1, 0, 0])
plt.scatter(azimuthData, velocity)
nx = np.linspace(0, 2 * np.pi, 100)
plt.plot(nx, cos_Wave(nx, *coeffs))
plt.savefig("plot.png")
print(coeffs)
[6.63878549 1.03148322 -0.27674095]
source to share