I used the scipy hilbert function to calculate the envelope of my signal. The problem is that the signal is complex, so it throws an error when I use Hilbert function. I tried to just use the real part of the signal, but the result doesn't look good as you can see in the following picture.

enter image description here

The code snippets I used:

# Calculate and plot the envelop of the interpolated data.
amplitude_envelope = abs(hilbert(x_long.real))

fig = plt.figure(figsize=(15, 5))                 # Open a graphical window
plt.plot(t_long,x_long.squeeze(),'g+-',label='interpolated signal')           # Plot the data x vs time t. 
# Each original (un-interpolated) point is contained in the new series.
# To illustrate this, we mark the original data points using green symbols
plt.plot(t,x_noisy.squeeze(),'k+')           # Plot the data x vs time t.

plt.plot(t_long, amplitude_envelope.squeeze(), 'm-', label='envelope')

plt.xlabel('Time')       # add a label to the x axis
plt.title('Interpolated data (green) and envelope (magenta).' 
          'Uninterpolated data points (black)')               # add a title


using only amplitude_envelope = abs(x_long) gave the following result: enter image description here

  • $\begingroup$ Could you please add the definition of the envelope of a complex signal to your question? $\endgroup$
    – MBaz
    Sep 28, 2021 at 21:40
  • $\begingroup$ I am not sure about the definition tbh. The points in my signal are in complex form (x +iy) and I need to find the envelope of this signal. $\endgroup$
    – Rim Sleimi
    Sep 28, 2021 at 22:19
  • 1
    $\begingroup$ If the signal is already complex, then there is possibly no need to find its Hilbert transform. What does amplitude_envelope = abs(x_long) look like? $\endgroup$
    – Peter K.
    Sep 28, 2021 at 23:09
  • $\begingroup$ I added the result of that to the post. $\endgroup$
    – Rim Sleimi
    Sep 28, 2021 at 23:20
  • 1
    $\begingroup$ Thanks. So, next question: what are you expecting to see? Why do you want to look at the envelope? $\endgroup$
    – Peter K.
    Sep 29, 2021 at 0:44

1 Answer 1


Instead of using the Hilbert function. I tried the following:

  1. Find the location of peaks of (x_long).
  2. Find the location of troughs of (x_long).
  3. Get the interpolated (u_p) values of the upper envelope using the peaks and a spline (cubic) function.
  4. Get the interpolated (l_p) values of the lower envelope using the troughs and a spline (cubic) function.
  5. Evaluate (u_p) over the domain of (x_long) to get the interpolated values of the upper envelope. (Let's call them (upper envelope)). Evaluate (l_p) over the domain of (x_long) to get the interpolated values of the lower envelope. (Let's call them (lower envelope)).

Basically, a sequence of three steps (Find location, fit model, evaluate model) but applied twice, once for the upper part of the envelope and one for the lower. And this is the code snippets for that:

      def Get_envelope(self):
        Calculates the envelop of the interpolated data.

        x_long = self.Inverse_Fourrier_transform()
        peaks, _ = find_peaks(x_long.squeeze(), height=0) # find the peaks (above 0) in the interpolated data
        troughs, _ = find_peaks(-x_long.squeeze())        # find the troughts in the interpolated data

        #Fit suitable models to the data. Here I am using cubic splines.
        u_p = interp1d(peaks, x_long.squeeze()[peaks], kind = 'cubic',bounds_error = False, fill_value=0.0)
        l_p = interp1d(troughs, x_long.squeeze()[troughs],  kind = 'cubic',bounds_error = False, fill_value=0.0)
        Upper_envelope = [u_p(i) for i in range(x_long.shape[1])]
        Lower_envelope = [l_p(i) for i in range(x_long.shape[1])]

        return peaks, troughs, Upper_envelope, Lower_envelope

x_long is just a zero-padded complex signal in the time domain.


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