Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 705
nathan lachenmyer Avatar asked Feb 26 '12 18:02

nathan lachenmyer


People also ask

How do I get frequencies from FFT in Python?

We can obtain the magnitude of frequency from a set of complex numbers obtained after performing FFT i.e Fast Fourier Transform in Python. The frequency can be obtained by calculating the magnitude of the complex number. So simple ab(x) on each of those complex numbers should return the frequency.

How do you find the frequency of data using FFT?

Let X = fft(x) . Both x and X have length N . Suppose X has two peaks at n0 and N-n0 . Then the sinusoid frequency is f0 = fs*n0/N Hertz.

How does SciPy FFT work?

SciPy provides the functions fht and ifht to perform the Fast Hankel Transform (FHT) and its inverse (IFHT) on logarithmically-spaced input arrays. which is a convolution in logarithmic space. The FHT algorithm uses the FFT to perform this convolution on discrete input data.

Does numpy have FFT?

FFT in Numpy EXAMPLE: Use fft and ifft function from numpy to calculate the FFT amplitude spectrum and inverse FFT to obtain the original signal. Plot both results. Time the fft function using this 2000 length signal.


1 Answers

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[1]-t[0])  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.

enter image description here

like image 67
HYRY Avatar answered Sep 23 '22 04:09

HYRY