So I have this signal sampled at 300 Hz to begin with and this is the frequency domain: Original Signal Time Domain

Original Signal Freq Domain

I apply a second order butterworth filter using scipy with a cutoff frequency of 12.6 Hz and this is the resultant signal in time and frequency domains:

sos = signal.butter(2, 12.6, 'low', fs=300, output='sos')
x_filt = signal.sosfiltfilt(sos, x)

Filtered Signal Time Domain Filtered Signal Freq Domain

My question is shouldn't those frequencies around 300 Hz be filtered out and appear as zero and why aren't they? Should I be using a higher order filter in order to filter out those higher frequencies?


1 Answer 1


You sampled your signal at 300Hz.

That means your range of valid frequencies (for a real-valued signal) is -150Hz to +150Hz.

When you take the FFT, as you have done, the top half of the spectrum is really from -150Hz to 0$^-$Hz (the bin just before 0 frequency).

Use numpy.fft.fftshift to center the 0 frequency bin in the middle of your plots.

  • $\begingroup$ Could you help me explain why there is still high frequency components in the filtered signal? $\endgroup$ Commented Jun 1, 2022 at 15:09
  • 1
    $\begingroup$ @MichaelPozzi There aren't. Rather, once the signal is sampled, the spectrum is repeated to infinity in both directions. Once it's sampled at 300Hz, you can only see -150Hz to +150Hz (and any aliases if the original unsampled signal had frequency components higher than 150Hz). $\endgroup$
    – Peter K.
    Commented Jun 1, 2022 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.