Reputation: 167
I've been playing around with filters using scipy, trying to filter a signal. After reading the documentation and going through a few examples, I thought I got it, but it seems like I'm doing something wrong and can't get it to work.
Using a bandstop filter below, I'd expect the variable fy to be pretty much constant, but I see can see no difference between the data and filtered sine wave.
import pylab as plt
import numpy as np
import scipy
numsamples=1000
f0=1/10
x=np.linspace(0,100,numsamples)
y=np.sin(2*np.pi*f0*x)
fs=numsamples/(max(x)-min(x))
nyquist=0.5*fs
fstart=(3/4)*f0/nyquist
fstop=(4/3)*f0/nyquist
a,b = scipy.signal.butter(2,[fstart,fstop],'bandstop', analog=True)
fy = scipy.signal.lfilter(a,b,y, axis=-1, zi=None)
plt.plot(y)
plt.plot(fy)
plt.show()
Thanks for your help,
Mike
Upvotes: 0
Views: 3487
Reputation: 4697
I think you should drop the "analog=True" from your call to scipy.signal.butter and use the default digital filter. When I did this with your data, it worked pretty well.
From the docs:
A scalar or length-2 sequence giving the critical frequencies. For a Butterworth filter, this is the point at which the gain drops to 1/sqrt(2) that of the passband (the “-3 dB point”). For digital filters, Wn is normalized from 0 to 1, where 1 is the Nyquist frequency, pi radians/sample. (Wn is thus in half-cycles / sample.) For analog filters, Wn is an angular frequency (e.g. rad/s).
Because you requested an analog filter, you shouldn't have normalized the start and stop frequencies to the nyquist rate. That's only appropriate for a digital filter.
Is there a reason you want to use an analog filter here? I always use digital filters.
Also, consider using scipy.signal.filtfilt
instead of scipy.signal.lfilter
. Refs:
How To apply a filter to a signal in python
Upvotes: 1