Plot data tips are a great visualization aid for Matlab plots. They enable users to interactively click on a plot location and see a tool-tip that contains the clicked location’s coordinates. The displayed tooltip text is even customizable using documented properties of the datacursormode object.

A client has recently asked me to automatically display an attached data-tip to the last data point of a plotted time series of values. The idea was to immediately see what the latest value of the data series is.
Unfortunately, the official documentation clearly says that:
You place data tips only by clicking data objects on graphs. You cannot place them programmatically (by executing code to position a data cursor).
Well, this has never stopped us before, has it?
Creating new data tips
Under the hood, data tips use a data-cursor mode, which shares many similarities in behavior and programming code with the other plot modes (zoom, pan, data-brushing, etc.). At any one time, only a single such mode can be active in any figure window (this is a known limitation of the design). The code itself it actually quite complex and handles numerous edge-cases. Understanding it by simply reading the code (under %matlabroot%\toolbox\matlab\graphics\) is actually pretty difficult. A much easier way to understand the programming flow is to liberally distribute breakpoints (start in datacursormode.m) and interactively activate the functionality, then debug the code step-by-step.
Luckily, it turns out that the code to create a new data-tip is actually quite simple: first get the data-cursor mode object, then create a new data tip using the mode’s createDatatip() method, update some data-tip properties and finally update the data-tip’s position:
% First plot the data hLine = plot(xdata, ydata); % First get the figure's data-cursor mode, activate it, and set some of its properties cursorMode = datacursormode(gcf); set(cursorMode, 'enable','on', 'UpdateFcn',@setDataTipTxt); % Note: the optional @setDataTipTxt is used to customize the data-tip's content text % Note: the following code was adapted from %matlabroot%\toolbox\matlab\graphics\datacursormode.m % Create a new data tip hTarget = handle(hLine); hDatatip = cursorMode.createDatatip(hTarget); % Create a copy of the context menu for the datatip: set(hDatatip,'UIContextMenu',get(cursorMode,'UIContextMenu')); set(hDatatip,'HandleVisibility','off'); set(hDatatip,'Host',hTarget); set(hDatatip,'ViewStyle','datatip'); % Set the data-tip orientation to top-right rather than auto set(hDatatip,'OrientationMode','manual'); set(hDatatip,'Orientation','top-right'); % Update the datatip marker appearance set(hDatatip, 'MarkerSize',5, 'MarkerFaceColor','none', ... 'MarkerEdgeColor','k', 'Marker','o', 'HitTest','off'); % Move the datatip to the right-most data vertex point position = [xdata(end),ydata(end),1; xdata(end),ydata(end),-1]; update(hDatatip, position); |
Note: If you don’t like messing with the code, consider using Tim Farajian’s MakeDataTip utility, which basically does all this behind the scenes. It is much easier to use as a stand-alone utility, although it does not give you the flexiblility with all the data-tip properties as in the code above.
Updating an existing data tip
To modify the appearance of a data-tip, we first need to get access to the hDatatip
object that we created earlier, either programmatically, or interactively (or both). Since we can access pre-stored handles only of programmatically-created (not interactively-created) data-tips, we need to use a different method. There are actually two ways to do this:
The basic way is to search the relevant axes for objects that have Tag=’DataTipMarker’. For each data-tip, we will get two such handles: one for the marker (Type=’line’) and the other for the text box tooltip (Type=’text’). We can use these to update (for example) the marker size, color and style; and the text’s font, border and colors.
A better way is to access the graphics.datatip
object itself. This can be done using two hidden properties of the datacursormode object:
% Get the list of all data-tips in the current figure >> cursorMode = datacursormode(gcf) cursorMode = graphics.datacursormanager >> cursorMode.DataCursors ans = graphics.datatip: 2-by-1 >> cursorMode.CurrentDataCursor ans = graphics.datatip >> cursorMode.CurrentDataCursor.get Annotation: [1x1 hg.Annotation] DisplayName: '' HitTestArea: 'off' BeingDeleted: 'off' ButtonDownFcn: [] Children: [2x1 double] Clipping: 'on' CreateFcn: [] DeleteFcn: [] BusyAction: 'queue' HandleVisibility: 'off' HitTest: 'off' Interruptible: 'on' Parent: 492.005493164063 SelectionHighlight: 'on' Tag: '' Type: 'hggroup' UserData: [] Selected: 'off' FontAngle: 'normal' FontName: 'Helvetica' FontSize: 8 FontUnits: 'points' FontWeight: 'normal' EdgeColor: [0.8 0.8 0.8] BackgroundColor: [1 1 0.933333333333333] TextColor: [0 0 0] Marker: 'o' MarkerSize: 5 MarkerEdgeColor: 'k' MarkerFaceColor: 'none' MarkerEraseMode: 'normal' Draggable: 'on' String: {'Date: 01/09/11' 'Value: 573.24'} Visible: 'on' StringFcn: [] UpdateFcn: [] UIContextMenu: [1x1 uicontextmenu] Host: [1x1 graph2d.lineseries] Interpolate: 'off' |
We can see that the returned graphics.datatip
object includes properties of both the text-box and the marker, making it easy to modify. Moreover, we can use its aforementioned update method to move the datatip to a different plot position (see example in the code above). In addition, we can also use the self-explanatory getCursorInfo(), getaxes(), makeCurrent(), movetofront() methods, and a few others.
Cursor mode and data-tip properties
The graphics.datacursormanager
and the graphics.datatip
objects have several public properties that we can use:
>> cursorMode.get Enable: 'off' SnapToDataVertex: 'on' DisplayStyle: 'datatip' UpdateFcn: @setDataTipTxt Figure: [1x1 figure] >> cursorMode.CurrentDataCursor.get Annotation: [1x1 hg.Annotation] DisplayName: '' HitTestArea: 'off' ... % See the list above |
Both these objects have plenty of additional hidden properties. You can inspect them using my uiinspect utility. Here is a brief list for reference (R2011b):
graphics.datacursormanager
:
- CurrentDataCursor
- DataCursors
- Debug
- DefaultExportVarName
- DefaultPanelPosition
- EnableAxesStacking
- EnableZStacking
- ExternalListeners
- HiddenUpdateFcn
- NewDataCursorOnClick
- OriginalRenderer
- OriginalRendererMode
- PanelDatatipHandle
- PanelHandle
- PanelTextHandle
- UIContextMenu
- UIState
- ZStackMinimum
graphics.datatip
:
- ALimInclude
- ApplicationData
- Behavior
- CLimInclude
- DataCursorHandle
- DataManagerHandle
- Debug
- DoThrowStartDragEvent
- EmptyArgUpdateFcn
- EnableAxesStacking
- EnableZStacking
- EraseMode
- EventObject
- ExternalListenerHandles
- HelpTopicKey
- HostAxes
- HostListenerHandles
- IncludeRenderer
- Invalid
- IsDeserializing
- MarkerHandle
- MarkerHandleButtonDownFcn
- Orientation
- OrientationMode
- OrientationPropertyListener
- OriginalDoubleBufferState
- PixelBounds
- PointsOffset
- Position
- SelfListenerHandles
- Serializable
- TextBoxHandle
- TextBoxHandleButtonDownFcn
- Version
- ViewStyle
- XLimInclude
- YLimInclude
- ZLimInclude
- ZStackMinimum
- uistate
As can be seen, if we really want, we can always use the MarkerHandle or TextBoxHandle directly.
Deleting data tips
To delete a specific data-tip, simply call the cursor mode’s removeDataCursor() method; to delete all data-tips, call its removeAllDataCursors() method:
% Delete the current data-tip cursorMode.removeDataCursor(cursorMode.CurrentDataCursor) % Delete all data-tips cursorMode.removeAllDataCursors() |
Have you used plot data-tips in some nifty way? If so, please share your experience in a comment below.
p.s. – did you notice that Java was not mentioned anywhere above? Mode managers use pure-Matlab functionality.
I have used programmable datatips to pull various extrema and their time hacks off a telemetry stream during V&V of flight software. It is VERY useful. I did not know about the other properties you’ve shown above — very cool. Thanks!
Hi Isaac! I just arrived to this post ,and what a surprise, because I use all this tips for flight test software aswell (data processing of flight parameters)!! He he he we all arrive to the same places….True Story XD
Amazing work Mr. Altman by the way!!
Hi,
Thanks very much for this useful article!
I have a small problem I was hoping you can help me resolve. When I use your code above, the datatip is displayed in the right location on the curve, but instead of having the X and Y values, it contains a message that says “Error in datacursor datatip string function”. I tried updating the “String” field of hDatatip, but that doesn’t seem to help.
I would really appreciate any suggestions!
Thank you,
K
@K – you need to change the data-cursor object’s UpdateFcn property to a custom text-update function handle, as described here. See the top code snippet on this page for an example of setting the property, and look at the link in the previous sentence for an explanation of the actual callback function.
Also see this related article: http://undocumentedmatlab.com/blog/undocumented-cursorbar-object/
Thank you very much, Yair! 🙂
I have used this as a custom tooltip for a patch object. (Depending on position above the patch, a different tooltip needs to be displayed)
Just initialise the hDataTip hidden and without a cursor and set a timer for making it visible (and reset the timer in a windowbuttonmotionfcn so it displays after your mouse hovers for a certain amount of seconds)
To use this as a tooltip, you might need to additionally do the following to make sure your clicks arrive at the right object and not at the datacursor or textbox:
Great tip, thanks a lot! The following line doesn’t seem to work in Matlab r2011b, but removing it works just fine:
I used it to find and mark phase and gain margin on a Bode plot.
Hello,
How can I pass a third argument to @setDataTipTxt?
I have a graph with several plots, each of them comes from a different source file. I want the datatip to tell me (X,Y) plus the name of the source file. For that reason, I was willing to pass a third argument with the name of the source file. Am I on the right way?
great blog.
thank you.
@Felipe – you can do it like this:
@Yair, thanks for your answer.
I’d tried what you told me, but it seems there is a problem when appending sourceFilename to the output cell array of @setDataTipTxt. I’ve tried several ways but always get the same message: “Error in custom datatip string function”.
Do you have any idea why this is happening?
Thanks again.
It means that you have an error in your setDataTipTxt function. Put a breakpoint there (or a try-catch block) to see exactly where and why.
Hi Jair,
I believe my setDataTipTxt function is OK, I made it in the same way as it is explained in this blog:
http://blogs.mathworks.com/videos/2011/10/19/tutorial-how-to-make-a-custom-data-tip-in-matlab/
I even made the same experiment (changing ‘Y’ for ‘$’) and everything seems fine. The problem begins when I try to append sourceFilename to the cell array output of setDataTipTxt
Do you have any idea why this may be happening? do you know any other turnaround?
Thanks a lot for your help.
@Felipe – you probably forgot to declare the extra parameter(s) properly. See here.
Hello Yair,
I’m new to matlab so this is likely to be a very basic question but I haven’t been able to find an answer so far. Maybe you can help.
The question is: How can I make a datatip display full integer value?
My X values are in the range 0 to 1500000
When I make a datatip it displays:
X: 3.669e+05
Y: 17
I would like it to be:
X: 366915
Y: 17
Is that possible?
Any help will be appreciated.
Thanks
@Apn – of course it is possible. You just need to create a custom UpdateFcn for the figure’s datacursormode:
where
myDataTip
is defined as follows:More examples:
* http://blogs.mathworks.com/videos/2012/09/19/making-a-custom-data-tip/
* http://blogs.mathworks.com/videos/2011/02/25/creating-a-custom-data-cursor/
* http://blogs.mathworks.com/videos/2011/10/19/tutorial-how-to-make-a-custom-data-tip-in-matlab/
(looks like this is a favorite topic for Doug… 🙂 )
@Yair – Thanks, just what I was looking for.
BTW:
There is a small problem with the example, I think.
A ) is missing in line 3 of the function.
But besides that it worked perfectly.
Thanks again.
[…] HG handles for displaying a plot data-tip (a.k.a. data cursor). I have explained in the past how to programmatically control data-tips, but doing so relies on the figure datacursormode, which is figure-wide […]
Hi Yair,
First off, I’m fairly new to Matlab but I love your blog – its super informative and I’m looking forward to getting more practice so I can appreciate it more!
I was hoping you could help me with a minor predicament. I’m using the data cursor for its point selection property but would rather the textbox not be displayed at all. I’ve tried almost everything, including suppressing it in the updateFcn callback using:
but this doesn’t work, since it would appear the property just gets reset in a later callback. I’m running out of ideas and was hoping you would be able to point me in the right direction.
Thanks!
@Dani – try setting the
output_txt
to ” (empty), anddatapointhandle.CurrentDataCursor
‘s BackgroundColor and EdgeColor properties to ‘w’ (or rather, to your axes’ BackgroundColor)@Yair
Thanks for looking into it! Unfortunately I’ve tried the empty string and I either get the warning ‘Error in custom datatip string function’, or it defaults back to a previous allowable value. Switching the box to white also doesn’t solve the problem since its still displayed on top of the plot – unless I misunderstood your advice. Thanks anyways!
@Dani – an error means that you have some Matlab error in your callback function, and then Matlab automatically defaults back to the default. Anyway, if an empty string is not allowed, you can always try a sting containing a single space character. The data-tip box will then be so small that the obstruction of the plot data will probably be unnoticed.
What is the proper way to create a datatip in window (instead of datatip) mode programmatically?
I’ve tried this function based on your code and it works except I get tooltips instead of data in the window:
Hi, I just figured I’d report back, I think I figured it out (please excuse the ugly code, I’m sure this can be made much cleaner, but it seems to work). All off the functions called I simply stole verbatim from datacursormode.m and pasted into the same file as this function.
I’ve used your datatip “undocumented documentation” and it helped me a lot with enhancing the information extraction from graphics. However, the datatips have an unexpected behavior on mac users, which makes it bottom of the ylabel text, complicating their visualization. I’ve managed to solve this issue explicitly overriding the position of the ylabel to a z value lower than the datatip one, but now my ylabel will move around when I zoom or pan my axis. I over-read the ActionPostCallback function from the zoom and pan handles, to replace the position after there where a change on the axis, but this creates an effect like the one you explained here:
http://undocumentedmatlab.com/blog/setting-axes-tick-labels-format/
By chance, do you know any event listener that is linked to the axis label, or to movement on the axis, so that I can solve this issue without seeing my axis label flying around my figure until mouse is released? More details available here:
http://stackoverflow.com/questions/17584094/put-datatip-stack-on-top-of-axis-label-and-update-axes-label-after-a-change-was
Thank you very much, and congratulations for this site, it is very useful!
@Werner – you can set a property-change listener on the axis’s XLim / YLim properties. Note that this specific functionality requires a different syntax in the future HG2 compared to the current HG1.
Yair,
I massively abuse of the handle.listener syntax to listen to property changes of UDD objects. Could you give an example of what the equivalent syntax looks like in HG2 ?
Moreover, do you know if the same handle.listener syntax still works in HG2 to listen to java events ?
Thanks !
[…] object exposed via the datacursormode function. I have already shown how these can be used to customize and control data-tips programmatically (rather than interactively). For draggableDataTips, we first get the cursor object’s […]
The graphics.datacursormode object has an UpdateFcn handle. Opening graphics.datatip.updatestring.m reveals that the graphics.datatip object itself has an UpdateFcn. The latter is more useful because the cursorMode UpdateFcn is called as
whereas the datatip object’s UpdateFcn is called as
So, potentially you can have different datatips with different UpdateFcn in the same figure. This is useful for advanced visualization involving multiple datatips in the same figure.
Great article Yair, a nice insight into the workings of data tips. Is there any way you know in which HTML can be included in data tips?
I’m running R2011b & interested in being able to provide links with matlab: href to trigger some activity.
I’ve tried the simple way of just outputting HTML from the UpdateFcn (as below) but without any success
@Graham – data-tips are simply axes text objects, so they can be formatted with Tex/Latex but not HTML.
Hi Yair,
I used this excellent writeup to create custom tooltips for a bunch of figures. Everything mostly works, but the above method fails in one case, and I have no idea why.
Briefly: I create a single empty figure and set its WindowButtonDownFcn property to @myMagnifyFcn. I then plot nine subplots (arranged as 3×3) into that figure. The helper script myMagnifyFcn determines which of the subplots receives a mouse click, then creates a new figure and copies just that axes into it (using findobj, etc.). This much works just fine.
I then attempt to create the “custom tooltip” functionality for the latter (one-axes) figure as per your example, namely:
This is exactly the same code that I have working for other figures. But in this case, even though I can toggle the data cursor button in the latter figure just fine, @myToolTipFcn never seems to get called — I put a debug print statement at the top and it never executes.
I’m wondering if there is something scope-related that causes the above to fail. As I said, the datacursormode stuff works just fine for all the other figures I create in my parent script. Furthermore, I examined the contents of cursormodeMagnifiedFig in the debugger — it turns up as a graphics.datacursormanager object, just like the corresponding cursormodeFig does with all my “regular” figures, and the contents are identical in all cases — so I’m confident that the arguments to UpdateFcn (= myToolTipFcn) are getting passed correctly.
I’m stuck because I can’t figure out (no pun intended) how to debug what Matlab is doing — it simply doesn’t fire the helper function and fails silently. Can you suggest any good way to debug the datacursormode process?
Thanks very much in advance (for this post specifically and for the blog in general),
Jon
@Jon – your gcf probably points to another figure handle. Try using the actual figure handle rather than gcf – if it’s a hidden handle then gcf will not return it.
Hi Yair,
Thanks for the quick response. I had a hunch that might be an issue, but wrote “gcf” in my code snippet above for brevity. Since that apparently _does_ make a difference, I should clarify that the actual setup in myMagnifyFcn is
… and it is this setup that doesn’t work. I’m really baffled as to how else to debug this.
FWIW, I’m stuck using a R2006b on this project. Seems much more likely that it’s my fault and not Matlab’s, but any chance this could be an HG-related bug?
Jon
p.s. Sorry about the double post earlier, and thanks for cleaning it up.
Try adding a drawnow; pause(0.1); after the figure creation and before you retrieve datacursormode, maybe it will help. I no longer have access to R2006b (too old) so I can’t test. Good luck!
Tried that but no luck. Argh.
FWIW, checked that gcf, h_magnifiedFig, and get(gca,’Parent’) [where gca is the axes copied into the magnified figure] are all equal to one another — so the issue isn’t with operating on the wrong (or hidden) figure handle.
Anyway, I will try digging a bit further with the debugger and maybe ask over at the newsgroup to see if anyone else has an idea. In any case, I will report back if I ever get to the bottom of this.
Thanks again,
-Jon
I think I’ve found a solution. Following up here as promised, in the unlikely event someone else runs into this (obscure?) issue.
In my @myMagnifyFcn callback, the relevant part of the code to copy the clicked-upon axes and its contents to the new empty figure window is as follows:
(Note that legends and colorbars are handled separately later in the function, since I’ve found that COPYOBJ does not seem to handle them correctly, at least on R2006b.)
The problem is that COPYOBJ either also mis-copies the ‘hittest’ property of some (all?) objects, or else they are not inherited automatically from the parent figure. This causes subsequent mouse clicks into the new (“magnified”) figure to be ignored, so they fail to fire the callback.
So, after all that, the solution to this problem seems to be a one-liner(!) following the COPYOBJ statement:
and some small tweaks to the code that assembles the tooltip text (which are specific to my setup, so I’ll skip them here).
Hope this helps someone in the future. Thanks again, Yair, for doing all the heavy lifting.
-Jon
One more…
I have a callback function outputTxt = myCallback(obj, eventObj) to create customized datatips as described here, but I need to limit that behavior to only work for certain objects (specifically, plotted data points only, and not other lines showing mean, standard deviation, etc.).
I’m able to check which object is clicked selected with the data cursor by looking at the properties of clickedObj = get(eventObj, ‘target’). But even if I set outputTxt = {”}, I still get a (default) data tip. I would like to cleanly delete this.
The “Deleting data tips” section above shows how to do this from the parent script, but I’m wondering if it is possible to do this _from within the callback_. The variable obj is empty, while eventObj (whose class is graphics.datatipevent) has two properties, Target (a handle) and Position (a 2×1 matrix) — neither of which points to the datacursormode object used in the example. As a last resort, I tried executing this inside the callback:
… and that sort of works, except that sometimes it deletes not only the desired (errant) data tip but also other (valid) ones already created in the same figure, which should all be left alone.
Any suggestions would be most welcome.
Thanks,
-Jon
Thanks Dr.Yair Altman for your really nice tutorial.
I am writing a program with 4-context menus; one of them is related to datacursor mode, I can switch between any of them except datacursormode one, I CANNOT Switch it off, So pleae how to do it in some example demo?
Thanks in advance
@Mahmoud – I am not sure I understand your problem exactly. If you’d like me to look at your code, please contact me via email (the link is at the top left of every page here) for a short consultancy.
I create a plot and set the data cursor properties in a function using:
I then attempt to change the font to ‘FixedWidth’ (so my formatted strings all line up) by using:
However, when I use the data cursor, everything is as it should be except the font is still the default ‘Helvetica’. If I call this code from the command line it works fine. Any ideas what is wrong?
@Rick – this is possibly an internal Matlab bug. Try using an explicit font name (e.g. ‘Courier New’) or use HTML formatting in your string (e.g., ‘my data tip string here…’)
I have noticed that some properties change their enumeration values between HG1 and HG2. For example the
'Orientation'
field changes from'top-right'
to a simple'topright'
etc. Perhaps it is worth mentioning it both in the current article and in hg2-update.On another notice, in some cases using HG2 the data-tips are created (and changed programmatically) faster. They have also a much richer data-tip display (using TeX syntax and notation). It seems that MathWorks makes some really good job under the hood…
Do you know how to add two different markers on two ends of a line?
@xiaojidan – you can simply use separate plot() commands, each one for a different marker.
I’m plotting an image in MATLAB using imagesc and then selecting points with the datacursormode.
I’d like to any select point on the image not only the pixels itself.
That’s why I always used ‘SnapToDataVertex’, ‘off’ in MATLAB R2014a.
After switching to MATLAB R2014b. The cursor nethertheless snaps to the data vertex.
I can only select pixel (e.g. X=75 Y=122) but I have to be able to select points in the sub-pixel region (e.g. X=75.25 Y=122.78).
Has something changed in R2014b? How can I achieve the old behavior?
Thanks in advance!
@bash0r – this looks like a Matlab bug to me. I suggest that you contact support@mathworks.com to report it
I have contacted the MATLAB support:
“In R2014b, MATLAB has a new graphic handle system, so the image is visualized in a different way, which affect the behavior of setting ‘SnapToDataVertex’ ‘off’. If you are plotting lines, you can still have the same behavior.”
The support is looking for a workaround to achieve my task and has additionally contacted the development team.
I’ll keep you guys posted.
I’ve received an answer from the MATLAB support and they have sent a workaround for MATLAB R2014b to get the exact cursor location on an image.
Maybe someone is also in desperate need of this functionality 🙂
I just updated to R2014b and I’m having problems with code that just worked yesterday before the update. I used the top portion of code on this page to make a function createDataCursor(figureHandle,plotHandle,xcoord,ycoord). After the update, ‘NewDataCursorOnClick’, ‘ViewStyle’, and update pop up with errors that they don’t work for data tips:
The Matlab documentation says, “You place data tips only by clicking data objects on graphs. You cannot place them programmatically (by executing code to position a data cursor).” I don’t know if it always said that or if that’s updated language as of R2014a/b. The first two errors are not a big deal, but I don’t know what to do about “update” no longer working. How do I update the position of the data tip to a new location?
Sample of my function below:
If you read the article you’d see that the Matlab warning has always been there. R2014b introduced a major overhaul of the entire graphics system (a.k.a. HG2), and this functionality has changed with it. It can still be accessed programmatically, it’s just that the programmatic interface has changed. This is always a risk when using undocumented features such as the ones explained in this blog. You cannot expect them to remain unchanged forever…
You’d need to dig a bit to find out the required changes in 14b – I’m too busy working on other things now and do not expect to look into this in the near future. If you find anything useful, come back here and post it for the benefit of other readers.
Good luck!
In HG2, the data tip object has Cursor property, which itself has a Position property. Setting this property to a new location updates the position of the data tip, i.e.:
Note that unlike with the previous update() method, setting the value of hDatatip.Cursor.Position only triggers the UpdateFcn() callback if the value is not equal to the current position.
Hello,
I’m trying to copy an existing figure to a newly created figure.
say.. i’ve just created a figure with a few subplots and added a bunch of datacursors. call it “old_fig”.
this copies everything except for the datacursors.
Does anyone know how to copy the datacursors over also?
Cheers!!
Hi Yair
Many thanks for the excellent article.
I was wondering if in the datacursor mode, instead of showing the standard datatip, there is an efficient way to draw a vertical line that passes through the graph and intersects the y-value at/above/below the click position.
Many thanks,
MU
@MU – of course this is possible, but you would need to do this programmatically, by trapping the mouse-movement events in a callback. See an example here: http://undocumentedmatlab.com/blog/transparent-legend
I changed the font in my data tip to Courier New. This works great when the data tip display style is ‘Data Tip’…..but the appearance of the font reverts to Helvetica when the display style is ‘window’ even though
cursorMode.DisplayStyle
still shows Courier New.Any thoughts on why the appearance would change between the two display styles?
I change the font from within the data tip function:
Never mind……figured it out.
When you switch from the ‘Data Tip’ display style to the ‘window’ display style, the original data tip object still remains but ‘visible’ is turned ‘off’.
Then a panel is created to hold the same content that is in the data tip.
I was able to find the handle for that panel and set its font to ‘Courier New.’
Code is below:
Yair,
I’m sorry if this is a repeat question as I feel somebody probably has asked it before, but I’ve scoured this thread and still haven’t found the answer to my question. I’m using trisurf(tri,x,y,z,c) to plot a 3D color plot. The datatip function by default displays X Y Z using the Position property of of the event_obj. However, I looked through your list of the hidden properties of the event_obj but couldn’t find one that referred to the argument passed to the color input. I’d like to be able to edit the datatip function to show X,Y,Z,and Heat (which is what the color represents in my case).
Thanks,
Nick
@Nick – all you need to do is to set a custom UpdateFcn callback function for the
cursorMode
object (in my post it was@setDataTipTxt
). This callback function should have the simple following signature:within this callback function,
eventObj.Target
will be the handle of the surface object, andeventObj.Position
will be the data-tip’s X,Y,Z data coordinates. Use these coordinates (which correspond to a single point in the surface object’s XData,YData,ZData properties) to extract the corresponding C value from the surface object’s CData property (which has the same matrix size as ZData, thus enabling easy match). Then combine X,Y,Z,C into a string that you will set inoutputTxt
. That’s it. See the datacursormode documentation for details.@Yair, Worked beautifully – Thanks!
Hi,
I need to write the x axis difference between two or 4 datatips on the plot like legend.
Text function writes everytime as I zoom in.
Questions :
1) if marker one is the reference and if there is 4 markers, I need to calculate 3 distance w.r.t. marker one.
2) How to plot these mentioned 3 distances on the plot( by zooming into plot it will stay as legend )
I appreciated too much for your help.
WR
Hans
Hello,
Did MATLAB recently change the syntax to this? I am trying to get access to the current list of datacursors programatically, but nothing I have tried seems to work.
So not nearly as many properties are listed as above. Then, the next call to get the current data cursors does not work anymore
I am trying to make a GUI which gets the xy data from all plotted datacursors. I have not figured out how to do this programmatically unless I am creating the datatips programmatically and then storing them in my own cells. Currently, I have to have the user “export cursor data to workspace” by right clicking the datatip and doing it manually. This is rather clunky.
Any suggestions are appreciated – thanks!
I figured it out…actually found it elsewhere but then realized it is mentioned in this original post as well. You can still use
getcursorinfo(dcmObject)
to get a list of all data cursors.yes, this post was originally posted in 2011, more than 5 years ago – Matlab has changed a lot since then, including an entirely revised graphics system (HG2). The current data cursor object is similar, but not identical, to the one mentioned in the post. So if you just figure out how the property names have changed you could probably do everything now much as you could back in 2011. For example, the current data-cursor object can be gotten via
cursorMode.CurrentCursor
instead of usingCurrentDataCursor
.Dear Yair
I would like to make some of the lines on the plot “unaccessible” / “invisible” for the datacursor mode
(Thus, I want the possibility to place the data cursor only on part of the lines that appear on the plot).
How can I do that, please?
Thank You
Michael
@Michael –
Hey Dr. Altman,
This is a great tutorial though i am trying to adjust it to my script. I have a figure with 13 subplots in it that each have boxplot representation of the data that i am working with. I am trying to modify the data tip text for the outliers so that i can use the Observation row value that is displayed in the data tip. I want to introduce another value in the datatip that takes the value of Observation Row as displayed in the data tip and use it to display the subject number that is stored in a separate matrix that is generated before the boxplots are plotted. I am using Matlab R2013a and i am trying to adjust your code to my script and i am getting an error that reads:
for the following line of code:
I am still in work of adjusting this to my script, here are some adjustments that i have made so far:
Here is my update function
I am also linking my Matlab Answers post which has an image of the subplots that i am refering to.
I would greatly appreciate any help i can get.
https://www.mathworks.com/matlabcentral/answers/330463-custom-data-tips-for-boxplots
P.S. Sorry if the indenting looks poor, i already made sure that indenting wasn’t the problem!!
Hi,
Is it possible to maintain the hittest property of a figure after enabling datacursormode?
Thank you
To answer myself in case someone stumbles upon:
add this snippet inside your datacursor update function,
followed by setting any figure callbacks you want to survive while datacursor mode is enabled
@Yair, I am almost certain that I have read it in one of your answers somewhere but I have forgotten about it.
Hard to keep track of all the hacks:)
@Gep – I believe that you found it here: http://undocumentedmatlab.com/blog/enabling-user-callbacks-during-zoom-pan (October 2015)
ah yes.. i have stolen this hack years ago:)
Using MATLAB 2018b, I have been able to change the EdgeColor and TextColor of the datatip, but the BackgroundColor will not update properly. Specifically the BackgroundColor property of the datatip object changes to the correct RGB triplet but the actual Background color of the datatip does not change. Any Thoughts?
@Mike – you can modify the tip background via the TipHandle and/or BackgroundAlpha:
Hi, I’m working with MATLAB R2019a – update 4 (the latest one I think), and I would like to know if there are some updates on how these features work.
Actually some of the functionalities are still correct/working, like querying for the datacursormode (or manager) and set the update string function, but other (like querying for all the datacursor objects) seems broken. I also noticed that maybe the object itself is a bit different. Here are the outputs I’ve got at the prompt:
In particular, I would like to know if there is a way to change the default aspect of the markers for a given figure, since the workaround I’ve found is to change each property (marker shape, size, edge color, face color,…), then force an update (with pause), then change another property and so on.
This method has however few drawbacks:
-first, the middle step settings flash on the screen (and without the pause command between them, they are not accepted);
-second the changes are only temporary and I should update them every time the markers are drawn again, including during the resize of the figure/axes
I tried to have a look with the getundoc function, but I couldn’t really find anything useful.
Thanks,
Jacopo
@Jacopo – in R2019a the property is called PointDataCursors. Since it’s a
private
property of thedatacursoremode
, you cannot access it directly. Instead, usestruct(dcm).PointDataCursors
. I am not aware of a way to change the data-cursor defaults – perhaps there is a way, I just never bothered to look for one.Hi. I have a contour plot with multiple data sets plotted on it, i.e…
Generally with data cursor, I’d have to click around in the plot to get the data cursor to show each of the z1, z2, z3 data separately, along with its legend entry, hoping I click on the exact contour I want.
I would like to see if there’s a way to use myupdatefnc to show all 3 z data values at a particular x,y position in a single data cursor. Do you know if this is possible? Thank you!
Also to clarify, this is within a GUI, which allows users the ability to choose which of a set of, say, 10 types of data they want, as many as they want, to be plotted. So an automatic way of doing this, rather than passing in 3 specific data sets and pulling them out manually based on the current x,y would be helpful.
@Aselia/CW – In your updateFcn(~,eventData) function, you can fetch the clicked position via
eventData.Position
and based on this position you can compose your custom datatip text (which is returned as the output of updateFcn). Simply find a way to get the contours data accessible in your updateFcn (there are multiple ways to do this, all of them pretty standard/documented) and you’re basically done.I was able to get the contour data accessible within myupdatefnc, however I noticed that eventData.Position returns the absolute x,y position, whereas my contour z data might have a certain step size between data points such that the absolute x,y position doesn’t access the array correctly. Is there a way to do this without also pulling in my original x,y vectors, step size, etc and doing all the math myself? Doing the math and pulling the data in is fine…just wanted to avoid the extra bulk if possible.
My contribuition to create new datatip
Is it possible to add custom data tip for simulink blocks without using the description or Block Name or parameter names and values.To make my statement clear i want to add custom data tip without altering the blocks