Reputation: 1025
I'm plotting 10 items.
To generate my plot I am creating 10 independent Line
objects in a for loop
x=1:10;y=1;10;names = num2str((1:10)');
for i = 1:10
my_plots(i) = plot(x(i),y(i),'.','Color',rgb(i,:),'MarkerSize',14);
end
legend(my_plots,names);
When I click on an item in the legend it toggles visibility of the corresponding line
(legHandle.ItemHitFcn = toggleLegendItem
).
function toggleLegendItem(src,evnt)
if strcmp(evnt.Peer.Visible,'on')
evnt.Peer.Visible = 'off';
else
evnt.Peer.Visible= 'on';
end
end
This works fine
I run into issues when some of my plots are actually the same category.
In this simple example, I could combine lines 1:5 into one object in a number of different ways, and pass the combined object to the legend as a single item in my_plots
.
All of my line
objects are distributed between several independent axes/subplots. Each axis
has to remain independent because I need to be able to freely rotate each subplot without disturbing the other plots.
I've been able to build a shared legend between axes (because same class items share the same color, I only need to link the first line
for each class), but I cannot figure out how to link multiple line
objects to a single legend item, so that I am able to properly all lines
across axes
on each legend item callback.
I have an array of lines.
{{Line Line Line}}
{{Line Line Line}}
{{Line Line Line}}
...
{{Line Line Line}}
Basically what I need to do is set multiple Peer
objects to a single legend item, but I am not sure if that is possible.
If someone has another solution that allows for combing multiple line
handles across axes that would be helpful too.
Upvotes: 2
Views: 175
Reputation: 1025
So looking at the legend()
function, I found that it's not possible to instantiate a legend with multiple Peer
objects per item. There may be a way to go back and add multiple references via some sort of "combined object" but I'm not sure if a "combined object" exists that can handle objects with different Parent
handles.
A quick fix to my problem (which was attributing a callback to the same item in multiple axes) was to use the shared properties within each class and across axes to get the handles for all items within each class. In this case I already assigned color to be distinctive between categories but a more objective property like Tag
could also be used.
function toggleLegendItem(src,evnt)
% Find all items in this category
obj = findobj(findall(gcf,'type','Scatter'),'CData',evnt.Peer.CData);
for oid = 1:length(obj)
if strcmp(obj(oid).Visible,'on')
obj(oid).Visible = 'off';
else
obj(oid).Visible= 'on';
end
end
end
The one nuisance that this solution leaves is that the legend is a child
of only one axis. If each category is not present in all axes, then the color for those missing categories may not show up. Luckily when you toggle each item's visibility the color appears and functions as normal. I would guess some other errors like this could occur.
Upvotes: 0