Matlab can gca and gcf replaced?

Hello I wonder how to refer to particular figure and/or axes when I do not use gca or gcf right after plot and figure commands. I think these things get a lot more complex in subplots. Is there a way to obtain the axes of a plot without issuing these two commands? Are there good tutorials on these on the web?

Risposte (2)

Stephen23
Stephen23 il 22 Ago 2016
Modificato: Stephen23 il 22 Ago 2016
The simplest way is to read the documentation, and you will find that every graphics function returns the handles of the graphics objects that it creates. The plotting functions also accept an axes handle, so you can specify exactly which axes to plot in:
fgh = figure(...)
axh = axes(fgh,...)
lnh = plot(axh,...)
Never rely on gca, gcf or anything similar: they are unreliable and will make your code buggy because their behavior depends on what the user clicked on, or what code has just run... basically using gcf and gca is how beginners write buggy, unreliable code. They should be used for playing in the command window, not for any serious code.

8 Commenti

It is best not to count on your active axes or active figure being the same between any two commands. Best is to specify everything, like Stephen shows. The commands that do not accept an axes as the first argument generally accept a 'Parent' property/value pair. If you encounter a graphics command that does not accept either, then it is probably going to open its own figure :(
I was reviewing an example in the 'exportgraphics' command article, under Export Figure, they wrote a code:
plot(1:10)
annotation('textarrow',[0.06 0.5],[0.73 0.5],'String','y = x ')
f = gcf;
exportgraphics(f,'AnnotatedPlot.pdf')
Is this a proper use of the 'gcf' call? I frequently use 'gcf' this way, except I don't even name it the 'f' variable. I am tryring to be better at writing less buggy codes. Thank you for your help.
Stephen23
Stephen23 il 19 Mar 2021
Modificato: Stephen23 il 19 Mar 2021
"Is this a proper use of the 'gcf' call?"
"Proper" in what sense?
"I am tryring to be better at writing less buggy codes."
Then avoid gcf and gca, exactly as the answer and Walter Roberson's comment explain. Always obtain the handle of every graphics object that you create, and then later use that handle to specify the exact graphics object that you want to refer to.
The examples in the documentation are intentionally simple, so that beginners can follow them. They are more the kind of code you would write in the command line, not the kind of robust code you would want to write for your own projects.
If you're going to refer to a plot later on in code, I would either store the handle to it when it is created or find the handle explicitly. From the handle to a graphics object you can "walk" down the graphics hierarchy via the Children property and/or the findobj or findall functions or up via the ancestor function.
h = plot(1:10);
f = ancestor(h, 'figure');
c = findall(f, 'type', 'line');
h == c
ans = logical
1
Even if the user of your code has another figure open and active as the current figure when the line of code defining f executes, f will be the figure containing the line whose handle is h.
@Steven Lord your example only have one 'h' handle. Say, I have two, h1 and h2, in one plot. Then I name f = gcf before executing 'exportgraphics' on 'f'. What type of troubles would I run into down the line if I use gcf in that way?
Stephen23
Stephen23 il 19 Mar 2021
Modificato: Stephen23 il 19 Mar 2021
@Kien Pham: if you are really interested in "I am tryring to be better at writing less buggy codes" as you wrote, then you would explicitly create the figure and obtain its handle (or refer to an existing figure via its handle), then add axes (also obtaining their handles). When you create the plots you would specify that they should be added to those axes in that figure. In fact, that is exactly what the documentation shows:
Then you call exportgraphics with that figure handle (or whatever object you want). Totally robust, no sign of gcf or gca anywhere, no ugly "walking" down the object heirarchy or other hacks.
If you keep using gcf or gca your code is not robust.
You're assuming the user didn't click on a different figure (making it active) between the creation of the plots in one figure and the call to gcf. The current figure may not be the one you expect to be current.
Also, anything like msgbox() or menu() or questdlg() creates a new figure. uigetfile() has unspecified implementation that is permitted to create a new figure (whether it does or not can depend on the operating system)

Accedi per commentare.

It’s not necessary to use gca and gcf for the axis and figure handles if you return the handle from the particular command.
Example:
Fig1 = figure(1);
ax211 = subplot(2,1,1);
plot([1:10], [1:10]+randn(1,10)*0.1, 'bp')
grid
subplot(2,1,2)
sp212 = plot([1:10], sin([0:9]*2*pi/9));
grid
Fig1Pos = Fig1.Position; % Figure 1 Position
xt211 = ax211.XTick; % Get X-Tick Values For Subplot 2,1,1
Ydata212 = get(sp212,'Ydata'); % Get Y-Data For Subplot 2,1,2

Categorie

Scopri di più su Creating, Deleting, and Querying Graphics Objects in Centro assistenza e File Exchange

Richiesto:

il 22 Ago 2016

Modificato:

il 19 Mar 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by