-
-
Save junzis/e06eca03747fc194e322 to your computer and use it in GitHub Desktop.
# https://stackoverflow.com/questions/25191620/ | |
# creating-lowpass-filter-in-scipy-understanding-methods-and-units | |
import numpy as np | |
from scipy.signal import butter, lfilter, freqz | |
from matplotlib import 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 | |
# Filter requirements. | |
order = 6 | |
fs = 30.0 # sample rate, Hz | |
cutoff = 3.667 # desired cutoff frequency of the filter, Hz | |
# Get the filter coefficients so we can check its frequency response. | |
b, a = butter_lowpass(cutoff, fs, order) | |
# Plot 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() | |
# Demonstrate the use of the filter. | |
# First make some data to be filtered. | |
T = 5.0 # seconds | |
n = int(T * fs) # total number of samples | |
t = np.linspace(0, T, n, endpoint=False) | |
# "Noisy" data. We want to recover the 1.2 Hz signal from this. | |
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) | |
# Filter the data, and plot both the original and filtered signals. | |
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() |
If you use replace lfilter with filtfilt you'll stay in phase with the source. https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.filtfilt.html
Hi. Thanks for your great job. However, I had a silly question. What is the order in this function? can we set the order number randomly or there is a rule for finding this number? Thanks
@Danielaaron1994 Check equation (1 - 11) in this doc
http://www.ece.uah.edu/courses/ee426/Butterworth.pdf
Thank you this is good lesson for me
how can i find cutoff frequency if my frequency is 44100 and i am import a complex data from csv file
Good job man. I have a question . I have a time based data frame (%d/%m/%y %H:%M:%S) I would like to implement denoising using wavelet, Low pass or high pass filtering but I don't know the sampling frequency, how can I get it?. Thanks in advance
Hi,
How can i apply this filter on real time accelerometer values?
Hello Junzi Sun,
Thank you for such a nice script! However, it seems to me that the filtered it a bit tilted to the right, i.e. its peaks don't seem to coincide with the peaks in the raw time series. To illustrate my point, I just shifted your filtered data 5 points to the left and added to your plot, as the code below.
Then, I just copied and pasted your code, with this modification, and ran it to generate the figure:
It seems to me that the peaks in the red curve are coinciding a bit better in time with the raw data. Do you have any recommendations on how to fix this in a more elegant way?
Cheers,
David