# Scipy/Numpy FFT Frequency Analysis

Posted on

### Question :

Scipy/Numpy FFT Frequency Analysis

I’m looking for how to turn the frequency axis in a fft (taken via scipy.fftpack.fftfreq) into a frequency in Hertz, rather than bins or fractional bins.

I tried to code below to test out the FFT:

``````t = scipy.linspace(0,120,4000)
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t))

signal = acc(t)

FFT = abs(scipy.fft(signal))
FFT = scipy.fftpack.fftshift(FFT)
freqs = scipy.fftpack.fftfreq(signal.size)

pylab.plot(freqs,FFT,'x')
pylab.show()
``````

The sampling rate should be 4000 samples / 120 seconds = 33.34 samples/sec.

The signal has a 2.0 Hz signal, a 8.0 Hz signal, and some random noise.

I take the FFT, grab the frequencies, and plot it. The numbers are pretty nonsensical. If I multiply the frequencies by 33.34 (the sampling frequency), then I get peaks at about 8 Hz and 15 Hz, which seems wrong (also, the frequencies should be a factor of 4 apart, not 2!).

Any thoughts on what I’m doing wrong here?

I think you don’t need to do fftshift(), and you can pass sampling period to fftfreq():

``````import scipy
import scipy.fftpack
import pylab
from scipy import pi
t = scipy.linspace(0,120,4000)
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t))

signal = acc(t)

FFT = abs(scipy.fft(signal))
freqs = scipy.fftpack.fftfreq(signal.size, t-t)

pylab.subplot(211)
pylab.plot(t, signal)
pylab.subplot(212)
pylab.plot(freqs,20*scipy.log10(FFT),'x')
pylab.show()
``````

from the graph you can see there are two peak at 2Hz and 8Hz. scipy.fftpack.fftfreq(n, d) gives you the frequencies directly. If you set `d=1/33.34`, this will tell you the frequency in Hz for each point of the fft.

The frequency width of each bin is (sampling_freq / num_bins).

A more fundamental problem is that your sample rate is not sufficient for your signals of interest. Your sample rate is 8.3 Hz; you need at least 16Hz in order to capture an 8Hz input tone.1

1. To all the DSP experts; I’m aware that it’s actually BW that’s relevant, not max frequency. But I’m assuming the OP doesn’t want to do undersampled data acquisition.

``````fs = 33.33