I'm trying to filter EEG trials from an array in which each trail has dimensions [8x125] = [number of channels x samples@250Hz], but the resulting signal looks static and wrong. Why is this happening? How can I improve my filtered signal quality? See below how the original signal and its PSD are and how the signal comes out of the filtering process:

Raw signal temporal and PSD graphs

Filtered signal temporal and PSD graphs


I'm first applying an IIR 60Hz notch filter, padding the signal (50 mirrored samples on each side), applying a bandpass FIR filter from 5 to 30 Hz, and trimming the signal back down, considering the introduced delay from the FIR filter:

from scipy.signal import lfilter, kaiserord, firwin, iirnotch, freqz

#Bandpass freq
low = 5 / NYQ
high = 30 / NYQ
b1, a1 = iirnotch(60, 9, SPS)
#Kaiser window method
width = 2/NYQ  #transition width
ripple_db = 11 #attenuation
N, beta = kaiserord(ripple_db, width)
b = firwin(N, [low, high], pass_zero = 'bandpass',  window=('kaiser', beta))
print('>>FIR Order: ', N)
delay = int(0.5 * (N-1)) # / SPS
print('>>Delay: ', delay)

win = 50
for x in range(data.shape[0]):
   #Notch filter
   filtsamples = lfilter(b1, a1, data[x, :, :], axis = 1)
   prefilt = np.hstack(( np.flip(filtsamples[:, 0:win], axis = 1), filtsamples[:, :], np.flip(filtsamples[:, -win:], axis = 1) ))
   posfilt = lfilter(b, [1.0], prefilt, axis = 1)
   flt_data[x,:,:] = posfilt[:, win+delay:-win]

Here are my frequency and phase responses for each filter:

Notch filter frequency and phase response FIR filter frequency and phase response


  1. When I plot the trials individually and plot the data before and after the IIR notch, I can see an instability is created by the filter on the first half (or more). Also, that creates a huge 60Hz spike (which is exactly what I'm trying to avoid LOL). My trials are pretty short, if I were to chop it off, almost no data would remain. Is there a way to avoid this?

Raw data vs. IIR notch filtered data

This is how the Notch filtered data looks by itself.

  • $\begingroup$ Not entirely related but a 60-Hz notch filter should be implemented using an IIR filter, not a FIR. $\endgroup$
    – Ben
    Jul 21 '21 at 17:40
  • 1
    $\begingroup$ @Ben It looks like it is IIR, hence the design call iirnotch. $\endgroup$
    – Peter K.
    Jul 21 '21 at 17:41
  • 1
    $\begingroup$ Welcome to SE.SP! It looks like an interesting problem. I suspect that the show you see in the bottom plots is the shape of the FIR filter impulse response. That leads me to think there's a "glitch" or "spike" in the intermediate filtered data in filtsamples. I'm wondering if the prefilt data is being transposed, so you're filtering across data sets rather than along them? $\endgroup$
    – Peter K.
    Jul 21 '21 at 17:45
  • $\begingroup$ @PeterK. you are right, the Notch filtered signal does look weird. When I plot it as is, it gives me this result and when I change the axis to 0 on lfilter, it gives me this result. Both have a prominent spike at 60Hz... but it feels that axis = 0 is not destructing the signal as much. What do you think? $\endgroup$
    – mgmussi
    Jul 21 '21 at 23:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.