- Undocumented Matlab - https://undocumentedmatlab.com -

Draggable plot data-tips

Posted By Yair Altman On October 23, 2013 | 6 Comments

A couple of years ago, I was asked by a client to figure out a way to make Matlab plot data-tips movable. The problem was that he had a very crowded plot and Matlab’s standard data-tips are displayed immediately adjacent to the data, thereby overlapping the plot parts. Matlab’s standard data-tips enable dragging to a very limited extent (only to the 4 corners of the data-point), and in any case the displayed textbox remains directly attached to the data point.
So I developed a small utility for my client that solves this problem. I then forgot all about it until a few days ago when I came across it again. Yesterday I uploaded this draggableDataTips utility to the File Exchange, where you can download it [1].
draggableDataTips enables the user to interactively drag any newly-created data-tip, anywhere in the Matlab figure. A dashed line connects the dragged data-tip with the original data point. Simple, intuitive, and effective. At 300 lines, the draggableDataTips.m source code is compact and easy to follow, and you’re welcome to take a look and further customize this utility for your specific needs.

draggableDataTips utility in action [2]
draggableDataTips utility in action

Technical implementation

The implementation of draggableDataTips relies on undocumented aspects of the data-cursor object exposed via the datacursormode function. I have already shown how these can be used to customize and control data-tips programmatically [3] (rather than interactively). For draggableDataTips, we first get the cursor object’s meta-data classhandle (a schema.class object), then use it to find the meta-data for its hidden CurrentDataCursor property (a schema.prop object). There is also a more direct approach, using the findprop function.
Whichever alternative we choose, we finally use this object to set the property’s SetFunction meta-property. Quite straight-forward, I should say:

% Get the cursor-mode object
cursorObj = datacursormode(hFig);
% Alternative #1: the indirect route to the meta-property
ch = classhandle(cursorObj);
hPropIdx = strcmpi(get(ch.Properties,'Name'), 'CurrentDataCursor');
hProp = ch.Properties(hPropIdx);
% Alternative #2: the direct approach
hProp = findprop(cursorObj, 'CurrentDataCursor');
% Update the meta-property to use a custom function whenever new data-tips are created
hProp.SetFunction = @installNewMoveFcn;

This has the effect that all new data-tips that will be created from then on will call our custom installNewMoveFcn function when the data-tip object is created. This installNewMoveFcn function, in turn, simply replaces the data-tips standard default callback for mouse movement (which is used while dragging), to a new custom function textBoxUpdateFcn:

% Install a replacement callback function for datatip textbox mouse movement
function hDataTip = installNewMoveFcn(cursorObj, hDataTip)
    srcObjs = get(hDataTip.SelfListenerHandles,'SourceObject');
    for srcIdx = 1 : length(srcObjs)
        if strcmpi(srcObjs{srcIdx}.Name,'Orientation')
            hDataTip.SelfListenerHandles(srcIdx).Callback = @textBoxUpdateFcn;
            hDataTip.MarkerHandle.Marker = 'none';
            break;
        end
    end
end

The textBoxUpdateFcn function basically moves the datatip textbox to the new mouse location, without limiting its positions as Matlab’s standard default callback function did. A dashed connector line is then drawn to connect the center of the textbox with the data-point. It’s a bit long to include here, but interested readers are welcome to look at the code (lines #99 onward in draggableDataTips.m).
As can be seen from the screenshot above, standard and draggable data-tips can be used in the same plot. This is done by simply turning the draggability functionality on and off by draggableDataTips before creating a new data-tip (using either alt-click or programmatically [3]):

draggableDataTips on    % or: draggableDataTips('on')  or: draggableDataTips(true)
draggableDataTips off   % or: draggableDataTips('off') or: draggableDataTips(false)

Notes:

  1. The actual code of draggableDataTips naturally contains more sanity checks, exception handling etc. I have only presented the core code in the snippets above, but you should always include such extra checks in any real-life program.
  2. There is a minor bug that causes the connector line to be on top of the box rather than beneath it, but aside from this all works ok. For some reason, uistack did not work. If anyone has a fix for this bug, please let me know.
  3. Did you notice that Java was not mentioned anywhere above? Mode managers, such as the data-cursor mode, use pure-Matlab functionality.

HG2

Unfortunately, when I tested draggableDataTips on HG2 [4], Matlab’s upcoming new graphics engine, the utility failed. Data-cursors have undergone a significant reengineering in HG2 (about time!), causing multiple properties and methods to change names and functionality. But this could be overcome (see lines #43-53 in draggableDataTips.m).
However, I could not overcome the apparent fact that unlike HG1 (or more specifically, schema objects, that HG1 uses for its data-tips functionality), in HG2 (or rather, MCOS class objects) we cannot override an object’s meta-properties, specifically its SetMethod (which is the MCOS equivalent of schema.prop‘s SetFunction meta-property).
So for the moment, draggableDataTips does not work on HG2. I hope to find a solution for this by the time HG2 launches. If anyone finds a fix for the problem, please let me know. If I ever find or receive a fix, I will update this post with the relevant technical details.
For the moment there is no rush, since HG2 is still relatively far away in the distant future, and draggableDataTips works splendidly in the current HG1.
Have you used plot data-tips in some nifty way? If so, please share your experience in a comment below.

Categories: Handle graphics, Hidden property, High risk of breaking in future versions, Stock Matlab function, Undocumented feature


6 Comments (Open | Close)

6 Comments To "Draggable plot data-tips"

#1 Comment By Werner On October 23, 2013 @ 20:40

You are amazing… as soon as I finish my master and hopefully start earning some money, I will gladly buy you some cups of coffee. xD

And yes, I had the same issue when using customized datatips with HG2 (I used your older post information on this topic available here).

#2 Comment By Ortmann On February 24, 2015 @ 07:13

Wow…it just works.

Thank you so much!

#3 Comment By Patricio On September 10, 2015 @ 13:10

worked like magic. Thanks a lot!

#4 Comment By Simon On September 23, 2015 @ 01:12

Hi Yair!

Thanks for this great piece of code! It works perfectly.

I have a question concerning the customization of the data-tips: I’d like to give the user the ability to define the line style and the marker at the data-point position. I know I can change it in the code directly. But I’d rather like to give both settings as additional inputs to draggableDataTips. The only thing is I don’t know where to store this information in order to access it in functions installNewMoveFcn and updateConnectorLine. Do you have a hint?

Thanks in advance!

Best regards, Simon

#5 Comment By SVee On August 5, 2016 @ 20:33

Hi,

Nice tricks.
Any chance it could work on HG2 by using the method described in [11] or am I wasting my time trying?

Cheers,

#6 Comment By Yair Altman On August 6, 2016 @ 20:40

@SVee – it’s definitely worth a shot, you’re not wasting your time. Let us all know if you discover anything useful.


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/draggable-plot-data-tips

URLs in this post:

[1] download it: http://www.mathworks.com/matlabcentral/fileexchange/44065-draggable-data-tips

[2] Image: http://undocumentedmatlab.com/images/draggableDataTips.png

[3] customize and control data-tips programmatically: http://undocumentedmatlab.com/blog/controlling-plot-data-tips/

[4] HG2: http://undocumentedmatlab.com/blog/hg2-update/

[5] Controlling plot data-tips : https://undocumentedmatlab.com/articles/controlling-plot-data-tips

[6] Accessing plot brushed data : https://undocumentedmatlab.com/articles/accessing-plot-brushed-data

[7] Undocumented scatter plot jitter : https://undocumentedmatlab.com/articles/undocumented-scatter-plot-jitter

[8] Plot LimInclude properties : https://undocumentedmatlab.com/articles/plot-liminclude-properties

[9] Plot markers transparency and color gradient : https://undocumentedmatlab.com/articles/plot-markers-transparency-and-color-gradient

[10] Undocumented plot marker types : https://undocumentedmatlab.com/articles/undocumented-plot-marker-types

[11] : https://undocumentedmatlab.com/blog/accessing-private-object-properties

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.