MATLAB filter not attenuating enough Currently, I'm working on removing 50 Hz power line interference from an ECG signal. Before trying out notch filters, I decided to try out a simple lowpass filter with a cutoff less than 50 Hz. Here's the MATLAB code I used to make the filter:

Fs=500; %Sampling rate in Hz
Ast = 120; %Stopband attenuation
Ap = 1; %Passband ripple
Fp = 30; %Passband end
Fst = 45; %Stopband beginning
Hd=fdesign.lowpass('Fp,Fst,Ap,Ast',Fp,Fst,Ap,Ast,Fs);
d=design(Hd,'butter'); % Design a butterworth filter with the given characteristics
fvtool(d);


The magnitude response of the filter is:


As you can see, the filter has around a 180 dB attenuation at 50 Hz and even more at higher frequencies. 

Now, I run this filter on my data. Here's the original data, in the time and frequency domain:



And here's the data after applying the filter:



As you can see, the attenuation at 50 Hz is nowhere near the 180 dB that the filter advertised. For a better look, here's the plot of the magnitude response computed by taking the ratio of the FFTs of the signal before and after filtering:



Clearly, the attenuation is nowhere near the level it is supposed to be at. Is this the way it's supposed to be or am I doing something wrong in the implementation? 

Thanks in advance for all the help!

Edit : Here's an enlarged view of a single beat of the ECG after applying the filter. Note the 50Hz noise right after the tall peak.
(Disclaimer: I don't have a Matlab license for trying your example.)

First, your ECG signal is quite short, and you don't seem to be applying any windowing before the FFT (which is equivalent to applying a rectangular window). So your final spectrum will be the circular convolution of your signal with the window transform, and hence the tails above 40Hz.

Second, you are designing for hundreds of dB attenuation. This yields filters of very high order, which are very sensitive to numerical precision errors during calculations. In real life you think in tens of dB, not hundreds.

In general, the best approach for cleaning ECG signals is:


Notch filter at 50 Hz (a band-pass of order 6 to 8 should suffice).
Low-pass filter with cutoff around 100 Hz (notice where you stop having ECG harmonics and start having only acquisition noise).


Edit for the downvoter: The filtered signal is OK, but using FFT without care gives a misleading result. At least you should apply a smooth window function to the signal (in this case, the already filtered signal) in order to get a more faithful spectrum representation. Try with a Hamming window: plot(abs(fft(y .* hamming(length(y))))), where y is the filtered signal.