3

Matlab provides a function called uistack for arranging UI objects in the depth direction (which objects are in front of which others, etc). There is also a function (axes) for setting the current axes. I find that when I call axes, it also automatically puts that axes object in front of all other objects (including uipanels, etc). Is there any way to avoid this?

Here is some code that illustrates my question:

figure(1)
clf

ax1 = axes();
set(ax1,'position',[.1 .1 .5 .5],'xtick',[],'ytick',[],'color','r')

ax2 = axes();
set(ax2,'position',[.3 .3 .5 .5],'xtick',[],'ytick',[],'color','b')

% blue (ax2) is on top since it was created after ax1

uistack(ax1,'top')

% red (ax1) is now on top (good)

axes(ax2)

% [do some plotting or something in ax2]

% blue (ax2) is now on top (I'd rather avoid this)
Jed
  • 193
  • 11
  • I know I can go back and set uistack(ax1,'top') again at the end, but in my real situation I have many objects and there is one i want to keep on top regardless of what I do to any other objects (uipanels, uicontrols, etc)... its a hassle to keep having to put that object on top every time I touch any other object. – Jed Feb 02 '21 at 18:45

1 Answers1

4

To make h_ax the current axes in figure h_fig without putting those axes in front, use:

set(h_fig, 'CurrentAxes', h_ax)

Why this works

From the documentation of the axes function, the syntax axes(cax)

makes cax the first object listed in the Children property of the figure and sets the CurrentAxes property of the figure to cax.

Making cax the first object listed in the Children property is what causes it to be in front. This can be checked by modifying that property and seeing the effect. Also, by looking at uistack's code it is seen that what that function internally does it to rearrange the order of the figure's Children.

Setting the figure's CurrentAxes property to cax is what causes those axes to be the current ones. This can be checked by modifying that property, plotting something and seeing in what axes the plot appears.

So, setting the CurrentAxes property of the figure to the desired axes achieves the desired effect without moving those axes to the front.

Jed
  • 193
  • 11
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • Thanks... this is exactly what I was looking for, but I am going to edit one typo I think you made: it should be set(f, 'currentaxes',h) instead of set(h, 'currentaxes',f) – Jed Feb 03 '21 at 03:26
  • 1
    Thanks again... in retrospect this seems so obvious, so I am embarrassed to have even asked it, but I am very glad I did... in fact, it helped me figure out something else that has troubled me in the past. Sometimes I run a long program that updates figures regularly so i can visually check some result. Using set(0,'currentfigure',h_fig) instead of figure(h_fig) in my loop (which is analogous to what you posted, but for figures) allows me to continue editing a file, e.g., while monitoring progress in the background... :-) Yay! – Jed Feb 04 '21 at 18:02
  • 1
    @Jed I see. That way the figure window doesn't get the focus. Nice! – Luis Mendo Feb 04 '21 at 23:10