This is an archival dump of old wiki content --- see scipy.org for current material.
Please see http://scipy-cookbook.readthedocs.org/

This cookbook recipe demonstrates the use of scipy.signal.butter to create a bandpass Butterworth filter. scipy.signal.freqz is used to compute the frequency response, and scipy.signal.lfilter is used to apply the filter to a signal. (This code was originally given in an answer to a question at stackoverflow.com.)

   1 from scipy.signal import butter, lfilter
   2 
   3 
   4 def butter_bandpass(lowcut, highcut, fs, order=5):
   5     nyq = 0.5 * fs
   6     low = lowcut / nyq
   7     high = highcut / nyq
   8     b, a = butter(order, [low, high], btype='band')
   9     return b, a
  10 
  11 
  12 def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
  13     b, a = butter_bandpass(lowcut, highcut, fs, order=order)
  14     y = lfilter(b, a, data)
  15     return y
  16 
  17 
  18 if __name__ == "__main__":
  19     import numpy as np
  20     import matplotlib.pyplot as plt
  21     from scipy.signal import freqz
  22 
  23     # Sample rate and desired cutoff frequencies (in Hz).
  24     fs = 5000.0
  25     lowcut = 500.0
  26     highcut = 1250.0
  27 
  28     # Plot the frequency response for a few different orders.
  29     plt.figure(1)
  30     plt.clf()
  31     for order in [3, 6, 9]:
  32         b, a = butter_bandpass(lowcut, highcut, fs, order=order)
  33         w, h = freqz(b, a, worN=2000)
  34         plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="order = %d" % order)
  35 
  36     plt.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)],
  37              '--', label='sqrt(0.5)')
  38     plt.xlabel('Frequency (Hz)')
  39     plt.ylabel('Gain')
  40     plt.grid(True)
  41     plt.legend(loc='best')
  42 
  43     # Filter a noisy signal.
  44     T = 0.05
  45     nsamples = T * fs
  46     t = np.linspace(0, T, nsamples, endpoint=False)
  47     a = 0.02
  48     f0 = 600.0
  49     x = 0.1 * np.sin(2 * np.pi * 1.2 * np.sqrt(t))
  50     x += 0.01 * np.cos(2 * np.pi * 312 * t + 0.1)
  51     x += a * np.cos(2 * np.pi * f0 * t + .11)
  52     x += 0.03 * np.cos(2 * np.pi * 2000 * t)
  53     plt.figure(2)
  54     plt.clf()
  55     plt.plot(t, x, label='Noisy signal')
  56 
  57     y = butter_bandpass_filter(x, lowcut, highcut, fs, order=6)
  58     plt.plot(t, y, label='Filtered signal (%g Hz)' % f0)
  59     plt.xlabel('time (seconds)')
  60     plt.hlines([-a, a], 0, T, linestyles='--')
  61     plt.grid(True)
  62     plt.axis('tight')
  63     plt.legend(loc='upper left')
  64 
  65     plt.show()

The plots generated by the above code:

butterworth_bandpass_frequency_response.png butterworth_bandpass_example.png

SciPy: Cookbook/ButterworthBandpass (last edited 2015-10-24 17:48:26 by anonymous)