Given sampling rate FSample
and transform blocksize N
, you can calculate the frequency resolution deltaF
, sampling interval deltaT
, and total capture time capT
using the relationships:
deltaT = 1/FSample = capT/N
deltaF = 1/capT = FSample/N
Keep in mind also that the FFT returns value from 0
to FSample
, or equivalently -FSample/2
to FSample/2
. In your plot, you're already dropping the -FSample/2
to 0
part. NumPy includes a helper function to calculate all this for you: fftfreq.
For your values of deltaT = 1 hour
and N = 576
, you get deltaF = 0.001736 cycles/hour = 0.04167 cycles/day
, from -0.5 cycles/hour
to 0.5 cycles/hour
. So if you have a magnitude peak at, say, bin 48 (and bin 528), that corresponds to a frequency component at 48*deltaF = 0.0833 cycles/hour = 2 cycles/day.
In general, you should apply a window function to your time domain data before calculating the FFT, to reduce spectral leakage. The Hann window is almost never a bad choice. You can also use the rfft
function to skip the -FSample/2, 0
part of the output. So then, your code would be:
ft = np.fft.rfft(signal*np.hanning(len(signal)))
mgft = abs(ft)
xVals = np.fft.fftfreq(len(signal), d=1.0) # in hours, or d=1.0/24 in days
plot(xVals[:len(mgft)], mgft)