How to Design IIR Filter: Step-by-Step Guide
To design an
IIR filter, first choose the filter type and specifications like cutoff frequency and order. Then use design functions such as scipy.signal.iirfilter to calculate filter coefficients and apply the filter to your data.Syntax
The main function to design an IIR filter in Python is scipy.signal.iirfilter. It requires specifying the filter order, cutoff frequency, filter type (like lowpass, highpass), and design method (like Butterworth, Chebyshev).
- order: The filter order (integer).
- Wn: Cutoff frequency or frequencies (normalized 0 to 1, where 1 is Nyquist frequency).
- btype: Filter type - 'lowpass', 'highpass', 'bandpass', or 'bandstop'.
- ftype: Filter design method - 'butter', 'cheby1', 'cheby2', 'ellip', etc.
- output: Type of output coefficients - usually 'ba' for numerator and denominator.
python
from scipy.signal import iirfilter b, a = iirfilter(order=4, Wn=0.2, btype='lowpass', ftype='butter', output='ba') print('Numerator coefficients:', b) print('Denominator coefficients:', a)
Output
Numerator coefficients: [0.00391622 0.01566487 0.0234973 0.01566487 0.00391622]
Denominator coefficients: [ 1. -3.18063855 3.86119435 -2.11215536 0.43826514]
Example
This example shows how to design a 4th order Butterworth lowpass IIR filter with cutoff frequency 0.2 (normalized). It then applies the filter to a noisy signal and plots the original and filtered signals.
python
import numpy as np import matplotlib.pyplot as plt from scipy.signal import iirfilter, lfilter # Create a noisy signal fs = 1000 # Sampling frequency T = 1.0 # seconds n = int(T * fs) t = np.linspace(0, T, n, endpoint=False) signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.random.randn(n) # Design IIR filter order = 4 cutoff = 0.2 # normalized frequency (0.2 corresponds to 0.2 * Nyquist frequency) b, a = iirfilter(order, cutoff, btype='lowpass', ftype='butter', output='ba') # Apply filter filtered_signal = lfilter(b, a, signal) # Plot results plt.figure(figsize=(10, 6)) plt.plot(t, signal, label='Noisy signal') plt.plot(t, filtered_signal, label='Filtered signal', linewidth=2) plt.xlabel('Time [seconds]') plt.ylabel('Amplitude') plt.legend() plt.title('IIR Butterworth Lowpass Filter') plt.show()
Output
A plot showing the noisy signal and the filtered signal with smoother waveform after filtering.
Common Pitfalls
- Incorrect cutoff frequency: Cutoff frequency must be normalized between 0 and 1, where 1 is the Nyquist frequency (half the sampling rate).
- Filter order too high: High order can cause instability or excessive delay.
- Wrong filter type: Choosing bandpass instead of lowpass or vice versa can cause unexpected results.
- Not checking filter stability: IIR filters can be unstable if designed improperly.
Always verify filter coefficients and test the filter on sample data.
python
from scipy.signal import iirfilter # Wrong: cutoff frequency not normalized (e.g., 200 instead of 0.2) try: b, a = iirfilter(4, 200, btype='lowpass', ftype='butter', output='ba') except ValueError as e: print('Error:', e) # Right: normalized cutoff frequency b, a = iirfilter(4, 0.2, btype='lowpass', ftype='butter', output='ba') print('Filter designed correctly.')
Output
Error: Wn must be greater than 0 and less than 1
Filter designed correctly.
Quick Reference
| Parameter | Description | Example |
|---|---|---|
| order | Filter order (integer) | 4 |
| Wn | Cutoff frequency (normalized 0 to 1) | 0.2 |
| btype | Filter type: lowpass, highpass, bandpass, bandstop | 'lowpass' |
| ftype | Filter design method: butter, cheby1, cheby2, ellip | 'butter' |
| output | Output format: 'ba' for coefficients | 'ba' |
Key Takeaways
Normalize cutoff frequency between 0 and 1 before designing the filter.
Choose filter order carefully to balance performance and stability.
Use scipy.signal.iirfilter to get filter coefficients easily.
Test the filter on sample data to verify correct behavior.
Beware of common mistakes like wrong cutoff frequency or filter type.