What would cause Matlab to lose track of gcf()?
14 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Chris
el 7 de Sept. de 2024
I'm trying to reproduce a bug/reduce it to something I can report, but so far it only happens when I call a particular 150-line function. I can put the offending code, up to and including the line that causes the error, in a new function and it runs fine, so I imagine there's something going on behind the scenes with the other 140 lines. T̶h̶i̶s̶ ̶c̶o̶d̶e̶ ̶r̶u̶n̶s̶ ̶f̶i̶n̶e̶ ̶o̶n̶ ̶W̶i̶n̶d̶o̶w̶s̶.̶
If I pause inside the function and type
which gcf
I get: built-in (/Applications/MATLAB_R2024a.app/toolbox/matlab/graphics/gcf)
Which is correct. But when I call gcf immediately after, I get:
Unrecognized function or variable 'gcf'.
Sorry I don't have an example to upload. I'm just looking for troubleshooting ideas.
5 comentarios
dpb
el 7 de Sept. de 2024
Editada: dpb
el 7 de Sept. de 2024
I figured it would be something of the sort where somehow you would have redefined gcf or got bad syntax with it...glad you did find it.
But,
gcf().Children.Title % To demonstrate there's a figure
I would strongly recommend against writing code of such nature where you call either gcf or gca repeatedly to refer to the same figure/axes; besides such syntax errors as the above, since MATLAB is event driven, it is possible an external event such as user interaction can change focus and instead of the desired figure/axis being returned, you get what that new focus is.
Much more reliable coding is to save the handles of the objects when you create them, or if it is necessary to call gcf; then do it like
hF=gcf;
...
and then use hF consistently in the function -- you'll avoid such issues as writing such bad syntax and also be assured of using/referring to the correct figure later on. If you do have multiple figures/axes, create an array of grapics objects handles to hold them.
% gcf().Children.Title.String = "I AM ERROR"
and certainly, trying to assign to a property of an inderect reference to the property of the secondary graphic object is not surprising to have confused the parser even if it isn't specifically written to prohibit such.
axes
gcf().Children
gcf().Children.Title
does return the handle to the title, but trying to do an assignment in that syntax is just expecting too much.
But, consider
figure
axes;
colorbar;
gcf().Children
and now you've got an array of children and what is
gcf().Children.Title
to try to do now?
It is far better to save handles to the objects when you create them and use those, but if you find you simply must find a particular object such as the title in an axes, then use findobj to do so by 'Type' or 'Tag' or similarly.
Respuesta aceptada
Walter Roberson
el 7 de Sept. de 2024
Unrecognized function or variable 'gcf'.
You can get that error if you had previously defined gcf as a variable in your code, but then you cleared the variable. When you create a variable then MATLAB removes the name from the list of available functions; when you then clear the variable it no longer knows it as a variable and does not add it back in as a function.
6 comentarios
dpb
el 12 de Sept. de 2024
Editada: dpb
el 12 de Sept. de 2024
figure;
close(gcf)
% nongraphics code here...
tmp=gcf;
tmp.Children
If there were only one figure when closed gcf(), then the gcf() call subsequently will create a new one; but that's all it will have done at that point.
Still is very unsafe code construction using implicit handles; there's no guarantee about what the Children of gcf() will be; is not necessarily even a single object, nor any, the latter of which is the case here because creating the default figure only results in the figure handle itself; there are no children until put an axes or other allowable child of a figure graphics object into it...referring to an empty figure's children does return the placeholder without error, but then trying to address a property of an as yet uncreated child object rightfully errors.
dpb
el 12 de Sept. de 2024
figure; axes;
figure;
close(gcf)
% nongraphics code here...
tmp=gcf;
tmp.Children
Alternatively, if there were multiple figures extant and an earlier one did have something inside it; then the result would be the previous....
Again, can't emphasize enough how unsafe/undpredictable such coding practice is and should be strictly avoided.
Más respuestas (1)
Image Analyst
el 7 de Sept. de 2024
Editada: Image Analyst
el 7 de Sept. de 2024
Don't do it like that: gcf().something. Assign something to gcf, like g:
g = gcf; % No parentheses after gcf. I think a figure must have already been created before doing this.
then you can set properties of g to change the gcf properties:
g.WindowState = 'maximized' % Maximize the figure window.
When you do
gcf().Children.Title % To demonstrate there's a figure
it assumes gcf is a variable and is a vector. But it is NOT. But since you put parentheses, it assumes it is and it wants an index inside the parentheses, which you didn't provide. That's why it's giving you the error "At least one index is required." As far as I know gcf just refers to the current figure and therefore is never an array and so won't take parenthese or an index. If you need a bunch of figures up simultaneously and need to manipulate their properties, you need to save their handles, which can be an array of handles, or just simply separate variables, like
g1 = figure('Name', 'This is figure 1');
g2 = figure('Name', 'This is figure 2');
g3 = figure('Name', 'This is figure 3');
Then you can manipulate whichever one you want individually, as long as that figure window still exists (you haven't closed it).
1 comentario
Ver también
Categorías
Más información sobre Graphics Object Identification en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!