HOWTO · SciPy
SciPy signal.butter
Diseña y aplica un filtro Butterworth de paso de banda en Python con scipy.signal.butter, secciones de segundo orden y una gráfica de la señal.
En esta página
Usa scipy.signal.butter para diseñar un filtro Butterworth y, después, aplica las secciones de segundo orden resultantes a una señal muestreada. Este ejemplo conserva una componente de 50 Hz y reduce otra de 250 Hz, y representa la señal de entrada junto al resultado filtrado. Usa sosfiltfilt para filtrar en ambas direcciones, lo que evita el desfase de una única pasada hacia adelante.
La función diseña filtros Butterworth digitales o analógicos; no filtra los datos por sí misma. La referencia oficial de procesamiento de señales de SciPy documenta las funciones de diseño de filtros.
Usa scipy.signal.butter para diseñar un filtro Butterworth
Un diseño Butterworth tiene una respuesta en magnitud máximamente plana en su banda de paso. La función scipy.signal.butter devuelve los coeficientes del filtro; para el filtrado digital práctico, solicita secciones de segundo orden con output="sos". En filtros de orden alto, esta representación suele ofrecer mayor robustez numérica que un único numerador y denominador.
El argumento N indica el orden del filtro. En un diseño pasabanda, la función de transferencia resultante tiene orden 2 * N; el parámetro N sigue indicando el orden que se pasa a la función de diseño. El argumento Wn especifica la frecuencia crítica o, para un filtro pasabanda, un rango de dos valores ordenados de menor a mayor. Son frecuencias de diseño, no especificaciones independientes de las bandas de paso y de rechazo. Un filtro Butterworth tiene una ganancia aproximada de 1/√2 (−3 dB) en cada frecuencia crítica.
Elige el tipo de filtro, el orden y las frecuencias críticas
Establece btype="bandpass" para conservar las frecuencias entre dos límites. Para un filtro de paso bajo, usa "lowpass"; para uno de paso alto, usa "highpass"; y para uno de rechazo de banda, usa "bandstop". Los límites deben ser positivos, estar en orden creciente y quedar por debajo de la mitad de la frecuencia de muestreo.
Si proporcionas fs, expresa Wn en las mismas unidades que fs (por ejemplo, ambos en hercios). Si omites fs, SciPy interpreta las frecuencias críticas digitales en unidades donde 1 equivale a la frecuencia de Nyquist, es decir, la mitad de la frecuencia de muestreo. Por ejemplo, una frecuencia crítica de 100 Hz con fs=1000 Hz equivale a Wn=0.2 si omites fs.
Elige el orden según la pendiente de transición y el coste computacional que requiera tu aplicación. Un orden mayor hace más pronunciada la transición, pero aumenta el cálculo y puede volver el diseño más sensible a los efectos numéricos. No garantiza un mejor resultado para todas las señales. Si necesitas especificar la ondulación de la banda de paso o la atenuación de la banda de rechazo, utiliza un método de diseño que admita esas especificaciones, como scipy.signal.iirdesign.
Aplica el filtro a una señal
Este ejemplo ejecutable muestrea una señal a 1000 Hz. Su componente de 50 Hz está dentro de la banda de paso de 40–100 Hz, mientras que la componente de 250 Hz queda fuera. sosfiltfilt aplica las secciones hacia adelante y hacia atrás, de modo que el resultado no presenta el desfase de un filtro causal de una sola pasada. Antes de ejecutar el ejemplo, instala SciPy, NumPy y Matplotlib en tu entorno de Python. El ejemplo guarda la figura comparativa como butterworth_filter.png en el directorio actual.
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import butter, sosfiltfilt
fs = 1000.0
duration = 1.0
t = np.arange(0.0, duration, 1.0 / fs)
signal = np.sin(2.0 * np.pi * 50.0 * t) + 0.6 * np.sin(2.0 * np.pi * 250.0 * t)
sos = butter(4, [40.0, 100.0], btype="bandpass", fs=fs, output="sos")
filtered = sosfiltfilt(sos, signal)
fig, axes = plt.subplots(2, 1, sharex=True, figsize=(9, 5))
axes[0].plot(t, signal, label="Input")
axes[0].set_ylabel("Amplitude")
axes[0].legend()
axes[1].plot(t, filtered, label="Filtered", color="tab:orange")
axes[1].set_xlabel("Time (s)")
axes[1].set_ylabel("Amplitude")
axes[1].legend()
fig.tight_layout()
fig.savefig("butterworth_filter.png", dpi=150)
plt.close(fig)
La entrada es la suma de dos sinusoides conocidas, así que el ejemplo es reproducible y no depende del ruido aleatorio. Para usar tus propias muestras, sustituye signal y establece fs con su frecuencia de muestreo; mantén las unidades de la matriz de señal y de los ajustes del filtro coherentes. Para el procesamiento en flujo o en tiempo real, utiliza un filtro de una sola pasada, como sosfilt, y ten en cuenta su fase y su comportamiento inicial.
Representa e interpreta la señal filtrada
Abre butterworth_filter.png para comparar, durante el mismo intervalo de tiempo, la entrada combinada en el primer eje con las muestras filtradas en el segundo. La oscilación de 50 Hz sigue siendo destacada, mientras que la componente de 250 Hz se atenúa. La gráfica permite una comparación cualitativa, pero no garantiza amplitudes exactas: la respuesta cambia gradualmente cerca de cada frecuencia crítica y el resultado también depende de los datos y del orden del filtro.
El ejemplo representado usa filtrado en ambas direcciones, que procesa los datos hacia adelante y hacia atrás. Esto elimina el retardo de fase, pero hace que la operación no sea causal, por lo que resulta adecuada para datos sin conexión y no para un flujo en directo. El filtrado en ambas direcciones también puede producir transitorios cerca del principio y del final de un registro finito. Examina esas zonas antes de interpretar mediciones en ellas. Para datos en directo, utiliza en su lugar un filtro causal y ten en cuenta su retardo y el comportamiento de su estado inicial.
Errores frecuentes: frecuencia de muestreo, orden del filtro y transitorios
- Frecuencia de muestreo:
fsdebe corresponder a los datos que realmente has muestreado. Si no coincide, cambia el significado físico de todas las frecuencias del diseño. Las frecuencias iguales o superiores a la frecuencia de Nyquist no se pueden representar de forma fiable en datos muestreados; antes de muestrear, utiliza una frecuencia de adquisición adecuada y un filtro antialias. - Orden del filtro:
Nno es una medida de intensidad. Al aumentarlo, la transición se vuelve más pronunciada y crecen los costes computacionales y numéricos. Compara la respuesta obtenida con los requisitos de tu tarea, en vez de suponer que conviene usar el mayor orden posible. - Argumentos de frecuencia: Si proporcionas
fs, usa las mismas unidades paraWnyfs. Si omitesfs, normaliza las frecuencias digitales respecto de la frecuencia de Nyquist. En un filtro pasabanda,Wncontiene las frecuencias críticas inferior y superior; no expresa los límites de la banda de rechazo ni objetivos de atenuación. - Transitorios y dirección:
sosfiltfiltes una operación práctica sin desfase para el procesamiento sin conexión, mientras quesosfiltes una operación causal de una sola pasada, adecuada para flujos de datos. Ambas pueden presentar efectos de inicio o de borde; deja suficientes datos alrededor de la región que quieras analizar y revisa los extremos.