MATLAB - Fourier Transforms with freqz
21 Jul 2008 Quan Quach 28 comments 3,791 views
This is the fifth post in the blinkdagger signal processing series.
One of the drawbacks of using the fft command is that it doesn’t give you any information on the frequency axis. It’s up to the user to create the corresponding frequency vector in order to obtain a meaningful FFT result. In the previous post, we discussed how to properly create frequency vectors to correspond with your FFT data.
In this tutorial, we’ll explore a different method to obtain the Fourier Transform of a given signal using a nifty built in command: freqz.
- Example
- Using the fft command
- Using the freqz command
- Two Sided Spectrum
- Positive Frequencies Only
- Defining Your Frequency Interval
- Knowing your Limits
- Conclusion
Example
Let’s use the following code to create an example signal. The example signal is simply a sine wave with a fundamental frequency of 4 Hz.

fo = 4; %frequency of the sine wave in Hz Fs = 100; %sampling rate in Hz Ts = 1/Fs; %sampling time interval t = 0:Ts:1-Ts; %time vector n = length(t); %number of samples, 100 y = 2*sin(2*pi*fo*t); %the sine curve %plot the sine curve in the time domain sinePlot = figure; plot(t,y) xlabel('time (seconds)', 'FontWeight','Bold') ylabel('y(t)', 'FontWeight','Bold') title('Sample Sine Wave', 'FontWeight','Bold') set(sinePlot,'Position',[500,500,500,300]) set(sinePlot,'Color',[0.97 0.97 0.97]) grid

Using the fft command
As discussed in the Introductory FFT Tutorial, the fft command within MATLAB only returns one vector of data. You should read this fft tutorial first if you are unfamiliar with using the fft command. But basically, the fft command only takes in as input the y-data of your time-domain signal. Thus, it only returns the output-data of the fourier transform, which is in complex form.
Using the freqz Command
The freqz command is a pretty versatile command. With this command, you can dictate what frequency range you want to be evaluated. So for example, lets say that I wanted to only look at the range of -5 Hz to 16 Hz, with frequency increments of 1 Hz.
freqzExample = figure; freqRange = -25:1:16; %create a frequency vector from -25 to 16 freqzData = freqz(y,1,freqRange,Fs)/length(y); %get the fourier data stem(freqRange,abs(freqzData)) xlabel('freq (Hz)', 'FontWeight','Bold') ylabel('Amplitude', 'FontWeight','Bold') title('Using the freqz command', 'FontWeight','Bold') set(freqzExample,'Position',[500,500,500,300]) set(freqzExample,'Color',[0.97 0.97 0.97]) xlim([-25 16]); ylim([0 2]); %set axes limits grid
Two Sided Spectrum
If I wanted to do a two sided spectrum, I would have defined the frequency range in the following manner:
twoSided = figure; freqRange = -Fs/2:1:Fs/2; %create a two sided spectrum freqzData = freqz(y,1,freqRange,Fs)/length(y); %get the fourier data stem(freqRange,abs(freqzData)) xlabel('freq (Hz)', 'FontWeight','Bold') ylabel('Amplitude', 'FontWeight','Bold') title('Two Sided Spectrum', 'FontWeight','Bold') set(twoSided,'Position',[500,500,530,300]) set(twoSided,'Color',[0.97 0.97 0.97]) xlim([-50 50]); ylim([0 2]); grid
Positive Frequencies Only
If I only wanted to see a positive portion of the fourier transform:
positiveFreq = figure; freqRange = 0:1:Fs/2; % create a frequency range over the positive frequencies freqzData = freqz(y,1,freqRange,Fs)/length(y); %get the fourier data stem(freqRange,abs(freqzData)) xlabel('freq (Hz)', 'FontWeight','Bold') ylabel('Amplitude', 'FontWeight','Bold') title('Positive Frequencies', 'FontWeight','Bold') set(positiveFreq,'Position',[500,500,500,300]) set(positiveFreq,'Color',[0.97 0.97 0.97]) ylim([0 2]); grid
Defining Your Frequency Interval
In addition to defining my frequency limits, I can only define how fine or coarse I want my frequency interval to be. In the following example, I’m going to increase the frequency resolution. This means that the output data will have 5 times as many data points! 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 here!
frequencyInterval = figure; freqRange = 0:0.2:Fs/2; % frequency vector with increment of 0.2 freqzData = freqz(y,1,freqRange,Fs)/length(y); %get the fourier data stem(freqRange,abs(freqzData)) xlabel('freq (Hz)', 'FontWeight','Bold') ylabel('Amplitude', 'FontWeight','Bold') title('Frequeny Interval Reduced', 'FontWeight','Bold') set(frequencyInterval,'Position',[500,500,500,300]) set(frequencyInterval,'Color',[0.97 0.97 0.97]) ylim([0 2]); grid
Knowing your Limits
The frequency range of your data depends on the sampling rate, Fs. If Fs = 100 Hz, then your spectrum will span from -50 Hz to 50 Hz. What happens if you go outside this range? Simply put, the information is repeated. Let’s see what happens when we define a frequency range from -200 to 200.
freqRange = -200:1:200; %create a frequency vector from -200 to 200 freqzData = freqz(y,1,freqRange,Fs)/length(y); %get the fourier data freqzLimit = figure; stem(freqRange,abs(freqzData)) xlabel('freq (Hz)', 'FontWeight','Bold') ylabel('Amplitude', 'FontWeight','Bold') title('Using the freqz command', 'FontWeight','Bold') set(freqzLimit,'Position',[500,500,500,300]) set(freqzLimit,'Color',[0.97 0.97 0.97]) ylim([0 2]); grid
As you can see, the same information is simply repeated so there is no need to define a frequency vector outside the range of -Fs/2 and Fs/2.
Conclusion
The freqz command is a versatile command which in my opinion, is easier to use than the fft command. The ability to define your frequency axis is very helpful and flexible. With this method, you don’t have to worry about zero padding; you can simply define a very fine frequeny interval to get a better spectral resolution.
28 Responses to “MATLAB - Fourier Transforms with freqz”
Leave a Reply
Include MATLAB code in your comment by doing the following:
<pre lang="MATLAB">
%insert code here
</pre>


Thanks a lot for the great post. I’ve always being using fft and I’d never heard of this freqz command before. It’s really appealing that you can always change the frequency window and interval independently from the time window and interval of the signal. It’s especially useful when I have several sets of signals with different lengths and intervals. I think I can freqz them into frequency domain with same length and do whatever I want, and ifft them back. It would be really nice.
However, when I test this command with a large number of points, say 2^16, the freqz command is just way too slow. Do you experience the same thing?
Hi Wenzao,
You know, I’ve never used it for that many data points. I”ll have to look into it and get back to you.
Quan
I used the above examples to create the fft plots… when i do it your way i get the same/ similar plots to yours. if you look at the matlab example of the fft using their analysis code and your input variables the graphs come out differently. why?
Wenzao,
Can you give me an example of the data that you’re using? I created random vector of size 2^16 and did a freqz on it, and it processed pretty quickly.
Quan
EmptyC,
In the MATLAB documentation, the following code is used:
For one, this snippet of code performs some zero padding by going to the next power of 2. Doing this is desired because it gives the optimal processing speed for fft. Because of the zero padding that occurs, it will not look exactly the same. In addition, only the positive spectrum is plotted. You can check out the previous signal processing tutorials to get a better idea of what is going on.
Quan
in fourier analysis is it desirable to have this zero padding?
ok… i want to be a little clearer. is it truly better to bring the N value to the next power of 2 or is it better to just leave the data as is? in some cases i have 150 and in others 95. basically the number of samples is all over the spectrum.
Is keeping the N value the same for each analyzed file better than letting N be the length of the array?
I am taking Fourier Transform of a femtosecond second Gaussian pulse. This is my code:
When I run it, the fft plot showed up immediately, but the freqz ran for several minutes and gave the same result.
btw, how did you put a frame for the matlab code in your post? It looks neat but I know very little of HTML.
EmptyC,
When you increase the number of sample points to more than the original input signal, this is called zero padding. There is no new information added, but it also doesn’t hurt to do it. One of the reasons why people use a power of 2 for the number of points is because it makes the fft command process faster. For signals that are of the size that you are doing, it really doesn’t make much of a difference.
Personally, I would use the next power of 2, and then multiply by a factor of 4. So if your input signal is 95 points long. I would move it up to 128, and then multiply by 4, giving us 512 points.
Go here for more info on zero padding: http://www.blinkdagger.com/matlab/matlab-fft-and-zero-padding
Quan
Wenzao,
First, in order to use the frames, you need to do the following
<pre lang="MATLAB">
%insert code here
</pre>
Second, it appears that freqz wasn’t meant to be used with such a large signal size. I’ll look into it some more and get back to you!
Quan
Wenzao,
Okay so I quickly ran some cases in MATLAB and it looks like when the data set approaches 10,000 point, it starts to slow down considerably as it is using the polysolver to evaluate the points on the unit circle (hopefully that made sense). Luckily for me, most of the stuff I’ve ever dealt with is around 2000 points or less.
Quan
Thanks a lot! I don’t know what is polysolver but it seems like I have to stick with fft then.
This is definitely more versatile than fft, but are you supposed to be able to get the signal back into the time domain simply by using ifft? I’ve tried using it but end up with a load of complex numbers
Hey Stephen,
I beleive there is
invfreqzinside MATLAB, but i’ll have to check. Never used it before, but I was planning on writing about the IFFT next!Quan
Hi, I’m having a problem with side-bands, and I noticed you have a similar issue when you Increased your frequency interval. Initially you get amplitude of 1 at 4Hz and 0 every where else (starting from 5up and 3down). I decrease the frequency point interval to 0.1 Hz (rather than 1Hz), the amplitude at 3Hz is now around 0.25. It seems odd to me that taking more points actually changes points taken previously when they were more spaced out.
The reason I ask is that I’m working on a similar problem, but I cannot get rid of the sidebands at all if I want any precision. My signal is a 20GHz signal, and I need to see the sideband effects when I change certain things in my program. Essentially I need precision to about 0.5GHz or better. The effects are very small though, and when this artifical sideband is cluttering my waveform, the small effects cannot be seen through the noise. Any suggestions?
Thanks,
Matt
Hi Matt,
If you go to this tutorial, you’ll get a semi-explanation to why this happens.
http://www.blinkdagger.com/matlab/matlab-fft-and-zero-padding
See the part about: Why Does My Output Look Like a Sinc?
When you take more points, you are essentially zero padding the signal.
Assume we have a simple sinusoid as our signal.
When we pad the signal with zeros, we are effectively multiplying a rectangular box with the original signal in the time domain. In the frequency domain, this translates into convolving a sinc function (Fourier transform of a rectangular window) with an impulse (Fourier transform of the simple sinusoid) resulting in a sinc-like output!
Hope this helps,
Quan
Hi im going to find a spectogram plotting frequency as a function of time of water waves measured with a wave gauge.
The input file is a matrix in the following way
time amplitude
0 0
1 0.3
2 0.5
3 0.3
4 0
and so on. The data is huge
All data i sampled at 100 hz…
How do i make this spectogram using fft or freqz?
help spectrogram
if you don’t like the way they do the FFT, then you will be responsible in generating your own frequency & time vectors, and a matrix of fourier amplitudes then use 3D commands like ’surf’ or ‘waterfall’
OK but can you give me a example code that can find a spectogram plotting frequency as a function of time of water waves measured with a wave gauge.
The input file is a matrix in the following way
time amplitude
0 0
1 0.3
2 0.5
3 0.3
4 0
and so on. The data is huge
All data i sampled at 100 hz…
did you try using spectrogram yet?
Thanks for the post. I’ve tried to use freqz and compare with fft. I obtain different result for fft and freqz. But if I inverse both result using ifft, I get the same input signal back. Any explanation on this? Can i use ifft instead of invfreqz? thanks. These was my code:
zayax,
you are doing the exact same thing twice, but naming them differently!
Quan
Hey Quan. First, let me thank you for showing a simply and effective way to implement the fft. I had a hard time getting it to work before I found this site. Have you been able to look into invfreqz? My interest is to take residuals from an OLS fit and remove the autocorrelation that shows up at low frequencies and inverse the Fourier transform to proceed with further calculations. Any help is greatly appreciated.
Chad
Concerning post number 22:
The reason why you see a difference between fft and freqz is:
1) According to your calculations your resulting fft (as your inpur signal) has a length of 501, so not a power of 2, which means other algorithms than the well known butterfly are activated to obtain the spectrum.
2) Your freqz command divides the range between [0,pi) on the unit circle into 502 parts, meaning that you actually obtain twice the frequency resolution as in your fft-obtained spectrum.
To obtain the same results from fft and freqz do:
The results should be the same. Note also that w is always smaller than pi.
How to remove zeros from the figure, because there is no need of showing zero amplitude, is there away to remove zero amplitude…….i just want to show amplitudes greater than zero
Hi there
I think this post is great. Is there any chnace you would be wanting to go through ‘invfreqz’ with us at some point in the future?.
Shobana
Does anybody know how big the errors are when fft or freqz is used on aperiodic instead of periodic signals? Thanks a lot!