You always need a good initial guess when you try a curve fitting.
import numpy as np import pylab as pl import csv from scipy.optimize import curve_fit def sinfunc(x,a,b,c): return a*np.sin((x-c)*(2.0*np.pi/b)) def findamp(x): return (max(x)-min(x))/2.0 def find0cross(x): n=0 while x[n] >= 0: # skip while positive n+=1 while x[n] < 0: # skip while negative n+=1 n1=n # 1st neg to pos transition n+=10 # skip a little bit while x[n] >= 0: # skip while positive n+=1 while x[n] < 0: # skip while negative n+=1 # 2nd neg to pos transition n2=n return [n1, n2] t, v1, v2 = np.loadtxt('OwonData1.csv', unpack=True, delimiter=',') #v1=3500*sin(t*(2.0*np.pi/400)+1.2) #v2=4000*cos(t*(2.0*np.pi/400)) plt.plot(t,v1,'g--',lw=5) plt.plot(t,v2,'b--',lw=5) a1=findamp(v1) a2=findamp(v2) n11, n12 = find0cross(v1) n21, n22 = find0cross(v2) p1=n12-n11 p2=n22-n21 pave=(p1+p2)/2 print n11,n12,p1 print n21,n22,p2 guess1=[a1,pave,n11] guess2=[a2,pave,n21] fitpars1, covmat1 = curve_fit(sinfunc,t,v1,guess1) fitpars2, covmat2 = curve_fit(sinfunc,t,v2,guess2) print guess1, fitpars1 print guess2, fitpars2 pl.plot(t,sinfunc(t, *fitpars1),'r') pl.plot(t,sinfunc(t, *fitpars2),'r') phase2deg=360.0*((fitpars2[2]-fitpars1[2])/((fitpars1[1]+fitpars2[1])/2)) print phase2deg, "(negative value is in advance)"
The first and the second zero-crossings, from negative to positive, are used for estimating the period and the offset of a sine wave.