I am trying to fit some horizontal wind data to a cosine curve in order to estimate the direction and speed of winds at various heights (Velocity Azimuth Display), however it appears that whenever I attempt to do so with values > ~1, the curve appears way too flat and the output of the fit is lower than expected.
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 the coeffs output being:[ 1., 0., 0.13705066] and plot attached:
Python CurveFit
I have performed a similar curvefit using IDL's builtin curvefit function, and received more realistic values yielding [ 7.0348234, 0.59962606, 0.079354301] and providing a proper fit. Is there any reason why this is the case? I am assuming that it likely has something to do with the initial estimate (P0), however, utilizing an initial initial estimate in the IDL implementation still provides much more reasonable results.
You need to fix a few things:
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]