6

The following stackoverflow qestion:

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

identifies how to get handles to all of the axes from a figure in Matlab. However, this list will also contain handles to legends, at least in R2008a, which appear to also be axes. How can I tell (programatically) the legends from the real plot axes in a vector of axes handles?

Community
  • 1
  • 1
crobar
  • 2,810
  • 4
  • 28
  • 46

3 Answers3

12

From linkaxes, the code you want is:

ax = findobj(gcf,'type','axes','-not','Tag','legend','-not','Tag','Colorbar');

This will return the handles of all the data axes in the current figure.

Nzbuu
  • 5,241
  • 1
  • 29
  • 51
  • But what if someone malicious changed the tags of the axes? – Andrey Rubshtein Jan 31 '12 at 00:12
  • @Jonas, I respectfully disagree. If you write the code yourself, just keep the handles. If you adapt to 3rd party code then anything that can go wrong, will go wrong. – Andrey Rubshtein Jan 31 '12 at 07:46
  • I wish to use the code to set all the colour limits in a figure to the same range, without having to get all the handles to each subplot in advance. So in this case the expediency of this solution trumps the risk that the tags have been changed (and also pointed out that Colorbars are also really axes). In this way I can either take in a figure handle, or take in a list of axes handles and have it work both ways. Thanks for all the answers. – crobar Jan 31 '12 at 09:54
  • 1
    @Andrey: Normally, I'd agree with you. However, in this case, setting the axes tag to `'legend'` also breaks TMW code. This is where I usually draw the line between accommodating other people and telling them that they should do things differently. – Jonas Jan 31 '12 at 13:24
  • @Jonas, if they maliciously change the tags of the axes, then they need to keep track of the data axes themselves. There is no general way to detect the purpose of a set of axes automatically. – Nzbuu Jan 31 '12 at 14:43
  • @Jonas, Nzbuu, I understand your opinions. By the way, this solution is definitely elegant. Nzbuu, regarding your last comment, you can detect the 'String' property for legends. Since "regular" axes don't have it, even a really malicious user can't change it. Check out (2) in my answer. Thanks – Andrey Rubshtein Jan 31 '12 at 14:58
  • @Andrey: However, a non-malicious user might create a non-standard legend by adding custom axes, and give them the tag "legend" so as to label them with TMW standards :). BTW: I like your solutions. One of your upvotes is from me. – Jonas Jan 31 '12 at 15:01
  • @Jonas, thanks. I also learned a lot from your posts. What are those TMW standards that you are talking about? BTW - non malicious users rock :) – Andrey Rubshtein Jan 31 '12 at 15:04
  • @Andrey: TMW=The MathWorks, the company that makes Matlab. – Jonas Jan 31 '12 at 15:05
  • I can't take credit for my answer: it's taken from the `linkaxes` source code. Since that's an official part of base MATLAB, doing anything that would cause it to fail should be _considered harmful_. – Nzbuu Jan 31 '12 at 15:49
  • Looking more closely at the `linkaxes` source code, it may be that the `isappdata` function is helpful in detecting non-data axes. – Nzbuu Jan 31 '12 at 15:53
6

1) By default the Tag property of legend is 'Legend'. Of course, there is no promise that it is not changed.

 get(l)

 ....
 BusyAction: 'queue'
      HandleVisibility: 'on'
               HitTest: 'on'
         Interruptible: 'off'
              Selected: 'off'
    SelectionHighlight: 'on'
                   **Tag: 'legend'**
                  Type: 'axes'
         UIContextMenu: 200.0018
              UserData: [1x1 struct]

 ....

2) Another difference (which is more robust) is that regular axes do not have String property, but legends do. I am not sure whether there are other types of objects that also have String property. For example:

  plot(magic(3));legend('a','v','b');
  allAxesInFigure = findall(f,'type','axes')
  b = isprop(allAxesInFigure,'String')

You can verify it by calling:

get(gca,'String')
??? Error using ==> get
There is no 'String' property in the 'axes' class.

But on the other hand, for legends there is such a property. That is why it is more robust.

 plot(magic(3)); l = legend('a','b','c');
 get(l,'String')

ans = 'a' 'b' 'c'

3) I would recommend to solve this in a broader context. Just keep track of the legends and axes you create by storing their handles. That is, instead of coding like:

 plot(magic(3));
 legend('a','v','b');
 plot(magic(5));
 legend('a','v','b','c','d');

Code like this:

 p(1) = plot(magic(3));
 l(1) = legend('a','v','b');
 p(2) = plot(magic(5));
 l(2) = legend('a','v','b','c','d');
Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
0

Just slightly modifying the code of my answer at the stackoverflow question you mentioned:

axesHandles = get(fig, 'Children');
classHandles = handle(axesHandles);
count = length(axesHandles);
isLegend = false(1, count);
for i = 1:count
    isLegend(i) = strcmp(class(classHandles(i)), 'scribe.legend') == 1;
end
legendHandles = axesHandles(isLegend);

Unfortunately, this solution depends on implementation details.

Community
  • 1
  • 1
tm1
  • 1,180
  • 12
  • 28