Python scipy.signal IIR Filter Design


The following is an introduction on how to design an infinite impulse response (IIR) filters using the Python scipy.signal package.  This post, mainly, covers how to use the scipy.signal package and is not a thorough introduction to IIR filter design.  For complete coverage of IIR filter design and structure see one of the references.

Filter Specification

Before providing some examples lets review the specifications for a filter design.  A filter is usually defined in the frequency domain.  The following figure depicts the frequency domain specification.


The specification figure illustrates a low-pass filter but the terminology applies to all filter types, lowpass, highpass, bandpass, and stopband.

This article is available in PDF format for easy printing
  • Passband (Wp) : This is the frequency range which we desire to let the signal through with minimal attenuation. In the scipy functions this is in normalized frequency, 1 > Wp > 0.
  • Stopband (Ws) : This is the frequency range which the signal should be attenuated. Again, in scipy this is in normalized frequency, 1 > Ws > 0.
  • Passband ripple (Rp, gpass) : The max variation in the passband, in decibals.
  • Stopband attenuation (As, gstop) : The max level in the stopband or in other words the min attenuation in the stopband, in decibals.

NOTE: The cutoff frequency is the -3dB point.  If the cutoff frequency is required the algorithm will work to meet the -3dB point at the Wc frequency.  The pass frequency, Wp, is the last, first, or first and last frequencies in the passband which the Rp value occurs (the rest are less).  See the zoomed in frequency plots below for an example.

The above specifications are the information that will be used and passed to the IIR filter design functions. In addition to our filter specification information we need to select our "filter" type.  The following table summarizes the different IIR filter design approaches supported by the scipy.signal design functions.  The following table was taken verbatim from [4].

IIR Filter Types, verbatim from [4] Grover and Deller, "DSP for micro..."
Bessel Knee? What knee? Monotonic Monotonic Near-linear s-to-z mappings distort phase. FIR usually more efficient for linear phase
Butterworth Rounded Maximally flat, monotonic Monotonic nonlinear near cutoff Easy to design by had Maple syrup is better on waffles
Chebychev I Sharp Ripples Monotonic Worse Easy to design by hand
Chebychev II Sharp Monotonic Ripples Worse Somewhat more complicated design than Chebychev I
Elliptic Maximally sharp Ripples Ripples Drunk fly on cross- country skies in a tornado Not viable for design by hand

Side note, the Digital Signal Processing and the Microcontroller book has some great -geek- humor.

Discrete Filter Design

If it wasn't already known, now we know the information needed to use the scipy.signal IIR filter design functions.  Let's look at the scipy.signal.filter_design.iirdesign function arguments.


A couple comments on the arguments to the iirdesign function; wp is the pass frequency, this is the last point where gpass (Rp) occurs.  And ws is the frequency where the magnitude will be less than -gstop (As).  The wp and ws arguments are in normalized frequency, 0 < wp (ws) < 1, where 1 is the Nyquist frequency. And gpass and gstop are defined in decibals.  ftype is the filter design type, which can be one of the following ['ellip', 'butter', 'cheby1', cheby2', 'bessel']. For additional information see the iirdesign documentation.

To design an IIR filter in python.scipy we are going import the basic numerical, scientific, and plotting packages.

Then create the coefficients for each of the filter types.

Plotting the frequency response for the designed filters we get the following. 

iir_ex1_freq iir_ex1_freq_pass

From the plots we can see that the 'ellip' and 'cheby2' have the steepest transition band.  The others have fairly mellow transitions.


From the phase response we can see the bessel has near linear phase.  But it is usually better to use a FIR if linear phase is required vs. trying to achieve the desired response with a higher order bessel.

We can also plot the impulse response for each of the filters.


The elliptical and the chebychev 2 filters can do much better in the transition band.  But to achieve the steeper transition need to pull in Ws.  The butterworth and chebychev 1 filters would fail with a more aggressive Ws or lower As.  The following plots show how we can build a more aggressive filter with the 'ellip' and 'cheby2' filters.


Functions: iirdesign and iirfilter

The iirdesign takes our filter specifications and uses one of the IIR filter design methods to generate the coefficients.  The design methods determine the order of the filter.  The iirfilter function will take the desired order.  There are other functions to help determine the order per the specifications.  The response will be based off the order vs. trying to achieve some set of specifications.

Look for the next post where examples for highpass, bandpass, and stopband will be covered using the iirdesign function.  For more information and background, Rick Lyon's Understanding Digital Signal Processing is always a good place to start.

Software Acknowledgements

Different open-source packages and sources were used. Here I try and mention a couple; the sane mpl color scheme was used in all the plots.  And the ipython qtconsole and notebook were used to generate plots and experiment with the scipy functions.


[1] R. Lyons, "Understanding Digital Signal Processing",
      2nd ed., Prentice Hall, Upper Saddle River, New Jersey, 2004 
[2] A. Oppenheim, R Schafer, and J. Buck, "Discrete-Time Signal Processing",
      2nd ed., Prentice Hall, Upper Saddle River, New Jersey, 1999
[3] S. Smith, "The Scientist and Engineer's Guide to Digital
      Signal Processing", Chp. 17.
[4] D. Grover and J. Deller, "Digital Signal Processing and the microcontroller",
      Prentice Hall, Upper Saddle River, New Jersey, 1999
[5] S. Orfandis, "Introduction to Signal Processing",Chp. 11.2, pg 566.

[ - ]
Comment by fwkzNovember 13, 2012
What about phase responsehere? They are smooth line. When I execute this code i get saw tooth-ish shape not a smooth line like here. How do you compute/plot phase characteristics here to get such a shape?
[ - ]
Comment by cfeltonNovember 13, 2012
Look at the y-axis scale on you plots. Is it between 2pi and -2pi? You can use the *unwrap* function to allow the phase response to be outside mod 2pi.
[ - ]
Comment by ssudspMay 20, 2013
Great tutorial. How do you go from filter design to your plots though (the code seems to be missing)? I've looked into the arrays created by iirdesign() and they look like they might be the A and B coeffectients? I don't have much experience with scipy and matplotlib so there is probably a simple answer.

[ - ]
Comment by cfeltonMay 21, 2013
[This](http://www.dsprelated.com/showcode/270.php) code snippet includes an example using the signal.freqz and plotting the response.

Hope that helps,

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: