# Butterworth filter in python

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 (250 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?

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 '18 at 11:11

## 1 Answer

(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?