Reputation: 305
I'm trying to use a Butterworth filter in Python as described in this thread with these functions:
def butter_bandpass(lowcut, highcut, fs, order=5):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = butter(order, [low, high], btype='band')
return b, a
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = lfilter(b, a, data)
return y
The output of the FFT of my data without applying the filter gives the following plot:
However, after applying the filter above with:
lowcut = 1.0
highcut = 50.0
x2_Vtcr = butter_bandpass_filter(x_Vtcr, lowcut, highcut, fs, order=4)
where fs is the sampling frequency (1000 in my case) I get as FFT:
It looks like the filter shifts the frequency to the left and I don't get the peak where it should be. Any idea as to why this is happening?
Just in case I place where the data file (second column). The DC is quite strong so after FFT the first element should not be included in the plot.
Thank you!
Upvotes: 1
Views: 6452
Reputation: 22701
The 2 functions above seem to work fine here. This is an example of a white noise signal sampled at your fs=250
, and filtered with the two functions you mention, with a passband between 1Hz and 50 Hz as you do:
from numpy import random, arange
from numpy.fft import rfft, rfftfreq
fs = 250.
t = arange(0., 30., 1 / fs)
x_Vtcr = random.randn(len(t))
hat_x_Vtcr = rfft(x_Vtcr)
freqs = rfftfreq(x_Vtcr.size, 1 / fs)
plt.plot(freqs, abs(hat_x_Vtcr), 'b')
lowcut, highcut = 1.0, 50.0
x2_Vtcr = butter_bandpass_filter(x_Vtcr, lowcut, highcut, fs, order=4)
hat_x2_Vtcr = rfft(x2_Vtcr)
plt.plot(freqs, abs(hat_x2_Vtcr), 'r')
The resulting PSD is fine with me (red is the filtered one):
I guess your error is somewhere else? Please compare your code with the above snippet. You may also want to read THIS for next time.
EDIT:reply to the comment.
It does indeed work also with your data. I did:
datafile=loadtxt('V.dat')
x_Vtcr=datafile[:,1]
x_Vtcr-=x_Vtcr.mean()
and then I ran the above script, without the line on which I generate the x_Vtcr
data of course. The resulting filtered output follows:
Upvotes: 1