0
0
RosHow-ToBeginner · 4 min read

How to Implement FIR Filter in Python: Simple Guide

To implement a FIR filter in Python, you can use the scipy.signal.lfilter function with filter coefficients created by scipy.signal.firwin. This applies the filter to your data by convolving it with the FIR coefficients.
📐

Syntax

The basic syntax to apply a FIR filter in Python is:

  • firwin(numtaps, cutoff, window='hamming', pass_zero='lowpass'): Creates FIR filter coefficients.
  • lfilter(b, a, x): Applies the filter to data x using coefficients b and denominator a.

For FIR filters, a is usually 1 because FIR filters have only zeros (no poles).

python
from scipy.signal import firwin, lfilter

# Create FIR filter coefficients
numtaps = 51  # Number of filter taps (coefficients)
cutoff = 0.3  # Normalized cutoff frequency (0 to 1, where 1 is Nyquist frequency)
coefficients = firwin(numtaps, cutoff, window='hamming')

# Apply FIR filter to data
# b = coefficients, a = 1 for FIR filter
filtered_signal = lfilter(coefficients, 1, [1, 2, 3, 4, 5])
💻

Example

This example shows how to create a low-pass FIR filter and apply it to a noisy sine wave signal to smooth it.

python
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, lfilter

# Generate sample data: noisy sine wave
fs = 500  # Sampling frequency in Hz
T = 1.0   # seconds
t = np.linspace(0, T, int(fs*T), endpoint=False)
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.random.randn(len(t))

# Design FIR filter
numtaps = 101
cutoff = 0.1  # Normalized cutoff frequency (0 to 1, where 1 is Nyquist frequency)
coefficients = firwin(numtaps, cutoff, window='hamming')

# Apply FIR filter
filtered_signal = lfilter(coefficients, 1, signal)

# Plot original and filtered signals
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.title('FIR Filter Applied to Noisy Signal')
plt.legend()
plt.grid(True)
plt.show()
Output
A plot showing the noisy sine wave and the smoother filtered signal over time.
⚠️

Common Pitfalls

  • Wrong cutoff frequency: The cutoff must be normalized between 0 and 1, where 1 is the Nyquist frequency (half the sampling rate).
  • Filter delay: FIR filters introduce delay equal to half the filter length; this can shift your signal in time.
  • Using lfilter vs filtfilt: lfilter applies filter once causing phase delay; filtfilt applies forward and backward to remove delay but doubles computation.
  • Filter length too short: Too few taps can cause poor filtering; too many taps increase computation.
python
from scipy.signal import filtfilt

# Using lfilter (causes delay)
filtered_lfilter = lfilter(coefficients, 1, signal)

# Using filtfilt (zero phase delay)
filtered_filtfilt = filtfilt(coefficients, 1, signal)
📊

Quick Reference

Here is a quick summary of key FIR filter steps in Python:

StepFunctionDescription
Design filterfirwin(numtaps, cutoff)Create FIR coefficients
Apply filterlfilter(b, 1, x)Filter signal x with coefficients b
Remove delayfiltfilt(b, 1, x)Zero-phase filtering (optional)
StepFunctionDescription
Design filterfirwin(numtaps, cutoff)Create FIR coefficients
Apply filterlfilter(b, 1, x)Filter signal x with coefficients b
Remove delayfiltfilt(b, 1, x)Zero-phase filtering (optional)

Key Takeaways

Use scipy.signal.firwin to create FIR filter coefficients with desired cutoff.
Apply the FIR filter to data using scipy.signal.lfilter with denominator 1.
Normalize cutoff frequency between 0 and 1, where 1 is Nyquist frequency.
FIR filters introduce delay; use filtfilt to remove phase delay if needed.
Choose filter length (numtaps) carefully for balance between smoothness and performance.