File Exchange

image thumbnail


version (17.7 KB) by Daniel Frisch
Quickly zoom & scroll through your signal. Apply digital filter and adapt it on the fly, via GUI


Updated 12 Nov 2018

From GitHub

View Version History

View license on GitHub

plotECG( X,Y ) — Plot Very Long, Multichannel Signals — Zoom & Scroll/Pan via Slider


Enables you to plot and zoom & scroll/pan through signals with millions of samples.
There is one slider for panning and one for zooming.
To move forward or backward by exactly one screen width,
use the scroll wheel or click on the slider trough.

If you launch plotECG() without any arguments,
one of two demos is shown.


Input Arguments

- X:
Vector of timesteps, or scalar sample rate. scalar or [N x 1] double

- Y:
Signal vector, or signal matrix where each column represents one signal. [N x m] double

- LineSpec:
LineSpec string, max. 4 characters, see Matlab plot() documentation.
string (optional, default: '.')
If you define a marker here, set 'AutoMarkers' to 'none' so it won't be overridden.

Important Key-Value Parameters:
(For more parameters, look into plotECG.)

- 'Filter'
Change parameters like cutoff frequencies via slider, or text edit, and see the results on the fly.
Use the builtin 'filter_FFT', or 'filter_bandpass_notch', or define an own
filter function and pass its name as string or function_handle (see plotECG help).

- 'mmPerSec'
Initial zoom in screen millimeters per second. scalar double (default: 50)
If you change the figure size in this mode, the axis XLim will change
such that mmPerSec stays the same.

- 'secPerScreenWidth'
Initial zoom setting in seconds that are displayed on screen at a time. scalar double
If you change the figure size in this mode, the signal scale will change too,
such that XLim stays the same.

- 'ShowAxisTicks'
Shows the axis ticks and labels and a grid. string, 'on' or 'off' (default: 'on')
You can also change axis properties on the returned handles: = 'Seconds';

- 'ShowInformationList'
Shows information about the location of the last clicks in the signal. function_handle or string
Specify one of 'none' (default), 'std_InformationList', 'ecg_InformationList', as string,
or define an own function like those with two inputs and cell output
and pass its name or function_handle.
Mouse clicks are captured only if no interactive mode (pan, zoom etc.) is active in the figure.

- 'AutoStackSignals'
Cell array of strings with signal names. Length must be equal to number of columns of Y, or 0.
(default: {}) Stacks the signals vertically, so for example a multipolar ECG can be shown.
Example: {'I','II','III', 'aVR','aVL','aVF', 'V1','V2','V3','V4','V5','V6'}

- 'SecondXAxisFunction'
Function handle that maps from the provided X values to a different x axis scale
that will be displayed above the plotted signal. function_handle or string (default: 'none')
Example: @(x)x/60^2, shows the time also in hours.

- 'SecondXAxisLabel'
Label of second x axis. Example: 'Time in h'. string (default: '')

- 'YLimMode'
'dynamic': dynamic y axis limits according to minimum and maximum of currently visible signal
'fixed' : fixed y axis limits according to minimum and maximum of entire signal.
(default: 'dynamic') In 'fixed' mode, you shouldn't apply filters that change
the signal's mean much because YLim won't be updated.
You can change the fixed interval afterwards using the returned axes handle: = [-10,10];

- 'Parent'
Parent figure. (default: new figure is created)
Use delete(findall(hs.panel)) or close the figure to delete the old plot and its signals.
The 'HandleVisibility' of the figure created by default is set to 'Callback' to prevent you from
plotting into it accidentially from the command line.
To close the created figures from the command line, you have to use "close all hidden"
instead of "close all".


Output Arguments
- h:
Returns the chart line objects as a vector. Use h to modify a chart line after it is created.

- hs:
Returns a struct with handles to some more GUI objects for later modifiaction

You can set Name-Value parameters on the returned chart line handles:
set(h, 'LineWidth',3) etc.

Furthermore, you might want to change the X/YLabel: = 'Seconds'; or: xlabel(,'Seconds')



X = 0:0.001:100-0.001;

Y = sin(2*pi*0.1*X) + sin(2*pi*X) + .1*sin(2*pi*50*X);

[h,hs] = plotECG(X,Y);

[h,hs] = plotECG(1000,Y, 'Filter','filter_FFT');


Cite As

Daniel Frisch (2021). daniel-frisch-kit/plot-ecg (, GitHub. Retrieved .

@software{plotECG, author = {Daniel Frisch}, title = {{plotECG, Matlab Central}}, publisher = {{Matlab Central}}, organization = {{K}arlsruhe {I}nstitute of {T}echnology}, url = {}, version = {1.1}, year = {2015--2018}, }

Comments and Ratings (13)

Daniel Frisch

Hi Kevin, yes you can do it like this:

t = linspace(0,10,100)'; % (L x 1)
s = sin(2*pi*t); % (L x 1)
sMat = repmat(s,1,2); % (L x 2)
border = 50;
sMat(border+1:end,1) = NaN;
sMat(1:border-1,2) = NaN;
h = plotECG(t, sMat);
h(1).Color = 'red';
h(2).Color = 'green';

kevin sayed

would it be possible to color portions of the trace? ie, coloring the times where x is a between a range of certain values? Thank you!

Daniel Frisch

@Robin, you could either plot all ECG signals into one plot by passing the array as 2D matrix Y, each column representing one signal. With the additional Name-Value-Pair 'AutoStackSignals',{'I','II','III'}, you give the signals a name, and they are plotted in a nearly non-overlapping way. So you don't even need three axes, plotECG handles all for you. An other possibility would be to use the 'ScrollCallback' option and provide a function handle which is called every time after a zoom/scroll action. With this, you could control other axes.

Basílio Gonçalves

Thanks a lot Daniel!! It made my life 100000000000000x easier :D


Robin Berglund

Hi Daniel! Thank you for this wonderful tool.

I am creating a GUI with GUIDE for comparing different ECG signals. Therefore I want to plot 3 different signals in three different axes in one figure. I'm trying to use plotECG to make it so that one scroll and zoom bar controlls all the different plots, for exampel by using linkaxes and linkprobs. This has not worked however. Do you have any sugggestion on how to use plotECG for several subplots?


davide Cavone

Is it compatible with R2014a version?


Daniel Frisch

Hello Pranav, you can always quickly compare your result to the unfiltered signal by unchecking the checkbox. To plot both at the same time, replicate your signal columns with repmat before passing it to plotECG, and write your filter so that it only filters the second half of columns.


Super tool for adapting filters! Is it possible to plot both input signal and filtered signal? Which variables hold these data?


This is a superb extension I have been waiting for in a long time!
Added imho essential tags: scrollbar, panning

Daniel Frisch

Thank you for the feedback. plotECG comes with its own data cursor. Pass the name-value pair
'ShowInformationList','ecg_InformationList' or 'ShowInformationList','std_InformationList'
as additional parameters.
ecg_InformationList and std_InformationList are two local functions defined within the file plotECG.m. If you have other needs, just write your own function emg_InformationList.m similar to these. It must return a cell array of strings which will be shown in the list on the right side.

Kasper Pedersen

Great tool, exactly what I needed to show long series of EMG signals.
The only problem I have so far is getting the data cursors to work.
- Any suggestions would be most welcome.

Harald Hentschke

Nice! Looks sleek, works flawlessly (as far as I can tell from a few runs). Very helpful browsing tool for time series.

MATLAB Release Compatibility
Created with R2016a
Compatible with any release
Platform Compatibility
Windows macOS Linux

Inspired by: Plot (Big)

Community Treasure Hunt

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

Start Hunting!