Matlab: How to obtain all the axes handles in a figure handle?
Asked Answered
C

4

43

How do I obtain all the axes handles in a figure handle?

Given the figure handle hf, I found that get(hf, 'children') may return the handles of all axes. However, the Matlab Help suggests that it may return more than just the axes handles:

Children of the figure. A vector containing the handles of all axes, user-interface objects displayed within the figure. You can change the order of the handles and thereby change the stacking of the objects on the display.

Is there any way to obtain only the axes handle in the figure handle? Or how do I know if the handle returned by get(hf, 'children') is an axe handle?

Thanks!

Cowcatcher answered 14/10, 2010 at 23:21 Comment(0)
S
46

Use FINDALL:

allAxesInFigure = findall(figureHandle,'type','axes');

If you want to get all axes handles anywhere in Matlab, you could do the following:

allAxes = findall(0,'type','axes');

EDIT

To answer the second part of your question: You can test for whether a list of handles are axes by getting the handles type property:

isAxes = strcmp('axes',get(listOfHandles,'type'));

isAxes will be true for every handle that is of type axes.

EDIT2

To select only axes handles that are not legends, you need to cleanup the list of axes (ax handles by removing all handles whose tag is not 'legend' or 'Colorbar':

axNoLegendsOrColorbars= ax(~ismember(get(ax,'Tag'),{'legend','Colobar'}))
Sparkle answered 14/10, 2010 at 23:32 Comment(6)
The simple findall won't work if your figure has legends/colorbars/etc.: those are the "user-interface objects" mentioned in the bit of the documentation you quoted, and f∈dallfindall will return handles to those as well. You'll need to combine f∈dallfindall with a strcmpstrcmp testing not the typetype but the class, via strcmp(class(hand≤(potentialhand≤)))strcmp(class(handle(potential handle)))Sonyasoo
@AhmedFasih: thanks for the heads-up. To remove legends and colorbars, you can fortunately use the 'tag' property as well. Of course, if you want non-tagged axes only, you can simply do ax(strcmp('',get(ax,'Tag')).Sparkle
So in the end findall(figureHandle,'type','axes','tag','') is the shortest way.Norther
Just a short comment to get figureHandle: figureHandle= findobj('Type','figure');Rexford
@Diiiiii: findobj will only find figures with visible handles. This may or may not be good enough.Sparkle
@Jonas, your above answer is already good. In case someone is looking for the 'figureHandle' in your answer, (s)he can use the line in my comment. :)Rexford
H
3

Jonas' solution didn't work for me, because there were some handles referring to legends. Surprisingly, legends seem to be implemented as axes, at least in Matlab 2010a. Here is a solution if you only want the axes, not any legends or other stuff.

axesHandles = get(fig, 'Children');
classHandles = handle(axesHandles);
count = length(axesHandles);
isNotInstanceOfSubtype = false(1, count);
for i = 1:count
    isNotInstanceOfSubtype(i) = strcmp(class(classHandles(i)), 'axes') == 1;
end
axesHandles = axesHandles(isNotInstanceOfSubtype);

The script works by sorting out handles which reveal to be of a sub-type of type axes, for example scribe.legend.

A warning for those trying to improve the above code snippet: using something like

classHandles = cellfun(@(x) handle(x), axesHandles)

might not work as intended:

??? Error using ==> cellfun
scribe.legend type is not currently implemented.
Hogweed answered 27/8, 2013 at 10:5 Comment(1)
you can wrap the entire strcmp call inside cellfun/arrayfun (see my answer).Sonyasoo
G
3

"Jonas" and "tm1" have answers that work for some. However, as tm1 pointed the issue, there are several items inside type 'axes'.

To exactly refer to the legend or axes itself (there may exist other items), you need to differentiate them, using their characteristic properties.

In my example, I opened "property editor" and looked for differing properties for axes and legend (since they both belong to "type, axes"). I was trying to copy my axes and its legend:

copied_axes = findobj(temp_fig,'type','axes','Tag','');
copied_legend = findobj(temp_fig,'type','axes','Tag','legend');

Instead of 'Tag' property, I also could use an other property from the "Property Inspector". The thing is, they must differ. Most of their properties are the same.

Gummy answered 28/8, 2013 at 13:51 Comment(0)
S
2

The solution by @tm1 is excellent. Mine is a little less complicated (if you're ok with functional programming):

% initialize `fig` somehow, i.e., "fig=gcf()" for the current figure or
% "fig=get(0,'children')" for all open figures; can be vector or scalar.

ax = findall(fig, 'type', 'axes');
ax = ax(arrayfun(@(i) strcmp(class(handle(i)), 'axes'), ax));

ax will contain only plot axes. This works because the class of a legend or colorbar object is different from axes.

Edit @Jonas points out a potential improvement to filter the results of findall, because at least legends and colorbars seem to have non-empty Tag properties: replace the last line in the above code snippet with

ax = ax(strcmp('', get(ax, 'Tag')))

Both these techniques are kludgy and may break in the future (a comparison against ggplot2 or Bokeh might be interesting).

Sonyasoo answered 3/9, 2013 at 13:17 Comment(1)
mlint (the source code analyzer that the Matlab editor uses to put ugly-colored underlines in your code) stupidly says that I should use isa instead of strcmp(class(...), '...') but of course that doesn't work here because legend/colorbar objects are axes objects (axes is a parent class); we have to filter them out because the original findall axes objects returned them!Sonyasoo

© 2022 - 2024 — McMap. All rights reserved.