14
$\begingroup$

Can I get help on how to make frequency axis going from negative frequency to positive frequency, (in Hertz), that will be the x-axis in an FFT result, but given either an even length FFT, or odd length FFT. I am having some troubles making it in MATLAB. (Assume you know the sampling frequency f_s).

$\endgroup$
2
  • 2
    $\begingroup$ It may help you to think about the frequencies being spaced equally around the unit circle. A 4-point FFT has frequency bins at [0/4fs, 1/4fs, 2/4fs, 3/4fs], for instance, which is more commonly written as [0, fs/4, fs/2, -fs/4]. A 3-point FFT has frequency bins at [0/3fs, 1/3fs, 2/3fs], or can be written as [0, fs/3, -fs/3]. For odd sizes this equal spacing skips over the Nyquist frequency, but always includes 0. $\endgroup$
    – endolith
    Jul 10, 2014 at 18:01
  • 1
    $\begingroup$ @endolith This analogy helped me out immensely, thank you so much! $\endgroup$ Jul 3, 2019 at 6:08

2 Answers 2

6
$\begingroup$

One approach is simply to calculate the frequency vector for the unshifted DFT output (i.e. what you would get directly from MATLAB's fft() function, without doing an fftshift()), then remap the frequencies that correspond to locations on the negative side of the axis. Example:

% assume input signal "x", sampling frequency "fs"
% calculate FFT
X = fft(x,Nfft);
% calculate frequency spacing
df = fs / Nfft;
% calculate unshifted frequency vector
f = (0:(Nfft-1))*df;
% move all frequencies that are greater than fs/2 to the negative side of the axis
f(f >= fs/2) = f(f >= fs/2) - fs;
% now, X and f are aligned with one another; if you want frequencies in strictly
% increasing order, fftshift() them
X_normal_order = fftshift(X);
f_normal_order = fftshift(f);

The answer provided by learnvst should work also; this is just another way of thinking about it that doesn't require any special casing for even/odd DFT sizes.

$\endgroup$
2
  • 1
    $\begingroup$ Hello JasonR, is it sure that this code is working, since if I try it with fs = 1000 and Nfft = 256, the f_normal_order I get starts with a positive number, becomes negative, and then positive again. Also the lengths are not matching. $\endgroup$ Jul 26, 2012 at 21:23
  • 1
    $\begingroup$ Sorry, fixed a couple typos in the code. It should work now. $\endgroup$
    – Jason R
    Jul 27, 2012 at 2:17
9
$\begingroup$

You can make a positive frequency spectrum quite simply (where fs is the sampling rate and NFFT is the number of fft bins). In the Matlab implementation of the FFT algorithm, the first element is always the DC component, hence why the array starts from zero. THis is true for odd and even values of NFFT.

%//Calculate frequency axis
df = fs/NFFT;
fAxis = 0:df:(fs-df);

If you need to wrap the frequency spectrum, you need to take into account whether you have an odd numbered NFFT. There always needs to be a DC component, so . .

df = fs/NFFT;
fAxis = (0:df:(fs-df)) - (fs-mod(NFFT,2)*df)/2;

Notice how the calculation of the positive frequency axis is identical to above, but the FFT-shifted term changes to accomodate even or odd FFT lengths.

These code snippets were taken from a long answer posted on SO (that you might find interesting) found here: https://stackoverflow.com/questions/9694297/matlab-fft-xaxis-limits-messing-up-and-fftshift/9699983#9699983

$\endgroup$
2
  • $\begingroup$ Okay, so can I use this for odd NFFT too then? $\endgroup$ Jul 25, 2012 at 18:43
  • $\begingroup$ Ah, sorry. I see the slight complication when going from -ve to +ve frequency. I have changed the answer slightly. $\endgroup$
    – learnvst
    Jul 25, 2012 at 20:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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