axes title of all open figures
14 views (last 30 days)
Show older comments
Hello together,
having for example two open figures, where each figure has a plot in it with a title. I want an easy way without a loop, to get the titles of the plots. Sofar my idea is, to get all open figures (in the example this are two) by
openFigures = findobj('Type', 'figure');
now i have an array of to 2x1 matlab.ui.Figures. To get the Title of the first figure i can use:
title1 = openFigures(1).Children(2).Title.String
(I'm using the index 2 after Children because the index 1 is the legend.)
So my question is how to get both titles in one command like:
titles = openFigures(1:2).Children(2).Title.String
This Syntax does not work though.
Do you have any idea without using a loop?
Thank you for your help Rafael
0 Comments
Accepted Answer
Adam
on 31 May 2017
Edited: Adam
on 31 May 2017
It can be done, but sometimes you have to ask yourself why you specifically want to avoid a for loop because the alternative can often be a lot worse, especially in the case of Matlab where you cannot chain together parentheses and other forms of brackets such as
get( hTitles, 'String' ){:} % Invalid syntax
So you end up with lots of lines of code having to keep getting one level of results at a time and unpacking them from a cell array to a regular object array and on and on down the chain, and with the assumption mentioned below that axes are the only children of the figure, although you can filter out other children.
So this works...but is it better than a for loop? I would say not personally. Certainly you cannot do it in one command:
% Setup figures for testing
hFig(1) = figure;
imagesc( magic(20) );
title( 'magic20' )
hFig(2) = figure;
imagesc( magic(50) );
title( 'magic50' )
% Extract the title strings
ch = get( hFig, 'Children' );
hAxes = [ ch{:} ]; % Assumes axes are the only children
hTitles = get( hAxes, 'title' );
hTitles = [ hTitles{:} ];
titles = get( hTitles, 'String' );
0 Comments
More Answers (1)
Jan
on 31 May 2017
It will not work without a loop.
If you really need this, store the handles of the titles during the creation already. Then the access will be much more reliable than relying on the axes to be the 2nd child. If you store the title handles explicitely, the problem does not appear.
The was asked repeatedly in the forum, usually concerning sub-fields in structs. What do you expect as benefit in avoiding the loop?
6 Comments
Jan
on 9 Jun 2017
An object oriented approach helps here. You do not need to use OO commands, but only the idea of treating a figure as an object. It would be very complicated to keep a global list of all needed handles for a specific job. But if the handles are stored in a separate field of the "handles" struct inside a figure, it is enough to call a function with a set of figure handles and let it obtain the handles in each figure dynamically. Then the concerned handles are stored locally and you have only 1 location in your code, where changes must be applied.
This is implemented in Matlab already, see e.g. the list of "Children" for each object. But this is designed for other purposes and you cannot rely on the order of Children. Therefore openFigures(1).Children(2).Title is a really bad idea, because it will fail if you decide later (perhaps in some years, or your successor) to insert an additional element like a logo. Then it matters if the additional element is inserted on the top or bottom of the code, and if the wrong location is chosen, error messages will appear at a completely different location. Try to avoid such magic remote dependencies.
Better mark all concerned axes by a specific (unique!) ID:
specID = 'AutoTitleFeature_007';
figure;
axes('Tag', specID);
title('Axes 1');
figure;
axes('Tag', specID);
title('Axes 2');
function TitleList = GetTheTitles
specID = 'AutoTitleFeature_007';
openFigs = allchild(groot); % See PS below
TitleList = {};
for iFig = 1:numel(openFigures)
axesList = findobj(openFigs(iFig), 'flat', 'Type', 'axes', ...
'Tag', specID);
axesTitle = get(axesList, 'Title');
TitleList = cat(1, TitleList, axesTitle(:));
end
This looks more complicated at first, but it will be much easier, if you expand or change the code later.
But as said above: I'd prefer a method, which stores the handles o9f the concerned titles explicitely in the handles struct of each figure. Then it will not matter, if the axes are direct children of the figure or if you decide later on to create them in a uipanel.
PS. findobj('Type', 'figure') checks all graphic objects. If you have some GUIs with many axes, uipanels and some thousand line objects, this will take some time. findobj(allchild(groot), 'flat', 'Type', 'figure') is much faster, but currently groot can have figures as children only.
See Also
Categories
Find more on Interactive Control and Callbacks in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!