Designing Lowpass Filters with SciPy: From Theory to Practice

Nov 23, 2025 · Programming · 9 views · 7.8

Keywords: SciPy | Lowpass Filter | Signal Processing | Butterworth Filter | Digital Filter

Abstract: This article provides a comprehensive guide to designing and implementing digital lowpass filters using the SciPy library. Through a practical case study of heart rate signal filtering, it delves into key concepts including Nyquist frequency, digital vs. analog filters, and frequency unit conversion. Complete code implementations and frequency response analysis are provided to help readers master the core principles and practical techniques of filter design.

Introduction

Filter design is a fundamental and crucial task in the field of signal processing. This article uses a specific case study of heart rate signal filtering to provide a detailed explanation of how to design and implement digital lowpass filters using the butter and lfilter functions in the SciPy library.

Problem Context

Suppose we need to process a noisy heart rate signal. Since heart rates typically do not exceed 220 beats per minute, we need to filter out all noise components above this frequency. First, we convert 220 beats per minute to Hertz:

cutoff_frequency = 220 / 60 = 3.667 Hz

Key Concepts Explained

Nyquist Frequency

The Nyquist frequency is a core concept in sampling theory, defined as half the sampling frequency. In digital signal processing, all frequencies need to be normalized relative to the Nyquist frequency:

nyquist_frequency = 0.5 * sampling_frequency

This normalization ensures consistency in filter design across different sampling rates.

Digital vs. Analog Filters

When working with discrete sampled data, it is essential to use digital filters rather than analog filters. This is particularly important when using SciPy's butter function:

b, a = butter(order, cutoff, fs=fs, btype='low', analog=False)

Setting analog=False ensures that we obtain digital filter coefficients suitable for discrete-time systems.

Complete Implementation Code

Below is the complete implementation code for the lowpass filter:

import numpy as np from scipy.signal import butter, lfilter, freqz import matplotlib.pyplot as plt def butter_lowpass(cutoff, fs, order=5): return butter(order, cutoff, fs=fs, btype='low', analog=False) def butter_lowpass_filter(data, cutoff, fs, order=5): b, a = butter_lowpass(cutoff, fs, order=order) y = lfilter(b, a, data) return y # Filter parameter settings order = 6 fs = 30.0 # Sampling frequency in Hz cutoff = 3.667 # Cutoff frequency in Hz # Generate test signal T = 5.0 # Signal duration in seconds n = int(T * fs) # Total number of samples t = np.linspace(0, T, n, endpoint=False) data = np.sin(1.2*2*np.pi*t) + 1.5*np.cos(9*2*np.pi*t) + 0.5*np.sin(12.0*2*np.pi*t) # Apply the filter y = butter_lowpass_filter(data, cutoff, fs, order)

Frequency Response Analysis

To verify filter performance, we can plot its frequency response:

# Compute frequency response b, a = butter_lowpass(cutoff, fs, order) w, h = freqz(b, a, fs=fs, worN=8000) # Plot frequency response curve plt.subplot(2, 1, 1) plt.plot(w, np.abs(h), 'b') plt.axvline(cutoff, color='k') plt.xlim(0, 0.5*fs) plt.title("Lowpass Filter Frequency Response") plt.xlabel('Frequency [Hz]') plt.grid()

Result Validation

By comparing the original signal with the filtered signal, we can visually assess the filter's effectiveness:

plt.subplot(2, 1, 2) plt.plot(t, data, 'b-', label='Original data') plt.plot(t, y, 'g-', linewidth=2, label='Filtered data') plt.xlabel('Time [sec]') plt.grid() plt.legend() plt.show()

Common Errors and Considerations

In practical applications, pay attention to the following common issues:

Conclusion

This article provides a detailed, step-by-step guide to designing lowpass filters with SciPy through concrete examples. Proper frequency unit selection, digital filter configuration, and frequency response verification are key to ensuring optimal filter performance. With these fundamentals mastered, readers can extend this knowledge to more complex signal processing tasks.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.