Signal Processing

Designing Butterworth Filters with SciPy’s signal.butter

Spread the love

The SciPy library is a powerful resource for scientific computing, and its scipy.signal module provides comprehensive tools for signal processing. Filtering is a fundamental aspect of signal processing, and Butterworth filters are frequently employed due to their maximally flat magnitude response in the passband. This article delves into the scipy.signal.butter function, a key tool for designing these filters within SciPy.

Table of Contents

Understanding Butterworth Filters

Butterworth filters are celebrated for their maximally flat magnitude response within the passband. This characteristic ensures minimal signal distortion in the desired frequency range. However, this flatness comes at the cost of a relatively gradual roll-off in the stopband (the frequency range where the filter attenuates the signal). Achieving a steeper roll-off necessitates a higher filter order.

Using scipy.signal.butter

The scipy.signal.butter function is the primary tool for designing Butterworth filters in SciPy. Its key parameters are:

  • N: The filter order. Higher orders yield steeper roll-off but increase complexity and potential instability.
  • Wn: The cutoff frequency (or frequencies for bandpass and bandstop filters), normalized to the Nyquist frequency (half the sampling rate). A value of 0.5 represents half the sampling rate.
  • btype: The filter type: ‘lowpass’, ‘highpass’, ‘bandpass’, or ‘bandstop’.
  • analog: True designs an analog filter; False (default) designs a digital filter.
  • output: Specifies the output format. ‘ba’ (numerator and denominator coefficients) and ‘sos’ (second-order sections) are common options. ‘sos’ is generally preferred for numerical stability, especially with higher-order filters.

Example: Designing a Lowpass Butterworth Filter

Let’s design a 4th-order lowpass Butterworth filter with a 10 Hz cutoff frequency, assuming a 100 Hz sampling rate:


import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Sampling rate
fs = 100  # Hz

# Cutoff frequency (normalized)
cutoff = 10 / (fs / 2)  # Normalize to Nyquist frequency

# Filter order
order = 4

# Design the filter using SOS for stability
sos = signal.butter(order, cutoff, btype='lowpass', analog=False, output='sos')

#Print SOS
print("Second-order sections (sos):", sos)

Example: Applying the Filter and Visualization

To apply the filter and visualize the results:


# Example signal
t = np.linspace(0, 1, fs, endpoint=False)
sig = np.sin(2 * np.pi * 20 * t) + np.sin(2 * np.pi * 5 * t)

# Apply the filter
filtered_sig = signal.sosfilt(sos, sig)

# Plot the original and filtered signals
plt.figure(figsize=(10, 6))
plt.plot(t, sig, label='Original Signal')
plt.plot(t, filtered_sig, label='Filtered Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('Original vs. Filtered Signal')
plt.legend()
plt.grid(True)
plt.show()

Conclusion

scipy.signal.butter is a powerful tool for designing Butterworth filters. Understanding its parameters and utilizing the ‘sos’ output for numerical stability are crucial for effective filter design within your signal processing workflows. Remember to normalize cutoff frequencies to the Nyquist frequency. Visualizing filter responses using Matplotlib enhances understanding and allows for performance analysis.

Leave a Reply

Your email address will not be published. Required fields are marked *