iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use scipy.signal.butter to design a low-pass, high-pass, band-pass, or band-stop Butterworth filter. For most digital work, request second-order sections with output="sos"; specify the cutoff carefully, then choose between causal filtering with sosfilt and offline forward-backward filtering with sosfiltfilt based on your timing and phase requirements.
What a Butterworth filter does
A Butterworth filter is designed for a maximally flat passband response. In SciPy, its critical frequency Wn is the half-power point, corresponding to −3 dB. The scipy.signal.butter function returns filter coefficients; it does not apply them to your data.
The function supports low-pass, high-pass, band-pass, and band-stop designs. The documented SciPy 1.18.0 signature is butter(N, Wn, btype='low', analog=False, output='ba', fs=None). Check the documentation for the SciPy version installed in your environment, since API details can vary by release. See the SciPy 1.18.0 butter reference.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Choose the right cutoff units
For a digital filter, Wn follows one of two conventions. If you omit fs, SciPy treats the cutoff as a fraction of the Nyquist frequency, with 1 representing Nyquist. If you provide fs, express Wn in the same units as the sampling frequency, such as hertz when fs is in hertz.
#1 Best Overall
For an analog filter, set analog=True; then Wn is angular frequency in radians per second, not hertz. Do not mix the analog convention with digital sampling-frequency values.
- Digital, normalized: omit
fs;Wn=0.125means 0.125 of Nyquist. - Digital, explicit units: provide
fs; use the same units forWnandfs. - Analog: set
analog=True; specify angular frequency in radians per second.
For low-pass and high-pass designs, Wn is a scalar. For band-pass and band-stop designs, give a pair of edge frequencies. In a band-pass or band-stop design, order N produces an overall filter order of 2*N, represented by N biquad sections when using SOS output.
Rank #2
Design the filter and choose a coefficient format
Although ba (numerator and denominator polynomial coefficients) is the documented default, SciPy recommends second-order sections for general-purpose filtering. A single high-degree polynomial can be numerically sensitive, especially for high-order or narrowband designs. SOS represents the filter as a cascade of lower-order sections and is generally the safer choice for filtering.
This example designs a digital high-pass filter with a 15 Hz cutoff and a 1,000 Hz sampling rate, then applies it causally:
Rank #3
from scipy import signal
sos = signal.butter(10, 15, btype="highpass", fs=1000, output="sos")
y = signal.sosfilt(sos, x)
Here, x is your input signal, and y is the filtered output. If another library or interface specifically requires polynomial coefficients, you can request output="ba", but inspect the response and numerical behavior when the design is high-order or narrowband. The sosfilt reference describes filtering with SOS coefficients.
Choose causal filtering or zero-phase filtering
The filtering function determines how the designed filter is applied. A causal forward pass is suitable for sequential or streaming data, but it can introduce phase delay. Forward-backward filtering avoids phase delay by processing a data segment in both directions, but it requires the segment rather than only the current sample and doubles the effective filter order.
Rank #4
Use sosfilt for a forward causal pass
Use signal.sosfilt(sos, x) when data must be processed in sequence or when causal behavior matters. Account for the filter’s phase delay in downstream timing or phase-sensitive analysis.
Use sosfiltfilt for offline zero-phase filtering
When you can process a complete record and zero phase is appropriate, apply the SOS filter forward and backward:
Best Value
from scipy import signal
sos = signal.butter(4, 0.125, output="sos")
y = signal.sosfiltfilt(sos, x)
Because fs is omitted, the cutoff is 0.125 of Nyquist. Forward-backward processing changes the effective order, so it is not equivalent to a single forward pass of the designed order. Endpoint handling also matters: padding and transients near the start and end can affect results, particularly for short records. Consult the sosfiltfilt reference for its padding and edge behavior. The related filtfilt reference documents the forward-backward method.
Set the order from passband and stopband requirements
If you know the passband edge, stopband edge, maximum passband loss, and required stopband attenuation, use buttord to calculate the minimum Butterworth order and its natural frequency. Pass both returned values to butter. If you use fs, pass it consistently to both functions.
from scipy import signal
N, Wn = signal.buttord(wp, ws, gpass, gstop, fs=fs)
sos = signal.butter(N, Wn, btype="lowpass", fs=fs, output="sos")
Choose wp, ws, and the filter type to match your actual specification; the low-pass type above is only an example. For analog designs, set analog=True in both functions and express edge frequencies in radians per second. SciPy’s documented buttord reference includes an analog band-pass example with specified passband loss and stopband attenuation.
Verify the design against the signal-processing goal
Before relying on a filter, check that the selected cutoff convention, type, and order match the intended task. A Butterworth cutoff is a half-power point; that edge convention differs from the conventions used by some other design functions, including FIR design functions. SciPy’s iirdesign reference also describes Butterworth as an available IIR filter type and identifies the half-power cutoff convention.
- Confirm whether your cutoff is normalized to Nyquist, in the units of
fs, or an analog angular frequency. - Use SOS for ordinary filtering, and be especially cautious with polynomial coefficients for high-order or narrowband designs.
- Choose a causal forward pass for sequential processing; choose forward-backward processing only when offline segment processing and its changed order and edge behavior are acceptable.
- When the specification gives passband and stopband limits, derive the order with
buttordrather than choosing it by intuition.
The SciPy signal-processing tutorial, signal API index, and lfilter reference provide additional context for SciPy’s signal tools and filtering interfaces.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

