I am trying to remove low frequencies from a signal and intuitively I chose the high-pass filter, more specifically - a Butterworth filter, Order 4 (because I am not sure how to choose properly the order and 4 seemed as a good choice) and cutoff frequency of 50 Hz. The problem is, that the filter removes the low frequencies, however, the peaks that were caused from those low frequencies are still to be seen.

I have read also about adaptive filtering, but according to the literature, I need a reference signal, which would be used as a desired signal. I tried implementing an adaptive RLS/LMS filter and as a reference signal, I processed my data with a low-pass filter - Butterworth, 4th Order, 50 Hz for the cutoff frequency. This method also did not get me far.

I have provided a a copy of my data, which is sampled at 1500 Hz. enter image description here

  • 1
    $\begingroup$ Can you please clarify what you mean by "remove low frequencies" for your signal? Are you trying to remove the "blips" that seem to appear roughly every 1 second in this signal? $\endgroup$
    – Atul Ingle
    Commented Aug 26, 2017 at 21:31
  • 4
    $\begingroup$ Your fundamental mistake is that eventhough those heartbeat peaks have a period which approximately gives a fundamental frequency of 35 Hz, the quasi periodic beat pattern do have many harmonics in higher frequencies as a matter of continuous Fouerier series analysis. You should either try a comb filter, or use a nonlinear and/or time varying filter (an example is an adaptive filter) to remove those peaks without degrading the original signal. $\endgroup$
    – Fat32
    Commented Aug 26, 2017 at 23:49
  • 1
    $\begingroup$ Rather than talking about removing unwanted signal, of you look at the spectrum of your unfiltered signal, can you point out where your signal of interest lies? $\endgroup$ Commented Aug 26, 2017 at 23:59
  • 1
    $\begingroup$ Or even more important: what is your signal of interest? This might be a case of xyproblem.info $\endgroup$ Commented Aug 27, 2017 at 0:00
  • 1
    $\begingroup$ "I am interested in … the error" That requires you to define the error between which and what! So, what error are you talking about? $\endgroup$ Commented Aug 27, 2017 at 9:45

1 Answer 1


You want to remove the heart beat signal and keep the "noise". We can solve this problem by using a denoising algorithm, and subtracting the denoised signal from the original signal.

Setting frequency cutoffs for a frequency domain filter can get tricky and turn into a game of whack-a-mole because there's "high frequency" components in the heartbeat blip (due to the sudden rise and fall) and also in the wiggly stuff between a heart beat's T wave and the next heart beat's P wave.

Loosely speaking, the requirements in this de-noising problem are as follows:

  • Remove the little wiggles
  • Maintain larger jumps that appear in a heart beat PQRST waveform

This sounds like a great place to apply $\ell_1$ denoising or total variation denoising. The idea is to approximate the given signal $y$ with a signal $x$ such that the derivative of $x$ is "sparse" i.e. it doesn't change too frequently, but when it changes, the change is large. The denoised estimate $\hat x$ is given by: $$ \hat x = \min_x ||y-x||_2^2 +\lambda\sum|x_i-x_{i-1}| $$

I used proxTV toolbox in Python to solve this optimization problem.

import scipy.io as sio
import numpy as np
import matplotlib.pyplot as plt
import prox_tv as ptv

mat_struct = sio.loadmat('Signal1.mat')
noisy_signal = mat_struct['x'].T[0]

filtered_signal = ptv.tv1_1d(noisy_signal, 50)

time_vec = np.linspace(0, len(noisy_signal)/1500., len(noisy_signal))


fig, ax = plt.subplots(3,1,sharex=True)

ax[0].set_title('noisy signal')

ax[1].set_title('filtered signal')

ax[2].plot(time_vec,noisy_signal - filtered_signal)
ax[2].set_xlabel('time (s)')


And here's the resulting plot: enter image description here

Of course, there's a different kind of whack-a-mole you'll have to play with this technique: the $\lambda$ parameter which I set to $50$ in the code.

  • $\begingroup$ Thanks! I will test it on my computer as well! However, I would like to ask what is the cause for the peaks on the places, where the QRS was? $\endgroup$
    – dsax7
    Commented Aug 28, 2017 at 0:47
  • $\begingroup$ The algorithm isn't perfect after all! You'll notice, by playing with the $\lambda$ parameter, you can get those peaks to go away, at the price of adding some extra wiggles in the filtered signal. Also note that the y axis labels on the bottom subplot are different, about 1/10th of those of the top two. $\endgroup$
    – Atul Ingle
    Commented Aug 28, 2017 at 2:05

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.