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
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!