Why is get(gcf, 'children') inconsistent for the same figure handle? Messes up my bode plot when calling my function twice to draw into the same figure.
Show older comments
I have a method that makes a bode plot using bode(sys). It then draws an auxiliary line into the magnitude part of the bode plot by using
childrenHnd = get(gcf, 'children')
magnAxesHnd = childrenHnd(3);
axes(magnAxesHnd);
plot(get(magnAxesHnd, 'XLim'), [0, 0])
which works fine. As you can see, the handle for the magnitude axes is the third element of childrenHnd.
Now I'd like to use the same method to draw another frequency response in the same figure. However, suddenly, when I use the figure handle to get to the magnitude axes handle, it's the second element of childrenHnd. See the following example:
%%plot1
figure(1)
hold on
bode(H1)
childrenHnd = get(gcf, 'children')
magnAxesHnd = childrenHnd(3);
axes(magnAxesHnd);
plot(get(magnAxesHnd, 'XLim'), [0, 0])
hold off
%%plot2
figure(1);
hold on
bode(H2)
childrenHnd = get(gcf, 'children')
magnAxesHnd = childrenHnd(3);
axes(magnAxesHnd);
plot([1 10], [10, 10])
Using this code, my second auxiliary line is drawn in the phase part of the bode plot. Using childrenHnd(2) places the auxiliary line in the intended magnitude part.
Therefore, I can't reuse my method to draw correctly into the same figure. Any good solutions?
4 Comments
"Any good solutions?"
Yes: stop using gcf and looking for children of graphics objects! The much simpler and totally reliable solution: return and use explicit graphics handles for any object that you need to refer to.
All graphics functions that plot/create something return figure/axes/line/patch/... object handles: use them. Almost all graphics functions accept an input argument for specifying the parent object: use it. Done, problem solved by writing better, clearer, and simpler code. Here is a simple example:
fgh = figure(...);
axh = axes(fgh,...);
lnh = plot(axh,...);
Simple stupid commands like gcf and clc are for playing around in the command window. Do not use them in real code that you actually want to work reliably.
Kai-Jimmy Shen
on 14 Jul 2017
@Kai-Jimmy Shen: bode is one of the MATLAB functions that unfortunately does not accept/return useful graphics handles. So you are right: looking at the figure children might be the only way to get the required axes handles. However you should not rely on the order of the handles, instead you should check what features they have and pick the correct one. For example something like:
- obtain all figure children that are axes
- check their xlabel properties
- pick the axes with xlabel starting with 'Frequency'.
I have not checked this, and you will have to find some feature that uniquely identifies the correct axes. It also illustrates why it is so much simpler to obtain/access explicit graphics handles when possible, so you should still avoid gcf and obtain the figure handle directly from figure.
Alternative: if bode is defined in an Mfile then it may be possible for you to copy it and adapt it for your own needs. This might be a simpler option than mucking around with figure children. Ensure that you copy it to your personal working directory and do not alter the original file.
Kai-Jimmy Shen
on 14 Jul 2017
Accepted Answer
More Answers (0)
Categories
Find more on Plot Customization 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!