File Exchange

image thumbnail

dualcursor

version 1.9.0.0 (11.3 KB) by Michelle Hirsch
Add dual vertical cursors to a plot.

11 Downloads

Updated 03 Mar 2016

GitHub view license on GitHub

Editor's Note: This file was selected as MATLAB Central Pick of the Week

Dual cursors are useful for picking relative measurements off of a plot; for instance - calculate the period of a time series, or the relative amplitude of two frequencies. A picture's worth a thousand words, so take a peek.
Key Features:
- Basic syntax: dualcursor on / dualcursor off
- Extended syntax supports a high level of control
- Works with live data streams
- Works in GUIDE guis
- Includes delta calculations (x2-x2, y2-y1)
- Export selected region to a new figure or to the workspace

Comments and Ratings (66)

Thank you Michelle for the prompt feedback. Works like a charm!
As you already mentioned in the comments of your code. Same would apply to marker_color accordingly.
Again many thanks!

Thanks for the feedback, Thomas. I just pushed up an update that (I think!) addresses this issue.

Great work! Thank you!
One thing I discovered, which does not work for me, is the deltalabelpos after automatic repositioning of the cursors due to a zoom action. The position is set to default values. Is there a possiblity to store the values which I set?

@exploder123: I'm glad you've found dualcursor helpful. There's no direct way to move the cursors programmatically. Depending on what you'd like to do, it might work OK to just call dualcursor again anytime you want to move the cursors. The performance isn't great, but it's something. As a simple test, I tried the following, working from the first example in the dualcursor help:

for x = [200:1:300]
dualcursor([x 2*x])
drawnow
end

There might be ways to expose direct programmatic control, but it would likely be very invasive to the code (and the code is quite messy).

Thank you very much for this amazing tool Michelle. I have encountered a problem while trying to move your cursors programmatically. What is the proper way to move them using the command line or programmatically in a script?
Thank you again.

Dear Michelle,
I would like to thank you for your service !

Angelo Marchisella

@AnnaBananaza - I'm not sure exactly what behavior you want. If you are looking for the ability to put one cursor on one axes and the other on a different axes, this is not supported (and couldn't be added without a lot of effort). If you are looking to link two pairs of cursors on two different axes, you could try piecing something together with linkprop but this would also require a good bit of surgery.

Sorry I can't add these enhancements for you - I wrote this code many years ago, and the approach I took makes enhancements very difficult.

Great function ! Been using it for a while now. I was wondering if you had any idea to help me. I have too "axes" on wich I want to put my dualcursors. I'd like to move my cursor at value x on my axes2 when I move my cursor at value x on axes 1.
If you have any idea, I'd be pleased !
Thanks a lot !:)

Paul

Mr. Zhu

It works well, but lack of display mutiple data value simultaneously.

prash

What if I have two lines on same matlab figure window and if I use your code - it only shows values for one line (one set of data). Can cursor displays the data for two lines (data set)

jackup

Hi. Thanks for your work. Now I get a subplot with 5 axes in 1 gui panel. The X axil tickts are the same for all 5 axes and I want to use dual cursor to choose x range. How can I extend the cursor line to be vertical length of 5 axes instead of only length of one axes height. Thank you!

@Chantal - Sorry it's not working for you. I updated the code for R2014b to address this issue, so you seem to be running an older version of the file.

The current version of the file on GitHub looks correct - the line you mentioned (a bit farther down the file) is commented out. If for some reason you can't see this updated file, just comment out the line that errors, and replace with:

lineh = lineh(1);

(Current version on github: https://github.com/michellehirsch/MATLAB-Dual-Cursors/blob/master/dualcursor.m)

This files does no longer run since I updated to Matlab 8.4 that came with a new Graphics system. I suspect the problem may come from Graphics handles being now objects rather than numeric values.

The error I get is as follows:

Undefined function 'min' for input arguments of type 'matlab.graphics.chart.primitive.Line'.

Error in dualcursor (line 275)
lineh = min(lineh);

Any insight or comment appreciated. Thanks!

@Khlood -

The whole point of this submission is to take relative readings between two cursors. If you'd like just one cursor, I'd recommend using the built in datatip functionality. It draws as a point instead of a line, but otherwise is similar in terms of reading values from a chart.

More info:
http://www.mathworks.com/help/matlab/creating_plots/data-cursor-displaying-data-values-interactively.html

Hello! Awesome implementation. I've been trying to turn on only one cursor but could't. Would you please help?

@Jose -

My best guess is that you have HandleVisibility turned off. dualcursor requires HandleVisibility to either be 'on' (as you would typically have when just scripting) or 'callback' (the default setting for UIs built with GUIDE). This is a limitation from how I implemented dualcursor, and is noted at the end of the help.

Try setting the HandleVisibility to 'callback' to see if this works. If f is your figure, just add

f.HandleVisibility = 'callback'

before the call to dualcursor.

Hi,

dualcursor is not working properly in my GUI:

1- Data is loaded from file with pushbutton callback
2- Then dualcursor is called.

I see both cursors with the data tips, but cannot move them by holding left mouse button.

Any hint on what is going on?

Jose

Rafael -

You need to turn off zoom mode in order to be able to move the cursors. Turning zoom on disables the custom interactions I programmed to enable moving the cursors.

You should be able to zoom into a region of interest, turn off zoom mode, then move the cursors.

Great Tool.
But after I zoomed in or out im not able anymore, to move the Cursors with the mouse.
Am I doing anything wrong?

Artem - very nice refinement. I have updated the submission to include this change.

Michelle,

Thanks for your reply and giving me a hint where the problem was. I worked with serial date numbers where the absolute values are much higher order of magnitude than the interval.

So the line:

xLimits = xlim(axh).*[1.02 .98];

in the repositionCursors function gave me totally wrong cursor positions. I changed it to:

xLimits = xlim(axh) + diff(xlim(axh))*[.02 -.02];

Where the smaller interval is based on the old interval, rather than on the absolute values of the edges. Now your feature of snapping cursor turned out to be very useful in my application, please do not change it.

Thanks again for a quick response,
Artem

Artem - That was supposed to be a feature that the cursor would snap back onto screen if it ended up off of the screen for some reason! I'm not exactly sure why I added it, but I definitely put it there on purpose :).

Sorry that this doesn't work for you - I certainly can understand that there are use cases where you'd want them to stay still. Maybe this is what everybody would want, but I'm not sure. I'll leave the code as it is for now, but if I hear from others that the behavior feels wrong I'm happy to change it.

In the meantime, you should be able to get the behavior you'd like by simply commenting out one line:

Line 787, the last statement in the repositionCursors function.

Here's what you will see:
% Put cursors in new positions
dualcursor(xCursors)

Add a comment at line 787 so it looks like
% Put cursors in new positions
% dualcursor(xCursors)

Let me know if this works for you.

Michelle,

I am using your dualcursor on R2014b (8.4.0.150421). What I found running the example from the dualcursor code, that if the cursors go off screen when zooming in or panning, they appear at wrong places after zooming out. Could you please fix this bug for me?

Thanks,
Artem

Tjitske - could you provide more specific information about what issues you are encountering? I last updated this to work with R2014b, and verified that it also appears to work with R2015a.

Hi Michelle,

Have you updated yet to Matlab 2015? I am experiencing problems using your function in this version of Matlab.

Thanks,
Tjitske

@Rilin:

Dualcursor is designed to work in individual lines in plots. The pair of cursors can take differential measurements in two locations on a single line only, not across multiple lines. It’s not working for you since your plot contains multiple lines (one created every time through the for loop).

I can’t recommend a strong alternative since it’s not clear to me from this example what you are trying to achieve with the way you have put multiple lines side-by-side. Depending on what you are trying to do, one possibility would be to concatenate all of the data into a single vector that you plot once, e.g.

t1 = 0:.1:10;
t2 = [];
y = [];
figure;

for i =0:5
t = i*10+t1;
t2 = [t2 t];
y = [y sin(2*pi*t)];
end

plot(t2,y);

dualcursor

Rilin

Hello, thanks for your job. I have try dualcursor.m by following code. But why the dualcursors can only moving in a rang just like range [0 10],range [10,20]
and etc.? It cannot cover the whole range [0 60] in this example.
t1 = 0:.1:10
figure;

for i =0:5
t2 = i*10+t1;
y = sin(2*pi*t2);
plot(t2,y);
hold on

end
dualcursor

Rilin

Hello, thanks for your job. I have try dualcursor.m by following code. But why the dualcursors can only moving in a rang just like range [0 10],range [10,20]
and etc.? It can cover the whole range [0 60] in this example.
t1 = 0:.1:10
figure;

for i =0:5
t2 = i*10+t1;
y = sin(2*pi*t2);
plot(t2,y);
hold on

end
dualcursor

@Douglas Anderson - I updated the code several months ago to work with R2014b. Have you downloaded the latest version? If so, please let me know what problems you are encountering.

Hello again!

With 2014b, there are some changes, and this code is having a lot of problems!

Any thoughts? Have you tried it now?

Rajeev Yadav

Wonderful... I was told about this post by Yair Altman the MATLAB veteran. I guess, the title messed it up in search ...

Nice work, keep it up.

Thank you for this function. I have been using it for a while. It is very good for windowing datasets, but that means you need to move the left datalabel out of the way (to the left) every time you use it. How do you set up the position of the datalabel for this application?

Also, can the Del_x and Del_y be simply eliminated, if not needed?

Thanks! Great work. (five stars)

I sent Mayank a version that supports this. If it goes well for him, I will post this updated version to the File Exchange.

Hi, I have about 17 or 18 plots on my GUI, and I'd like to remove the Del_x and Del_y text completely from all but 1 of the graph. Is there a way I can do this?

Mark - glad you like it. The code doesn't do horizontal lines. It could be modified to do so, but would likely be a fair bit of work since my code all assumed vertical lines.

If anybody is up for tackling I'd be happy to review proposed changes! Just email me.

This is a superb bit of code! Is it possible to do horizontal lines? That would be a great addition.

Matthew

Great tool and something similar should be part of MATLAB release.

Clicking on one of the copied lines in the new figure causes the failure.

This is a great tool. I did find one bug. When a user exports a region to a new figure it appears that the copied lines retain the 'selected' callback and the 'update' case fails due to no cursors on the new plot. I fixed this issue by modifing the first few lines of the 'update' case to be:

case 'update' %Update the cursor value
%Find the position of the existing cursors

cursors = findobj(axh,'Tag','Cursor');

if isempty(cursors)
dualcursor('on',[],[],[],axh);
return
end

Aditya

Great utility. I especially like how it is easy to right click and export the data.

Can this utility work with subplots and multiple lines within each subplot?

I run into this a lot when looking at test data obtained from DAQ hardware or even when looking at simulation results.

Have you considered incorporating this feature into a utility "ssc_explore" that Atul Suri from Mathworks created?

Aditya

Danielle

flexible, useful and generic. Absolutely amazing!

Preston

Would it be possible to expand callback functionality so that I could call it within a GUI whenever a cursor was moved?

fburton

Another vote for horizontal cursors.

I would like to thank you very much for this precious work. And I need to ask you how we can have an additionnaly horizontal dual cursor at the same time in the same plot
Sincerly your's

was gga do that my self but hey now i have it, thanks....

Thank you very much for this tool.

Is it possible to use this function on the horizontal axis ?
How do you think it should be difficult to add this ability to work in this case ? (Toogle mode vertical <--> horizontal)

Thank you again.

Roy

If you have multiple plots in one figure how do you select which one to select?
Really nice work.

Scott

Is it possible to have this function be "modal". For instance, if I wanted to use this function in a script that asks the user to set the lower and upper bounds of interest using dualcursor, how do I have my code stop and wait for the user to slide the vertical bars to the appropriate locations? I guess I need a button added to the plot so that the program waits until the limits are set before the user hits the "submit" button?

Hoi Wong

It seems like the program doesn't like figures being a child of uipanel:

??? Error using ==> set
There is no 'WindowButtonDownFcn' property in the 'uipanel' class.

Error in ==> dualcursor at 688
set(get(axh,'Parent'),'WindowButtonDownFcn','','WindowButtonUpFcn','')

Error in ==> dualcursor at 220
dualcursor('off',[],[],[],axh);

Error in ==> episodesPanel>slider_strip_Callback at 147
dualcursor([1 2], handles.panel.episodes.infoDisplay.axes_electrogram);

??? Error while evaluating uicontrol Callback

??? Error using ==> uicontextmenu
An object of class uicontextmenu, can not be a child of class uipanel.

Error in ==> dualcursor at 325
cmenu = uicontextmenu('Parent',get(axh,'Parent'));

Error in ==> episodesPanel>slider_strip_Callback at 147
dualcursor([1 2], handles.panel.episodes.infoDisplay.axes_electrogram);

nicolas billard

Excellent. Only 1 thing : When i compile a soft which calls dualcursor, it turns. But it canno't turn when i deploy the soft on target pc with matlab runtime. May be it's due to the crypto aspect of dualcursor which is again crypted by compilation. Is it a solution for it?

Tony Rainoldi

works great

Friedhelm Steinhilber

super!

Alex Boboc

excelent

Frank Hart

Not working for me. Shame, too, it could be so useful. I am using Matlab R11 (5.3), and
when I run the sample code and then call
dualcursor, I get this message back:

??? labelformatfcnh = @
|
Missing variable or function.

Syntax error in ==> C:\MATLAB_SR11\central\dualcursor.m
On line 147 ==> datalabelformatfcnh = @local_maketextstring;

Paul Koola

Cool Tool

thomas toth

my plot contains multiple data sets (used hold on). is there a way to set the cursors on two different graphs as data source?
eg. measure x/y difference between two points on two graphs (data) within the same plot. could maybe done using left/right click of mouse?

thomas toth

Very nice tool. Just what I needed for my data evaluation and extraction. Now it's as good as any simulation tool. Thanks for the tool.

Lisa Barker

Works great

Poh Chee Khun

This is what I am looking for!

Denis Gilbert

Neat program for interactive data exploration !

Updates

1.9.0.0

Moved code to GitHub. Removed mistaken attribution.

1.8.0.0

Enhanced support for zoom and pan. If you zoom or pan such that the cursors go off screen, they are automatically brought back in to the visible part of the axis. Good stuff.

1.6.0.0

Removed hype from description.

1.4.0.0

A few small feature requests.

1.3.0.0

A few small updates based on user feedback.

1.2.0.0

Small fix - now works when the axes is parented to a uipanel, too (I wrote the original back in the day when the figure was the only parent an axes ever had ...)

1.1.0.0

Enhancement - now works when axes is parented to uipanel.

1.0.0.0

Now works (hopefully) with plot types that create compound (hggroup) objects, such as stem. Thanks to Ralph Schmidt for pointing out the bug.

Small bug fix: Eliminated error when clicking on a line AFTER dualcursor has been turned off. Thanks to Hao Fang for catching this.

Small bug fix: Eliminated error when clicking on a line AFTER dualcursor has been turned off. Thanks to Hao Fang for catching this.

Small bug fix: Eliminated error when user clicked on the figure background.

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

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.


Learn About Live Editor