T.Justice
T.Justice

Reputation: 75

How to get and plot a signal envelope

I would like to know if there is a function envelope in Python to have the same result as this

picture

I have already tried an envelope function in Python but there is this result and it doesn't correspond with what I want.

result

Upvotes: 3

Views: 17650

Answers (2)

Shuo Yang
Shuo Yang

Reputation: 131

Sometimes I would use obspy.signal.filter.envelope(data_array); But you can only get the upper line in your given example. Obspy is a very useful package dealing with seismogram.

Upvotes: 1

Dennis Jaheruddin
Dennis Jaheruddin

Reputation: 21563

Though you don't mention exactly what function you use, it seems like you are using two different kinds of envelopes.

The way you call envelope in matlab, the relevant description is:

[yupper,ylower] = envelope(x) returns the upper and lower envelopes of the input sequence, x, as the magnitude of its analytic signal. The analytic signal of x is found using the discrete Fourier transform as implemented in hilbert. The function initially removes the mean of x and adds it back after computing the envelopes. If x is a matrix, then envelope operates independently over each column of x.

Based on this, I suppose you would be looking for a way to get the Hilber transform in python. An example of this can be found here:

 import numpy as np
 import matplotlib.pyplot as plt
 from scipy.signal import hilbert, chirp

 duration = 1.0
 fs = 400.0
 samples = int(fs*duration)
 t = np.arange(samples) / fs

 signal = chirp(t, 20.0, t[-1], 100.0)
 signal *= (1.0 + 0.5 * np.sin(2.0*np.pi*3.0*t) )

 analytic_signal = hilbert(signal)
 amplitude_envelope = np.abs(analytic_signal)
 instantaneous_phase = np.unwrap(np.angle(analytic_signal))
 instantaneous_frequency = np.diff(instantaneous_phase) / (2.0*np.pi) * fs

 fig = plt.figure()
 ax0 = fig.add_subplot(211)
 ax0.plot(t, signal, label='signal')
 ax0.plot(t, amplitude_envelope, label='envelope')
 ax0.set_xlabel("time in seconds")
 ax0.legend()
 ax1 = fig.add_subplot(212)
 ax1.plot(t[1:], instantaneous_frequency)
 ax1.set_xlabel("time in seconds")
 ax1.set_ylim(0.0, 120.0)

Resulting in:

enter image description here

Upvotes: 2

Related Questions