I'm try to use cosine function as my model to fit the data, some how it doesn't work.
Here is my code:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def model(x,a,psi,b):
return a*np.cos(x + psi)+b
err_y = 0.5
err_x = 2
x = np.arange(10, 370,20)
x_r = x* (np.pi/180)
y = np.array([5.7, 7.9, 8, 6.6, 4.4, 1.3, 0.09, 1.2, 2.9, 5.9, 7.8, 9, 7, 4.2, 1.5, 0.17, 0.57, 2.5])
error = err_y * np.ones(y.size)
popt, pcov = curve_fit(model, x_r, y,p0 = (4, 3.14, 4), sigma = error,absolute_sigma = True)
print(popt)
plt.scatter(x,y)
plt.errorbar(x, y, yerr=err_y, fmt='none', c='k')
plt.xlabel('Angle(degree)')
plt.ylabel('Readout (V)')
plt.plot(x, model(x_r, *popt), color='red')
I tried many different initial guess for the parameters, but none of them work.
Your data has TWO cycles in 0 to 360 degrees - but your fitting function only allows for ONE.
Try allowing for a frequency inside the cosine, as well as the phase.
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def model(x,a,omega,psi,b):
return a*np.cos(omega*x + psi)+b
err_y = 0.5
err_x = 2
x = np.arange(10, 370,20)
x_r = x* (np.pi/180)
y = np.array([5.7, 7.9, 8, 6.6, 4.4, 1.3, 0.09, 1.2, 2.9, 5.9, 7.8, 9, 7, 4.2, 1.5, 0.17, 0.57, 2.5])
error = err_y * np.ones(y.size)
popt, pcov = curve_fit(model, x_r, y,p0 = (4, 2.0, 3.14, 4), sigma = error,absolute_sigma = True)
print(popt)
plt.scatter(x,y)
plt.errorbar(x, y, yerr=err_y, fmt='none', c='k')
plt.xlabel('Angle(degree)')
plt.ylabel('Readout (V)')
plt.plot(x, model(x_r, *popt), color='red')
plt.show()
Output (the angular frequency comes out as 1.98... or, effectively, 2)
[4.16352559 1.98440219 4.77715943 4.26330405]