Skip to content

Instantly share code, notes, and snippets.

@junzis
Last active December 6, 2022 08:16
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save junzis/e06eca03747fc194e322 to your computer and use it in GitHub Desktop.
Save junzis/e06eca03747fc194e322 to your computer and use it in GitHub Desktop.
Python Lowpass Filter
# 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()
@davidmnielsen
Copy link

davidmnielsen commented Feb 12, 2019

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.

plt.subplot(2, 1, 2)
plt.plot(data, 'b-', label='data')
plt.plot(y, 'g-', linewidth=2, label='filtered data')
y2=y[5:-1]
plt.plot(y2, 'r-', linewidth=2, label='5 points to the left')
plt.xlabel('Time [sec]')
plt.grid()
plt.legend(fontsize='small')

Then, I just copied and pasted your code, with this modification, and ran it to generate the figure:

image

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

@BigRex
Copy link

BigRex commented Mar 31, 2019

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

filtfilt

filtfiltplot

@Danielaaron1994
Copy link

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

@coroner4817
Copy link

@Warnnaphorn
Copy link

Thank you this is good lesson for me

@syedeesa1999
Copy link

how can i find cutoff frequency if my frequency is 44100 and i am import a complex data from csv file

@JARodMot
Copy link

JARodMot commented Jul 1, 2021

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

@nayanagg
Copy link

Hi,

How can i apply this filter on real time accelerometer values?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment