File Exchange

image thumbnail

clickableLegend - Interactive highlighting of data in figures

version (213 KB) by Ameya Deoras
A legend with clickable strings that let you hide and show objects in a plot.


Updated 01 Sep 2016

View Version History

View License

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

**** UPDATE ****
ClickableLegend now also highlights entries when you click them in the figure/axes window. This function is also R2014b ready
clickableLegend is a wrapper around the LEGEND function that provides the added functionality to turn on and off (hide or show) a graphics object (line or patch) by clicking on its text label in the legend. Its usage is the same as the LEGEND function in MATLAB.

1. You can group multiple lines into a single legend entry and toggle their visibility with a single click.

2. The DisplayedLines parameter lets you specify which lines should be displayed initially. This is useful if you have a large number of lines but want to start out with only a few shown.

3. If you save the figure and re-load it, the toggling functionality is not automatically re-enabled. To restore it, simply call clickableLegend with no arguments.

4. To prevent the axis from automatically scaling every time a line is turned on and off, issue the command: axis manual

Example 1:
z = peaks(100);
grid on;
axis manual;
clickableLegend({'Line1','Line2','Line3','Line4','Line5'}, 'Location', 'NorthWest');

Example 2:
f = plot([1:10;1:2:20]','x'); hold on;
g = plot(0:.1:10,sin([0:.1:10;0:.2:20]'),'r-');
h = plot(11:20,rand(5,10)*5,'b:');
clickableLegend([f;g;h], {'Line1','Line2','Line3'},...
'groups', [1 1 2 2 3 3 3 3 3], 'displayedLines', [2 3]);

Cite As

Ameya Deoras (2021). clickableLegend - Interactive highlighting of data in figures (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (54)

Patryk Chaber

Jack Garcia

Is there anyway to see the coordinates of the particular data point when you click on it as well as highlighting the legend?

Chung-Lin Tseng

Nice work! But I've got an issue of out-of-range text color in function togglevisibility. It seems that the text color is reset to [0,0,0] when exiting the if statement. So it'll cause color range error in else statement ([0,0,0]*1.5 - 1). A minor adjustment will solve it anyway. Still a fantastic work, thank you.

bien le

Jack deGooyer


Really usefull and great function. Thank you very much. I only have the Problem that datacursormode seems to block the clickability features completely. Do you have any suggestions?


Great function! It looks like they finally incorporated your functionality into matlab as well with the "ItemHitFcn" property of the legends.

Delphine Prevost

I love your tool, thanks ! I am using R2014b and use it almost everyday. Nevertheless, I have an idea for a new feature and I have tried to change the code but it creates bug with zoom afterward (I think I may have forget to change varargout).
Actually, I would like a legend with less lines than the actual number of plot. For instance, I plot a solid line with data and two dot lines for intersection at a given x, and this, for 4 sets of data. In this example, I have 12 plots and want only 4 items in legend. I want one click to remove 3 plots. For this use, I have used a cell with plots handles : first line is solid line and other lines are the "sub-plots" (in my example, I would have a 3x4 cell). Does somebody think they can help me with the feature ? I can post my code if needed, I just don't know where... Thanks for helping and thanks again for this function !

Ali Aghaeifar

Excellent tools, but why can't set the text interpreter to none? like this: set(h, 'Interpreter', 'none'); it doesn't work.


a really good nice work!!



There is no need to use this in R2016a or newer anymore because this is easily doable with shipped features. There is even an example in the doc which does exactly what this submission does:

>>web(fullfile(docroot, 'matlab/creating_plots/create-callbacks-for-interacting-with-legend-items.html'))


The option to highlight a line is not working on MATLAB R2016a. Is there a compatibility problem with the function highlightObject(lTextObj, lMarkerObj, plotObj, plotOptions)? Does anyone have a Solution for this?

Darrell Patton

I'm also getting the color outside range error when running on version 2016B. No problem when using version 2015B.
I determined that the problem is that the call to "set(obj,...)" causes the color values of hObject to reset to [0 0 0]. That should never happen.
The original code retrieves the current Color values of hObject and then assigns new Color values, based on the previous Color values.
Hard-coding the color values gets around the immediate issue, but if there is any other place in the program that uses the assigned Color values of hObject, it will have problems.

Erik Hedberg

Really handy submission, thanks! It seems however that setting the Interpreter property of the legend object no longer has any effect. Also, when I move the legend by click and drag it generates a lot of warnings "Error updating legend". I'm using 2016b.


Sugar Rush


Alton Vaughan

William Cable

I was having the same problem as Royi Avital with the color being outside the [0,1] range. To get it to work with 2016a I modified the togglevisibility function within clickableLegend to the following:

function togglevisibility(hObject, obj)
if get(hObject, 'UserData') % It is on, turn it off
set(hObject, 'Color', [0.5 0.5 0.5],'FontAngle','italic', 'UserData', false);
set(obj, 'HitTest','on','visible','on','handlevisibility','on');
set(hObject, 'Color', [0 0 0],'FontAngle','normal', 'UserData', true);

Stefan Engbers

I also have the problem Royi Avital has. Is there a solution yet?

Renwen Lin

Same Problem: I have some issues with MATLAB R2016a. The color is outside the [0, 1] range.

at clickableLegend>togglevisibility (line 139)
set(hObject, 'Color', get(hObject, 'Color')*1.5 - 1, 'UserData', true);

Royi Avital

I have some issues with MATLAB R2016a. The color is outside the [0, 1] range.

Josef Laumer

Great submission! Found the same issue like Alexander Stepanov, not every object has the MarkerSize poperty. Something like:
"if isprop(plotObj(i),'MarkerSize')
set(plotObj(i), 'LineWidth', lw+2, 'MarkerSize', get(plotObj(i),'MarkerSize')+2);
set(plotObj(i), 'LineWidth', lw+2, 'FontWeight', 'bold');
is needed. Would be great if the script could be updated.

Alexander Stepanov

One small issue - selection does not work with scatter plots, as they do not have a MarkerSize property. The code should either check if the property exists before trying to get/set it, or use a pre-defined set of properties based on graphics object type. Some of the types have changed with HG2 - e.g. 'hggroup' seems to be replaced with 'scatter', so probably the former is easier).

Alexander Stepanov

And a small comment on setting data tip position in my code (lines 197-198). In 2015b the code works, but data tip for some reason is not shown where you expect it to be. The following code works, but it needs slight tweaks to be backwards compatible:

pt = get(axh, 'CurrentPoint'); % Get the location of the click
X = get(clickedPlotObj,'Xdata'); % Retrieve Xdata
Y = get(clickedPlotObj,'Ydata'); % Retrieve Ydata
axisUnits = get(axh, 'DataAspectRatio'); % Relative lenghts of data units along each axis
dist = ((X-pt(1,1))/axisUnits(1)).^2 + ((Y-pt(1,2))/axisUnits(2)).^2; % Distances to clicked point on (X,Y) plane
idx = find(dist == min(dist),1); % Index the click
cursor = get(hTag, 'Cursor'); % Specific to recent Matlab releases
cursor.DataIndex = idx;

Alexander Stepanov

One small issue I found with my code (link below) - apparently @ancestor doesn't return a cell even if you wrap the argument in a cell array, unlike @get function, so lines 115-116 need to be changed to:

parentAxes = ancestor(plothan, 'Axes');
if iscell(parentAxes)
parentAxes = [parentAxes{:}];

Alexander Stepanov

Thanks. Btw, I have modified the code to achieve everything I mentioned, specifically:
- Clicking on a plot shows a data tip. Clicking on it again simply moves the data tip, keeping line(s) selected.
- Clicking on empty space inside axes removes all selections.
- Moving selected items on top of UI stack (& reverting back once deselected)

If you have time, could you please take a look and consider updating your submission, so everyone could benefit from these features?

I tried to keep as much of the original code intact as possible, and I did not update any of the documentation. Tested in 2015b.

Adrian Cherry

Alexander - with respect to your "Finally" bit. You can use gridLegend and clickableLegend together and I do. The function gridLegend tests to see if you have clickableLegend installed, if you do then it will use it.

Alexander Stepanov

Very nice. Great that it is now possible to highlight a line by clicking on it.

Some ideas if you plan to improve it further. There are two features it still lacks to completely remove the need to use @interactivelegend (another FEX utility) alongside this one:
1. Deselecting all lines when clicking on an empty space inside axes (much more convenient than having to click again on each line).
2. Displaying a label (same as in the legend) next to the the point you clicked on. When there are too many lines, it doesn't make sense to display the legend at all, so simply highlighting a line doesn't tell you which one it is. Displaying a label when you select a line solves the problem. That's exactly what @interactivelegend does.

Finally, would be nice to have control over which legend function is used as a base - e.g. so we could use @gridLegend utility from FEX, together with clickableLegend.

Andrey Vasilyev

Egon Geerardyn

Hoi Wong

I just notice that if I disable a legend and the print (or do a print preview), the legend text will reset to black (instead of grey).

This will throw an error in this line "set(hObject, 'Color', get(hObject, 'Color')*1.5 - 1, 'UserData', true);" as the color is [0 0 0], [0 0 0]-1=[-1 -1 -1] (togglevisibility() lost track of the color state as it's externally modified by printing).

Any idea how to handle cases like this robustly? Right now I just put a floor function over it "max([0 0 0], get(hObject, 'Color')*1.5 - 1)" but it will take a few clicks to get it back to the right state.

Hoi Wong

It seems like in R2014b, I cannot just override the already generated legend by just calling clickableLegend() or clickableLegend(gca). Anybody has the same issue?

In my case, the legends are generated by gscatter(), so I don't have control over it.

Stephen Goldrick


Feature request: modify the code to work with any font color in the legend. When the legend font color is changed to a different color, for example blue ([0 0 1]), the function crashes when any legend entry is clicked. This is because the scaling of the font color results in a vector with values greater than 1.


1. This is a very useful function when presenting a figure containing many data series to an audience.
2. Unfortunately there's an error in the 2nd example given in the preamble to the code. Instead of "'groups', [1 1 2 2 3 3 3 3 3]" in the clickableLegend call (which causes an error), I believe the intended usage was "'groups', [1 2 3 3 3 3 3]"
3. The behavior I wanted was to toggle data series visibility by clicking the associated legend text. The posted callback routine toggles the HitTest and HandleVisibility properties of the series, but to get the desired behavior, I replaced the two "set(obj, ...)" lines with





Egon Geerardyn


Super awesome


Nice work!

Bernd Meister


very nice and easy to handle tool...I tried it on a bunch of old plots and it works just pick of the month!

Evgeny Pr



Lukas Lansky

Jeff Preston


this is good stuff! how abt you get cracking on something similar for colorbar - i already have a name for it clickable colorbar ;)

Hoi Wong

Great idea! You saved my butt for my project.


Funny when I first saw this I thought: "nice but I don't really need it". Then today I was plotting a bunch of data and was wishing I had someone to "turn off" some of the lines. Just what I needed! Thanks for the great post.

Martin Richard

Very good indeed. Congratulations!

Riccardo Meldolesi

Great functionality.

I learnt from the code too!

Well done

Thierry Dalon

Excellent. It does what it sells. Very well coded as well.
Maybe the name of the function is a bit long.... I've changed it to ilegend.

Thierry Dalon

This is a feature I've requested as enhancement to TheMathworks for the base legend function.
Thank you for implementing it. I will give it a try.

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

Community Treasure Hunt

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

Start Hunting!