Linear envelope of an EMG signal

Hello,
I am trying to plot an RMS envelope over a single EMG signal from a respiratory muscle. The data was collected at 2000Hz. Prior to envelope calculation and plot i bandpassed the signal using a 6th order butterworth filter from 30-300Hz. For my envelope calculation, i have the following code:
[up,lo]=envelope(RUT,100,'rms');
I wish to plot the upper envelope on top of the original signal and so my code is:
plot(Time,RUT,Time,up,'lineWidth',0.1)
I am expecting the upper envelope to be higer up to the top of the signal and am not sure why it isn't. In all of the examples i've seen for Matlab, the upper envelope hugs the sigal more close to the top. So i am just curious if i did something wrong and what i can do to correct it.
Thank you in advance! My reference figure screenshot is attached below

 Accepted Answer

hello Ines
there is no bug here , the plot is correct vs what matlab is supposed to do
when you select 'rms' option, you cannot have the envelope on the 'top' of signal , because the rms of a signal is always less than the spikes amplitude.
here the demo code (from the matlab help) :
load('train');
envelope(y,150,'rms');
will give you this result (lo and up envelopes are displayed here)
now if you use 'peak' option, this is maybe what you wanted :
envelope(y,150,'peak');

14 Comments

Thank you, that makes sense. I am a little bit confused what a linear envelope tells me about a signal and so i think that was my main problem. It makes sense that RMS envelope would be lower than signal.
A quick follow up question, how would i go about putting the RMS value for this time duration on top of the plot? I am trying to google it but having a hard time finding a solution. Thank you
hello again
I am not sure what you mean by "on top" ?
does the built in matlab envelope function not give you the required output ?
FYI, this is a simple code for moving RMS
% dummy data
n=100;
x=linspace(0,2*pi,n);
data = abs(sin(x) + 0.25*randn(size(x)));
buffer = 10; % buffer size in samples
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r*');
legend('raw','rms');
Thank you, i've attached a picture for clarification. Basically want to know how to put number values on top of the plot like in the picture.
like this :
n=100;
x=linspace(0,2*pi,n);
data = 50*abs(sin(x) + 0.25*randn(size(x)));
buffer = 10; % buffer size in samples
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
Can this be done with a stacked plot? I tried modifying your code with a stacked plot and it seemed it wouldn't allow it. If true, i will need to switch to another plot type.
hello again
try this
t = tiledlayout(2,2,'TileSpacing','Compact');
n=100;
x=linspace(0,2*pi,n);
buffer = 10; % buffer size in samples
% Tile 1
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
% Tile 2
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
% Tile 3
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
% Tile 4
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
Thank you so very much. Is there a way to get rid of the axes of the top graphs and just keep the bottom one, as they are all the same? This way it would look more like a stacked graph. I am attaching a picture of what i have with stacked graph code. All that i am missing now is adding those numbers.
simply add this line where you don't want the X labels
set(gca, 'XTickLabel', [])
here the full code and resuts , the 2 upper plots are modified by not the bottom ones
t = tiledlayout(2,2,'TileSpacing','Compact');
n=100;
x=linspace(0,2*pi,n);
buffer = 10; % buffer size in samples
% Tile 1
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
set(gca, 'XTickLabel', [])
% Tile 2
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
set(gca, 'XTickLabel', [])
% Tile 3
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
% Tile 4
nexttile
data = 50*abs(sin(x) + 0.25*randn(size(x)));
a_rms=sqrt(movmean(data.^2,buffer)); % moving RMS
plot(x,data,x,a_rms,'r');
legend('raw','rms');
% put some text above rms curve
pos_x = mean(x); % centered on x axis
pos_y = 0.5*(max(a_rms) + max(data)); % half way between max of rms curve and max of raw data
text(pos_x,pos_y,num2str(round(max(a_rms))),'FontSize',25);
Thank you for your help!
as always, my pleasure !

Sign in to comment.

More Answers (0)

Products

Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!