MATLAB - FFT and Zero Padding
17 Apr 2008 Quan Quach 33 comments 10,759 views
This is the fourth post in the blinkdagger signal processing series.
Introduction
In the previous tutorial, we showed you how correctly scale your x-axis so that your FFT results were meaningful. In this post, we will be discussing zero-padding, a method that can help you better visualize/interpret your fft results. Zero-padding means that you append an array of zeros to the end of your input signal before you fft it. Luckily, the fft command within Matlab makes it very easy to zero-pad.
Why Zero Pad?
Two reasons that you might want to zero pad is to increase the number of data points to a power of 2. Traditionally, the FFT algorithm is more efficient when it is dealing with signals that contain 2^N data points. Nowadays, this isn’t as important with the modern algorithms. Another reason for zero-padding is for a “better” resolution in the frequency spectrum. We’ll discuss why quotes are used around better in a bit. In general, zero-padding can prove quite useful and should be used when using the fft command. In practice, it is helpful to zero pad a signal to 4 times it’s original length, giving you a 4-fold increase in the frequency resolution.
A Simple Example
Let’s use the same signal as the previous tutorial as our example signal:

fo = 4; %frequency of the sine wave Fs = 100; %sampling rate Ts = 1/Fs; %sampling time interval t = 0:Ts:1-Ts; %sampling period n = length(t); %number of samples y = 2*sin(2*pi*fo*t); %the sine curve %plot the cosine curve in the time domain sinePlot = figure; plot(t,y) xlabel('time (seconds)') ylabel('y(t)') title('Sample Sine Wave') grid

But now, lets append some zeros to the end of this signal:
Case 1: Number of points = 128
Case 2: Number of points = 256
Case 3: Number of points = 512
This is what the signal would look like for these three cases:
Taking the FFT of the Zero-Padded Signals
Luckily, the fft command within Matlab makes zero-padding extremely easy. The fft command has a second argument that allows you to specify how many data points the fft command will return. I modified the code I presented in the last tutorial to allow for zero padding and used it here:
%remember to save this function as an m-file! function [X,freq]=centeredFFT(x,Fs,N) %this is a custom function that helps in plotting the two-sided spectrum %x is the signal that is to be transformed %Fs is the sampling rate %N is the number of points returned in the FFT result %this part of the code generates that frequency axis if mod(N,2)==0 k=-N/2:N/2-1; % N even else k=-(N-1)/2:(N-1)/2; % N odd end T=N/Fs; freq=k/T; %creates the frequency axis X=fft(x,N)/length(x); % normalizes the data X=fftshift(X);%shifts the fft data so that it is centered
Now, lets take the fft of these three signals.
Why Does My Output Look Like a Sinc?
When we pad with zeros, we are effectively multiplying a rectangular box with the sinusoid in the time domain. In the frequency domain, this translates into convolving a sinc function with an impulse resulting in a sinc-like output!(You can download the script that I used in creating these plots at the end of this tutorial).
As you can see, there are more sampled points as N gets larger, and it is easier to see the general shape of the spectrum. The larger your N is, the finer the sampling will be. If I keep on increasing the number of zeros, it will make my frequency spectrum more refined. So does this mean I can just zero-pad my signal and get a better FFT spectrum every time? Well, technically speaking, you get more frequency bins when you zero pad, so yes, you do get a higher resolution in the frequency domain. But the caveat is that there is no new information added when you zero-pad.
When you increase the size of N, all you are really doing is interpolating the data to obtain more sample points. There is NO new information added when zero-padding is applied. The resolution has increased, but I repeat, THERE IS NO NEW INFORMATION ADDED! This might sound confusing and paradoxical, but it is a very important point.
If you have the option to take more data, it is ALWAYS better to get more data than to zero pad. Zero-padding is NOT a substitute for taking more data!
Another Example on how Zero Padding can Help
-
In this example, we are going to use zero padding to help us distinguish between two peaks that would otherwise be difficult to distinguish.
The example signal has f1 = 4 Hz and f2 = 4.5 Hz (meaning it will have a peak at 4 Hz and a peak at 4.5 Hz):
[tex]y(t)=100sin(2\pi{f}_{1}t)+100sin(2\pi{f}_{2}t)[/tex]
The following MATLAB code is used to generate the curve. Insert this into the MATLAB command prompt
f1 = 4; %frequency of the first sine wave f2 = 4.5; %frequency of the second sine wave Fs = 100; %sampling rate Ts = 1/Fs; %sampling time interval t = 0:Ts:2-Ts; %sampling period y = 100*sin(2*pi*f1*t) + 100*sin(2*pi*f2*t); %sum of sine waves plot(t,y) title('Sample Signal', 'FontWeight','Bold') xlabel('Time (seconds)') ylabel('Amplitude') grid
-
Now, lets take the FFT of the signal without zero padding. Theoretically, we expect two peaks. One peak at 4 Hz, and another at 4.5 Hz.
As you can see, it is difficult to tell that there are two peaks in this plot. It looks like the peaks got smashed together.
-
Now, lets apply some zero padding up to N = 1024 points.
The following function is used to perform this:
%remember to save this function as an m-file! function [X,freq]=positiveFFT_zero_padding(x,Fs,N) k=0:N-1; %create a vector from 0 to N-1 T=N/Fs; %get the frequency interval freq=k/T; %create the frequency range X=fft(x,N)/length(x); % normalize the data %only want the first half of the FFT, since it is redundant cutOff = ceil(N/2); %take only the first half of the spectrum X = X(1:cutOff); freq = freq(1:cutOff);
At the Matlab Command prompt, type the following to obtain the plot shown below:
fftPlot2 = figure set(fftPlot2,'Position',[500,500,600,300]) zeroPadFactor = nextpow2(length(y)) + 3; [a,b] = positiveFFT_zero_padding(y,Fs,2^zeroPadFactor); plot(b,abs(a)) title('FFT of Sample Signal: Zero Padding up to N = 1024', 'FontWeight','Bold') xlabel('Freq (Hz)') ylabel('Magnitude') grid xlim([0 10])
-
But didn’t we just say that no new information is added? How were we able to distinguish these two peaks if no new information is added?
The information was always there, but it was “hidden” in a way. When we took the FFT of the signal without zero padding, the frequency bins were not fine enough to differentiate the two peaks. By the sampling theorem, as long as you sample a bandlimited signal under the Nyquist rate, you know everything you need to know to perfectly reconstruct the signal. Therefore, at that point, you’ve done the best you can do; you can zero-pad all you want to get more points at the output of your FFT, but you don’t get any new information, because you already have all the information there is on the continuous-time signal.
Inherently, there is nothing wrong with zero-padding in itself. You just have to be careful in its application. Whenever I use the fft command, I tend to use an N that is 4 times larger than the amount of data points within my signal. Zero padding cannot hurt your FFT result.
Conclusion
It is a common misconception that zero-padding adds more information. Zero padding adds NO NEW information. The perceived benefit of zero-padding is increased spectral resolution. You are getting better resolution, but the key is to realize that there is NO NEW information added from the zero-padding. Zero-padding is useful, but it should not be a substitute for taking larger data samples. If you had to choose between taking twice as much data, or to zero pad your data, the answer is to ALWAYS take more data.
Download Source Files
Download the source files that were used in creating the plots.
Sources and References
Zero Padding Does Not Buy Spectral Resolution
33 Responses to “MATLAB - FFT and Zero Padding”
Leave a Reply
Include MATLAB code in your comment by doing the following:
<pre lang="MATLAB">
%insert code here
</pre>


Quan,
Not to salt the wound, but don’t you mean “MATLAB - FFT and Zero Padding” ?
:-0
Wound is salted
. . .
error is fixed
Great page mate
very helpful!!
Very Awesome presentation!!
Waiting for post on windowing and filtering!! (any tentative dates??)
thanks so much,it is very useful
[...] This can be very useful, as it can help you visualize your data better when you plot it. Read this tutorial on zero padding if there’s any confusion [...]
I second Amit K. A windowing/filtering tutorial would be amazing. It’d be nice to know if I was doing things right by comparing with your notes…
Anton and Amit,
I just started writing some stuff on windowing and just published a post today. Hope you guys enjoy it!
Quan
Very clear explanation
thank you
Great post.
Here you are padding a signal in time domain with the fft command. Can you pad the signal that’s already in the frequency domain, like a spectrum?
Hey Wenzao,
Yes, if you zero pad the frequency domain signal and then take the ifft of that signal, you will get a signal that has a “higher resolution” in the time domain. Note that there is no new information added. So basically, the same priniciples apply in both directions.
Quan
Thanks. That’s what I was thinking but not exactly what I need, because I have both time signals and frequency signals and I need to multiply them in frequency domain. So I need to pad both to get the same length and interval. However, I just found the “padarray” command and it works good.
Wenzao,
Be careful padding the data to get the same length and interval. I’m not sure exactly what your application is, but it sounds like it could be very tricky adjusting the lengths by zero padding to synchronize the frequency/time axes. Let me know how it goes.
Quan
In the MATLAB tutorial, namely
, there is this command set
And I am wondering is that a typo in the line starting with NFFT.
Suppose we take a signal that is 50000 samples long. This breaks down because of the to-the-power2 step. It does no harm in the example because it is slightly below the machine limit.
Or do they wanted to zero-pad as much as possible intentionally?
Thanks and congratulations with the MATLAB hiring news…
Arrgh, nevermind, I got the power of 2 twice! There goes another day…
Hi
If I have the peak field data and peak position with discrete number
peak =[[1.3871; -1.3870; 1.3870;...
-1.3872; 1.3867; -1.3871; 1.3861; -1.3874; 1.3862; -1.3876; 1.3869;...
-1.3875; 1.3863; -1.3870; 1.3867; -1.3872; 1.3870; -1.3875; 1.3869;...
-1.3874; 1.3864; -1.3872; 1.3868; -1.3876; 1.3863; -1.3871; 1.3862;...
-1.3874; 1.3870; -1.3872; 1.3866; -1.3880];
position =[83.4; 90.9; 98.4; 105.9; 113.4;...
120.9; 128.4; 135.9; 143.4; 151.0; 158.5; 166.0;...
173.5; 181.0; 188.5; 196.0; 203.5; 210.9; 218.4;...
225.9; 233.4; 240.9; 248.4; 255.9; 263.4; 271.0;...
278.5; 286.0; 293.5; 301.0; 308.5; 316.0]; %in mm along the z-axis
I would like to recreate the sinusoid waveform of the field along the z-axis by using the discrete fourier transform. please suggest me
Thanks
hi!!!
I have several .wav files and i want to make them have the same duration. I think that if want to do that i have to find the one that lasts more and then zero pad the others.
how can i do that?is there any matlab command to figure out the duration of each file?
thank you!!
“no information added by zero padding” is a little bit misleading:
in order to obtain discrete spectra you have to assume (or better work with) a periodical time signal (basics of discrete fourier transform DFT; just compare with fourier series expansion). This period is the overall time of measurement (or your number of samples).
Now, by adding zeros you increase automatically the overal signal period in the time domain - and this is information. Therefore, zero padding does influence the obtained spectrum - possibly in a wrong manner - if the measured signal is not already decayed to zero.
Very useful! Thank you!
Many thanks you are the king
Hi Quan,
I would like to ask you a clarifying question: you say zero padding does not increase the real resolution. It is just equivalent to interpolating. That makes the spectrum look better, closer to its theoretical version.
But the total spectrum range remains the same, with now more samples if we zero pad. To me, that means an increase in resolution….. I guess those interpolated points are not real signal points, so that means that we are not capture more of the signal buy just adding, creating artificial values that make the spectrum visually better….
Is that correct?
Or , is the spectrum getting more points but also getting larger, which means no increase in resolution?
thanks
marco
@Marco
You have the right idea when you said “I guess those interpolated points are not real signal points, so that means that we are not capture more of the signal buy just adding, creating artificial values that make the spectrum visually better….”
When you zero pad, you aren’t adding any “new” information to your signal, but you are making it easier to visualize when you plot the data
Quan
I got a very strange problem. As the post said, zero padding increases the spectral resolution. That is to say, removing zeros hides some details.
Now I have a 512×512 matrix, but only the central 384×384 elements are signals and outer 128 elements are zeros. The FFT of the larger matrix (512 elements) contains 10 straight lines. I believe that the FFT of the smaller matrix (384 element) should also contains 10 straight lines. Strangely the straight lines got huge noises in the FFT of the smaller matrix.
If somebody could kindly offer me help, please contact me at drjinsongliu@gmail.com.
Thanks!
Jinsong
hi
i want to ask whether there is any difference between taking n-point ifft
and then fft for OFDM Vs taking ifft and then n-point fft in matlab.
the difference i get is the signal with n-point ifft and then fft has a
spectrum which do not have good resolution can anyone help me in this
regard.
For example :
actual data =[1 0 0 0]
x = [0 0 1 0 0 0 0 0] %note the zeros at both ends of signal
x=ifft(x)
x=fft(x)
plot(abs(x))
hold on;
y = [1 0 0 0]
y=ifft(y)
y=fft(y,8)
plot(abs(y),’r')
In the first case i have interpolated 2 zeros on either side of the signal
and in the second case i am using the matlab comand to interpolate zeros
.Can you please tell me which one is wrong
Regards
The post is misleading. You see the two peaks after zero padding because the original samples had the required spectral resolution, i.e. fs/N was 100/200 = 0.5. That was exactly equal to the frequency separation between the two peaks. The zero padding won’t resolve the peaks if the second sine wave had a frequency of, say, 4.2 Hz. The signal is still sampled at the same rate, but you won’t see the peaks with any amount of zero padding. So, zero padding in time domain only interpolates in the frequency domain and cannot increase spectral resolving power.
@Bhaskar,
It’s an extreme example that shows that zero padding helps you view the frequency response with more detail via the interpolation. It can’t resolve information that isn’t in the original signal, which is mentioned in the post. Zero-padding adds no information.
Hi, Dear Quan Quach,
I put my question in a website. I am really grateful if you or anybody else would like to give me a hint.
Thanks a lot!
Jinsong
http://sites.google.com/site/zeropaddinghurtsmyfftresult/Home
Hi,
I came across this page today whilst trying to gather information on how to zero pad a signal which consists of 2 sine waves and some weak noise. However, the article contains everything (albeit very useful) except the code for carrying out the zero padding illustrated. Could you please supply me with the code.
Many thanks in advance.
Kola
Thanks to you,
finally I really understand for zero-padding is good for!!
Merci
I would add writing about Zero Padding in the Frequency Domain.
“Now, by adding zeros you increase automatically the overal signal period in the time domain - and this is information. Therefore, zero padding does influence the obtained spectrum - possibly in a wrong manner - if the measured signal is not already decayed to zero.”
My experiments shows the above statement is incorrect.
Hi,
I recently zero padded a sinewave to create a 2048 FFT window. I varied the length of padding and the length of the signal (e.g. doubling the original 720 (degrees) point sine wave) and altered the zero number always to create 2048 points. Trouble is I got quite different amplitudes though the frequencies were correct. Generally more padding gave a lower amplitude (maybe sensible?) But why would that be since from your examples you do not get any change in amplitude for different padding lengths on the same sine wave which is what I’d expect not changes amplitude as I got?