Retrieve legend handles and text
256 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Praveen Choudhury
el 23 de Sept. de 2016
I want to retrieve legend handles and text of an already created figure.
I am getting the desired output by [~,~,plots,txt] = legend(___).
It works fine on my machine but it doesn't work in an another machine (plots and text return empty).
Also, MATLAB also doesn't recommend this because of graphics issues. So my understanding is that there is graphics problem in the other machine.
So is there another way to get legend handles and text?
3 comentarios
Walter Roberson
el 23 de Sept. de 2016
What is it that you need to do with the handles? And which MATLAB releases are involved?
dpb
el 24 de Sept. de 2016
As Geoff and Walter note, revisions are significant here altho I note that the same output syntax is supported from as early as R12 thru current. However, with R2014(or thereabouts) handle graphics changed drastically internally from HG to HG2 and if one plot was generated and saved as .fig file on one system and then displayed on another crossing that great divide it's not too surprising (albeit disappointing) that such low-level compatibility has been broken.
Any hope will depend on these issues and what it is, as Walter asks, you really need to do...likely there are coding changes that can be made to the second system to manage to retrieve the data, but it's possible I suppose that the gulf is just too wide...
Respuesta aceptada
Walter Roberson
el 24 de Sept. de 2016
Editada: Walter Roberson
el 24 de Sept. de 2016
You cannot use a call to legend() to return handles to an existing legend. legend() historically always created a new legend. There are now a couple of syntaxes legend('show'), legend('boxon'), legend('boxoff') that do not always create a new legend, but in the cases where the legend already exists, the
[a, b, c, d] = legend(....)
syntax returns b, c, d as empty (at least in current implementations.)
When you use the
[a, b, c, d] = legend(....)
syntax in R2014b or later, the legend gets built differently. It gets created as a legend object, but the ItemText property gets instantiated with the handles to the text objects, whereas otherwise the ItemText property is set empty. (There might be other changes that I overlooked.)
I have not yet found any way to obtain the text handles of an R2014b or later legend that was not created with the [a, b, c, d] = legend() syntax. If there is a way, it would involve fishing through the various listener and callback properties and using functions() to obtain the static workspaces that might contain references to the actual objects.
But if the question is not about restoring from a .fig and is instead just about doing something with the properties of a legend that you just created, then the [a, b, c, d] = legend() syntax is still supported for now, and the question becomes what you want to do with the handles, as the mechanism for whatever it is you are trying to do might have changed.
14 comentarios
Afiq Azaibi
el 8 de Oct. de 2024
Thanks for updating the comment to point towards the post. To provide you with a little bit more context, the IconColumnWidth property introduced in R2024b is a step towards giving users more control over the legend appearance. You're right that it doesn't yet offer the detailed level of customization for individual legend icons that you're describing. In efforts to squeeze in incremental enhancements based on user feedback, there have been several updates aimed at improving legend customization over recent releases including controlling the sort order of legend items with the Direction property (23b), setting background transparency with the BackgroundAlpha property (24a), and now the IconColumnWidth (24b). The need for more granular control over legend items is on our radar. Thanks again for your contribution and interest!
dpb
el 8 de Oct. de 2024
Editada: dpb
el 8 de Oct. de 2024
I grok; it's been a somewhat rough ride for users away from having access to the underlying axes object and its children's handles from bygone era through a period when it was quite opaque and finally a journey back towards transparency and enhancements...
For other reasons, I've stayed at R2021b so far so some of these things I've just come across here.
Más respuestas (2)
Peter Reinprecht
el 25 de Oct. de 2016
in R2014b or later you can extract the line and legend object separately from an already existing figure
Legend object
hLegend = findobj(gcf, 'Type', 'Legend');
%get text
hLegend.String
Line object
hLines = findobj(gcf, 'Type', 'Line');
2 comentarios
Walter Roberson
el 25 de Oct. de 2016
The line objects you get this way are not the line objects belonging to the legend. Even if you
findall(gcf, 'type', 'line')
you will not be able to find the sample line that is used for the legend.
Brandon Ballard
el 7 de Sept. de 2020
If you are looking for a way to adjust the length of the lines in an existing legend then I would suggest using the following commands.
hLegend = findobj(gcf, 'Type', 'Legend');
hLegend.ItemTokenSize = [x1,x2];
By default the values for x1 and x2 are 30 and 18 respectively, so reducing the numbers will result in a smaller line in the legend window. However, the line style will remain identical to the lines used in the plot.
This code is only an application of that found in the link below:
Captain Karnage
el 22 de Dic. de 2022
Editada: Captain Karnage
el 22 de Dic. de 2022
I'll admit that findobj is a quicker, easier way to find the legends, but in case you want a way that kind of shows you the structure and where the legend is at, this works in R2022b (don't know about previous versions):
legendclass = 'matlab.graphics.illustration.Legend';
%Get the currentfigure
thisFigure = gcf;
%Get figure children
theseChildren = thisFigure.Children; %Alternately, gcf().Children works if you don't need a handle to the figure object
numChildren = numel(theseChildren);
for child = 1:numChildren
thischild = theseChildren(child);
if ~isa( thischild, legendclass )
thisLegend = thischild;
end
end
If you might have multiple legends, you can make thisLegend a cell array and increment an index counter each time a legend is found.
The one advantage here is you can get handles to the various objects in the structure along the way if you need them for other operations.
0 comentarios
Ver también
Categorías
Más información sobre Environment and Settings en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!