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:

enter image description here

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 (250 in my case) I get as FFT:

enter image description here

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?

Thank you!

  • Why has the amplitude increased so much? What happens if you plot on a log-log axis? – endolith Nov 5 '14 at 15:02
  • The amplitude has increased because all the energy now is only a few frequencies. That is precisely the problem, I don't know why that happens. I don't see how a log plot would help here. – Ambesh Nov 5 '14 at 15:14
  • A butterworth filter only decreases amplitude at some frequencies and leaves others unchanged, it will not increase them. log-log plot will show this clearly. commons.wikimedia.org/wiki/File:Butterlog.png – endolith Nov 5 '14 at 16:56
  • If I must point into some direction, I would check if the filter coefficients are calculated for a digital filter (analog=False as sg.butter parameter) However, something does not make sense on those signals but I am not yet sure what it can be. Could you send more information about the signal origin? What is the actual sampling rate (250 Hz I understand)?, how are you calculating the FFT?, Could you post the whole piece of code you are using (also for plotting). – Gaussiano Oct 11 at 11:11

(Not an answer, but can't post code in a comment)

Works fine for me:

from

 __future__ import division
from numpy.random import randn
from numpy.fft import rfft
from scipy.signal import butter, lfilter
from matplotlib.pyplot import loglog

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

fs = 250
lowcut = 1.0
highcut = 50.0
x_Vtcr = randn(10000)
x2_Vtcr = butter_bandpass_filter(x_Vtcr, lowcut, highcut, fs, order=4)
loglog(abs(rfft(x_Vtcr)))
loglog(abs(rfft(x2_Vtcr)))

What do you get that's different from this?

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.