I'm having trouble getting the phase of a simple sine curve using the scipy fft module in python. I followed this tutorial closely and converted the matlab code to python. However, no matter what phase I use for the input, the graph always shows 3. What am I missing?
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
import cmath
A=10
fc = 10
phase=60
fs=32#Sampling frequency with oversampling factor of 32
t = np.arange(0,2,1/fs)
#Convert the phase shift to radians from degrees.
phi = phase*np.pi/180
x=A*np.cos(2*np.pi*fc*t+phi)
N=256
X = scipy.fftpack.fftshift(scipy.fftpack.fft(x,N))/N
df=fs/N #Frequency resolution.
sampleindex = np.arange(-N/2,N/2,1) #Ordered index for FFT plot.
f = sampleindex*df #x-axis index continued to ordered frequencies
raw_phases = np.angle(X)
X2=np.copy(X)#Store the FFT results in another array.
#Detect very small numbers and ignore them.
tau = max(abs(X))/10
X2[abs(X)<tau]=0
phase=[cmath.phase(i) for i in X2]
plt.plot(f,phase)
plt.show()
EDIT: Here is some simpler code. Still can't seem to get the phase.
y = 28*np.sin(2*np.pi/7*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
phase = np.angle(yf)
yf = np.abs(yf[:N//2])
phase = phase[:N//2]
xf = xf[1:]
yf = yf[1:]
phase = phase[1:]
yf = yf-np.mean(yf)
#The frequencies seem to always be scaled by 0.1433, not sure why.
c = 2*np.pi/7/0.143301
freqs = xf[yf>np.std(yf)]*c
phases = phase[yf>np.std(yf)]
The frequencies I get are clustered around 2*np.pi/7. But the phases I get are:
array([-0.217795 , -0.22007488, -0.22226087, 2.91723935, 2.91524011,
2.91333367])
While there should be no phase at all.