Doc mention cutoff frequency correction for signal.filtfilt
See original GitHub issueThe filtfilt function runs two filters to cancel the phase shift. Hence to compensate for the twice -3dB attenuation, one should define a higher cutoff frequency equal to f_c = f_wanted / 0.8 . See explanations in https://nbviewer.jupyter.org/github/demotu/BMC/blob/master/notebooks/DataFiltering.ipynb, Cell[8]
This should be mentioned in the doc and the examples changed appropriately for filtfilt and lfilter
Simple example:
import numpy as np
import scipy
import scipy.signal
import matplotlib.pyplot as plt
f0 = 0.1
N = 2
rip = 0.05
x = np.linspace(0,100, 1001)
y = np.random.randn(len(x))
cutoffs = [None, f0, f0, f0/0.8, f0*0.8]
lss = ["-", "--", ":", ":", ":"]
labels = ["raw", "single pass", "dp: no corr", "dp: good corr", "dp: bad corr"]
Y = np.vstack((y, ys, yf, yff, yfff))
fig,ax = plt.subplots(figsize=(16,12))
single_pass=True
for cutoff, label, ls in zip(cutoffs, labels, lss):
if cutoff is None:
yf = y
else:
b, a = scipy.signal.cheby1(N, rip, cutoff)
if single_pass:
yf = scipy.signal.lfilter(b, a, y)
single_pass = False
else:
yf = scipy.signal.filtfilt(b, a, y)
ax.plot(x, yf, label=label, linestyle=ls, linewidth=2)
ax.set_xlabel("time")
ax.legend()
ax.set_xlim(2,5)
ax.set_ylim(-1.5,1.5)

The amplitude of the single pass lfilter (yellow) is comparable to the filtfilt with the corrected cutoff f0/0.8 (red).
On python3.7, Scipy 1.1
Issue Analytics
- State:
- Created 5 years ago
- Comments:11 (4 by maintainers)
Top Results From Across the Web
scipy.signal.filtfilt — SciPy v1.9.3 Manual
Now create a lowpass Butterworth filter with a cutoff of 0.125 times the Nyquist frequency, or 125 Hz, and apply it to x...
Read more >python - Apply butterworth filter (lowpass) to a signal
#Creation of the filter cutOff = 1000 # Cutoff frequency nyq = 0.5 * sf ... The .filtfilt method didn't work because I...
Read more >MATLAB filtfilt - Zero-phase digital filtering - MathWorks
This MATLAB function performs zero-phase digital filtering by processing the input data x in both the forward and reverse directions.
Read more >Background information on filtering — MNE 1.2.2 documentation
In other words, filtering can increase signal-to-noise ratio (SNR), ... bandwidth: 10.00 Hz (-6 dB cutoff frequency: 45.00 Hz) - Filter ...
Read more >How to filter noise with a low pass filter — Python - Medium
signal import butter,filtfilt# Filter requirements. T = 5.0 # Sample Period fs = 30.0 # sample rate, Hz cutoff = 2 # desired...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

@Xurotash So the CORRECT corrected cutoff frequency is:
f_corr = fs/pi * arctan( tan(pi*f_c/fs) / C)withC = (2**(1/n) - 1)**(1/4),nnumber of passes,fsthe sampling frequency andf_cthe wanted cutoff frequency. Tested withscipy.signal.butter(2, f_corr/(fs/2))it gives me the same result as rewritingbutterwith a correction factor. Whenf_c << fs/2, the correct correction is almost equal to the wrong correction (f_c/C), so it was not an error easy to spot!I dug some deeper into this cutoff correction, and realised that the correction factor should NOT be applied directly on the cutoff frequency, i.e. f_c_low = f_wanted / C is incorrect. I find this so interesting that i wrote an article on codeproject to highlight this issue. Multi-Pass Filter Cutoff Correction