Why is there a difference in magnitude response between scipy.filtfilt and scipy.lfilter?

1.4k views Asked by At

I was trying to filter a signal using the scipy module of python and I wanted to see which of lfilter or filtfilt is better. I tried to compare them and I got the following plot from my mwe

import numpy as np
import scipy.signal as sp
import matplotlib.pyplot as plt

frequency = 100.             #cycles/second
samplingFrequency = 2500.         #samples/second
amplitude = 16384   
signalDuration = 2.3
cycles = frequency*signalDuration

time = np.linspace(0, 2*np.pi*cycles, signalDuration*samplingFrequency)
freq = np.fft.fftfreq(time.shape[-1])
inputSine = amplitude*np.sin(time)
#Create IIR Filter
b, a = sp.iirfilter(1, 0.3, btype = 'lowpass')

#Apply filter to input
filteredSignal = sp.filtfilt(b, a, inputSine)
filteredSignalInFrequency = np.fft.fft(filteredSignal)
filteredSignal2 = sp.lfilter(b, a, inputSine)
filteredSignal2InFrequency = np.fft.fft(filteredSignal2)

plt.close('all')
plt.figure(1)
plt.title('Sine filtered with filtfilt')
plt.plot(freq, abs(filteredSignalInFrequency))
plt.subplot(122)
plt.title('Sine filtered with lfilter')
plt.plot(freq, abs(filteredSignal2InFrequency))

print max(abs(filteredSignalInFrequency))
print max(abs(filteredSignal2InFrequency))
plt.show()

Can someone please explain why there is a difference in the magnitude response?

Thanks a lot for your help.lfilt vs filtfilt

1

There are 1 answers

0
SleuthEye On BEST ANSWER

Looking at your graphs shows that the signal filtered with filtfilt has a peak magnitude of 4.43x107 in the frequency domain compared with 4.56x107 for the signal filtered with lfilter. In other words, the signal filtered with filtfilt has an peak magnitude that is 0.97 that when filtering with

Now we should note that scipy.signal.filtfilt applies the filter twice, whereas scipy.signal.lfilter only applies it once. As a result, input signals get attenuated twice as much. To confirm this we can have a look at the frequency response of the Butterworth filter you have used (obtained with iirfilter) around the input tone's normalized frequency of 100/2500 = 0.04:

enter image description here

which indeed shows an that the application of this filter does causes an attenuation of ~0.97 at a frequency of 0.04.