I am new to signal processing and I want to implement an LPF using SciPy. In order to do so, I used the following python code from: here
The code itself looks like:
import numpy as np
from scipy.signal import butter, lfilter, freqz
import matplotlib.pyplot as plt
def butter_lowpass(cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
def butter_lowpass_filter(data, cutoff, fs, order=5):
b, a = butter_lowpass(cutoff, fs, order=order)
y = lfilter(b, a, data)
return y
# Setting standard filter requirements.
order = 6
fs = 30.0
cutoff = 3.667
b, a = butter_lowpass(cutoff, fs, order)
# Plotting the frequency response.
w, h = freqz(b, a, worN=8000)
plt.subplot(2, 1, 1)
plt.plot(0.5*fs*w/np.pi, np.abs(h), 'b')
plt.plot(cutoff, 0.5*np.sqrt(2), 'ko')
plt.axvline(cutoff, color='k')
plt.xlim(0, 0.5*fs)
plt.title("Lowpass Filter Frequency Response")
plt.xlabel('Frequency [Hz]')
plt.grid()
# Creating the data for filteration
T = 5.0 # value taken in seconds
n = int(T * fs) # indicates total samples
t = np.linspace(0, T, n, endpoint=False)
data = np.sin(1.2*2*np.pi*t) + 1.5*np.cos(9*2*np.pi*t) + 0.5*np.sin(12.0*2*np.pi*t)
# Filtering and plotting
y = butter_lowpass_filter(data, cutoff, fs, order)
plt.subplot(2, 1, 2)
plt.plot(t, data, 'b-', label='data')
plt.plot(t, y, 'g-', linewidth=2, label='filtered data')
plt.xlabel('Time [sec]')
plt.grid()
plt.legend()
plt.subplots_adjust(hspace=0.35)
plt.show()
As it can be seen in the figure, a 6th order LPF with fs = 30 Hz and a cutoff frequency of 3.667 Hz filters the signal nicely:
In my application, the signal has a sampling frequency of 1.5 MSPS (1.5 MHz, the ADC has to sample with such a high rate, I cannot change that) and I want to use an LPF with 100 Hz cutoff frequency to filter my incoming signal.
When I change the corresponding two parameters in this test code just to see what would happen with the test data:
fs = 1.5e6
cutoff = 100
then the result becomes completely uninterpretable:
Testing it by an empirical way, I could find out that the problem is somewhat related to the cutoff/fs ratio. When it gets too small, strange things happen. However, I do not understand why this is happening. Also, any advice related to how to implement a 100 Hz cutoff LPF on a signal with a high sampling frequency would be appreciated.
Thank you very much in advance!