I have spent a lot of time in the last couple weeks fighting to discern some meaning from the results of some Fourier transforms I was doing. During this time I ran across some very helpful resources.

First and foremost among them is this excellent FFT tutorial for Matlab over at blinkdagger. I found this code and explanation to be very useful.

I still had a lot of learning to do however, especially about the correct frequency axis for my data. The simplest way to understand it (as far as I know) is this:

If you run an FFT on 9000 real-valued data points, then it will return an array of 9000 complex values. If you plot the complex modulus (absolute value, or abs(data) function in Matlab), then you will see that the magnitude of the data is symmetric. That is, the first 4500 points are the same as the last 4500 points. In fact there is an interchange of complex and real parts of the symmetric data, but we won’t get into that here.

The important part for me was to realize that if I look at only the first 4500 points, then point number 1 represents the lowest frequency component in the signal that can be detected. The 4500th point is the highest-frequency point that can be detected. What frequency is this point?

It is the Nyquist frequency, equal to half of the sampling rate. The maximum frequency that we can extract from the data is half the sampling frequency. Therefore if your data was taken at a rate of six per second (6 Hertz, or one every 0.166667 seconds), then the Nyquist frequency would be 3 Hertz.

This allows you to create a meaningful frequency axis for your Fourier-transformed data. The highest point is the Nyquist frequency, and the lowest point would be equal to the Nyquist frequency divided by the number of data points. In my above example, that would be 3 Hertz / 4500 data points = 0.00066666 Hertz.

As simple as this sounds, it did take me a little while to figure out.

Secondly, in case anyone is taking the FFT of real-world data, it is very likely that you will have to view it on a log-log axis in order to get anything meaningful out of looking at it. Much of the useful information to humans is often clustered around the low-frequency end. Viewing the data in log-log is very helpful for this. Also, this view can help you identify intensity dropoffs with increasing frequency. Some common ones are 1/f and 1/f^2.

To view in log-log, the matlab command is:

loglog(xAxisData,yAxisData);

If there are no other figures created, this will create a figure with your plot in it.

Are you sure your bin width calculation is correct? I’m trying to do the same thing and have not found any definitive information on this

Your calculation is binWidth = 0.5 * samplingRate / numSamples.

I googled for “fft bin width” and saw this page:

http://www.qsl.net/dl4yhf/speclab/fftinfo.htm

Their calculation is binWidth = samplingRate / numSamples

So with your example, the bin width would be 6 Hz/9000, not 3 Hz/9000.

Can you confirm with one of your professors?

Hi Ben,

I can’t tell you how grateful I am for your blog post about this. I’ve had a really hard time finding a simple explanation for the limits used, and so I wasn’t sure my axis was correct. Now I am sure, and I can draw some conclusions. Thanks!!

Martin