Illustrate some signal filtering function from scipy.signal
(http://docs.scipy.org/doc/scipy-0.14.0/reference/signal.html)
Similar to Matlab IIR filter design functions (http://mathworks.com/help/signal/ug/iir-filter-design.html)
import numpy as np
import scipy.signal as sig
iirdesign
: http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.iirdesign.htmliirfilter
: http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.iirfilter.htmlsig.iirdesign?
Example:
b,a = sig.iirdesign(wp = 0.001, ws=0.1,
gpass=3, gstop=40,
analog=False,
ftype='butter')
b, a
Compute the step response, using lfilter
(http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.lfilter.html)
N = 2*10**3
x = np.zeros(N)
x[N//10:] = 1
y = sig.lfilter(b,a, x)
np.ones(3) * 2 +1
import matplotlib.pyplot as plt
%matplotlib inline
t = np.arange(N)
plt.plot(t, x, 'k')
plt.plot(t, y, 'b', linewidth=2)
plt.ylim(-0.1, 1.5)
plt.grid()
dict of available filter types
ftypes = {
'butter': 'Butterworth',
'cheby1': 'Chebyshev I',
'cheby2': 'Chebyshev II',
'ellip': 'Cauer/elliptic',
#'bessel': 'Bessel/Thomson' # order selection not available for Bessel
}
groupe the above code in one single function:
def plot_step_resp(wp_log = -3, ws_log=-1,
gpass=3, gstop=40,
ftype='butter'):
# 1) Design the filter
wp = 10**wp_log
ws = 10**ws_log
b,a = sig.iirdesign(wp, ws, gpass, gstop, False, ftype)
N_ord = max(len(b), len(a))
# 2) Compute the impulse response
y = sig.lfilter(b,a, x)
# 3) Plot
t = np.arange(N)
plt.plot(t, x, 'k')
plt.plot(t, y, 'b', lw=2)
plt.ylim(-0.1, 1.5)
plt.grid()
plt.title('{} filter of order {}, with\n wp=$10^{{{:.1f}}}$, ws=$10^{{{:.1f}}}$, Gp=-{:.1f} dB, Gs=-{:.1f} dB'.format(
ftypes[ftype], N_ord, wp_log, ws_log, gpass, gstop))
Test the function
plot_step_resp(wp_log = -3, ws_log= -2,
gpass=3, gstop=40,
ftype='butter')
cf. widget doc: http://nbviewer.ipython.org/github/jvns/ipython/blob/master/examples/Interactive%20Widgets/Index.ipynb
from IPython.html.widgets import interact
For each parameter, we give an interval of allowed values
interact(plot_step_resp,
wp_log=[-3, -1.],
ws_log=[-2., 0],
gpass=[0.5,6], gstop=[10, 100], ftype=ftypes.keys());
compute the poles and zeros of the transfer function:
tf2zpk
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.tf2zpk.html
sig.tf2zpk?
def plot_roots(wp_log = -3, ws_log=-1,
gpass=3, gstop=40,
ftype='butter', zoom=False):
# 1) Design the filter
wp = 10**wp_log
ws = 10**ws_log
b,a = sig.iirdesign(wp, ws, gpass, gstop, False, ftype)
N_ord = max(len(b), len(a))
# 2) Compute the zeros and poles
z, p, k = sig.tf2zpk(b, a)
# 3) Plot
theta = np.linspace(0, np.pi*2, 500)
circle = np.exp(1j*theta)
plt.plot(circle.real, circle.imag, 'k')
plt.plot(z.real, z.imag, 'c*', ms=10)
plt.plot(p.real, p.imag, 'rD')
ax = plt.gca()
ax.set(aspect='equal',
xlim=(-1.1, 1.1), ylim=(-1.1, 1.1),
)
if zoom:
ax.set(xlim=(0.9, 1.1), ylim=(-0.1, 0.1))
plt.title('{} filter of order {}, with\n wp=$10^{{{:.1f}}}$, ws=$10^{{{:.1f}}}$, Gp=-{:.1f} dB, Gs=-{:.1f} dB'.format(
ftypes[ftype], N_ord, wp_log, ws_log, gpass, gstop))
plot_roots(wp_log = -3, ws_log= -1,
gpass=3, gstop=40,
ftype='cheby1')
interact(plot_roots,
wp_log=[-3, -1.],
ws_log=[-2., 0],
gpass=[0.5,6], gstop=[10, 100], ftype=ftypes.keys());