0
$\begingroup$

I'm trying to compute the DFT using scipy's functions. I don't understand why the phase spectrum of a simple sine wave with 2 Hz frequency doesn't show $\pm\pi/2$ at the $\pm 2Hz$ frequencies. Instead, the phase plot seems to have some linear dependence in the frequency, which I don't understand. I provide the code for assistance. How can this be fixed? Looks like a simple issue I'm not grasping. Please help.

import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft, fftfreq

# 1Hz sine wave
npts  = 100
tmax  = 10                          
t     = np.linspace(0, tmax, npts)
y     = np.sin(2*np.pi*2*t)
dt    = tmax/npts

# FFT computation
Y      = fft(y)
freq   = fftfreq(npts, d=dt)
amplit = abs(Y)/npts
phase  = np.angle(Y)
phase  = phase / np.pi

fig, ax = plt.subplots(1, 2, figsize=(10,4))
ax[0].plot(freq, amplit)
ax[1].plot(freq, phase)

ax[0].plot([2,2], [0,0.5], '--')
ax[0].plot([-2,-2], [0,0.5], '--')
ax[1].plot([2,2], [-1,1], '--')
ax[1].plot([-2,-2], [-1,1], '--')

enter image description here

$\endgroup$
2
$\begingroup$

For sinusoids that are not exactly integer periodic in the FFT length, an FFT measures the phase at a circular discontinuity. And that discontinuity flips direction as frequency changes from slightly below to slightly above an exact integer periodic-in-aperture frequency. This is part of the effect of the default rectangular windowing of any finite length DFT or FFT. Thus making the FFT phase result of a frequency sweep hard to interpret.

The way to remove this measurement at a circular discontinuity is to shift the waveform discontinuity away from the phase measurement point (FFT input sample 0) by doing a (circular) FFTShift before the FFT. Then your FFT phase result will be referenced to the center of the original input vector (original waveform sample N/2), which will be continuous for continuous input functions or waveforms.

After the FFT following an fftshift, you can use the FFT frequency and phase results for the the center of the original input waveform to compute the phase at any other point (for instance the beginning, or sample 0 of the original input waveform. Or the end, etc.).

$\endgroup$
  • $\begingroup$ Will this work if the signal has multiple sines/cosines/arbitrary phases at the origin? $\endgroup$ – simplestuff Oct 21 at 17:03
  • $\begingroup$ Could you comment on this from your experience? $\endgroup$ – simplestuff Oct 22 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.