0
0
RosHow-ToBeginner · 4 min read

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

ParameterDescriptionExample
orderFilter order (integer)4
WnCutoff frequency (normalized 0 to 1)0.2
btypeFilter type: lowpass, highpass, bandpass, bandstop'lowpass'
ftypeFilter design method: butter, cheby1, cheby2, ellip'butter'
outputOutput 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.