How to check if handle is to a deleted axes?

I am running an old plotting routine in R2015b for the first time. It is crashing on a legend command because apparently the axes handle points to a deleted axes, and I am stumped on how to check for this. Can you please replace the line (if legh == 'handle to deleted Axes') to correctly check whether the axis is deleted?
figure; % Make demo figure
peaks;
hAx = gca; % Get demo axis
delete(hAx); % Delete axis, changing state of axis handle
% Replace following line so it correctly checks if axis is deleted
if hAx == 'handle to deleted Axes'
isDeleted = true;
else
isDeleted = false;
end
if ~isDeleted
disp('Axis exists. OK to add legend')
end

 Accepted Answer

A couple of choices.
h = plot(1:10);
delete(h)
isvalid(h)
isgraphics(h)
Either of those will return false for a deleted handle. They differ on what they return true for. The first will return true for any valid handle. The second one will return true only for graphics objects. It also supports an argument to ask if it is a particular type of graphics object.

16 Comments

Confirming that both work in my example. Thanks!
I usually use
ishghandle( h );
There seem to be a plethora of similar functions in this area!
I wasn't aware of
isgraphics( h )
though I do like the specific version:
isgraphics( h, type )
that would shorten some of the multi-line validation I do with ishghandle.
It's relatively new. I think it was added in R2014b. If you need your code to run in older versions, you might still need your multi-line validation.
The problem with these approaches is that non-graphics objects also return false and some integers return true such as 0 or an integer that is also represented by an existing figure.
isgraphics(pi)
ans = logical
0
isgraphics('a','axes')
ans = logical
0
isgraphics(0)
ans = logical
1
Imagine testing if the first input 'h' to a function is an axis handle or not and define 3 different behaviors if...
  • h is a valid axis isgraphics returns true
  • h is a deleted axis isgraphics returns false
  • h is not an axis isgraphics returns false
  • h is 0 or a fig number isgraphics returns true
There's an undocumented method to test if a variable is a deleted axis but this could change in future releases.
figure()
ax = gca();
delete(ax)
isDeletedAx = ~isgraphics(ax, 'axes') && isa(ax,'matlab.graphics.axis.AbstractAxes')
isDeletedAx =
logical
1
Or use the class of the expected axes.
isDeletedAx = ~isgraphics(ax, 'axes') && isa(ax,'matlab.graphics.axis.Axes')
For a number of purposes, 0 and positive integers that match figure numbers are still accepted in graphics operations. Interestingly, if you double() a handle to a non-figure graphic object, then most functions will not treat it as a graphic handle any more (but set() will. Also I think I noticed some aspects of Simulink still using the doubles)
@Walter Roberson your comment just led me to find another way to test for deleted axes although it fails when testing any numeric value less than 0.
isDeletedAxes = @(h)double(h)<0;
ax = axes();
delete(ax)
isDeletedAxes(ax)
ans = logical
1
I can't use this solution. I get the following error:
'isvalid' requires one of the following:
Industrial Communication Toolbox
Image Acquisition Toolbox
Instrument Control Toolbox
isvalid ships with the base MATLAB installation and shouldn't require any toolboxes. If you are finding otherwise, there might be something wrong with your MATLAB installation.
@Benjamin Kraus isvalid errors for me as well -- there may be an issue with overlapping functions?
Can you let me know:
  • What MATLAB release you are using.
  • What is the output from: which -all isvalid
version: '9.10.0.1602886 (R2021a)'
Attached "which -all isvalid" output in: isvalid_whichall.txt.
@Quinton Guerrero: Thanks for that information. It definitely looks like you should have the appropriate versions of isvalid on your path. My recommendation is to contact Technical Support. I would file a bug report for you, but I suspect Technical Support is going to want to collect some additional information to help them debug the problem.
I'm using R2022b
The attached text file contains the output of which -all isvalid
isvalid is not a function, it is a method. If you try to call isvalid with no parameter or with a parameter that is not one of the classes that defines isvalid then MATLAB is going to go searching for a useable isvalid. MATLAB knows that there is isvalid in various toolboxes but at that level it does not know the class support inside those toolboxes, so it does not know that the isvalid in those toolboxes is irrelevant to whatever you are doing.
What is class() of what you are passing to isvalid?

Sign in to comment.

More Answers (1)

How to check if graphics handle is to a deleted object?
Let's look at some options and decide which is best.
Deleted handles will be detected as objects but not as graphics objects so this line below may seem reasonable.
isDeletedObj = @(h)isobject(h) & ~isgraphics(h);
However, as the tests below show, this function will incorrectly identify graphics placeholders and string objects as deleted objects.
To test for a specific type of deleted object, add a condition that tests the class of the object.
isDeletedAxes = @(h)isobject(h) & ~isgraphics(h) & isa(h,'matlab.graphics.axis.Axes');
Another indicator of a deleted graphics object is to convert its handle to double which should return -1.
isDeletedObj_2 = @(h)double(h)==-1 & isobject(h) & ~isgraphics(h);
Example
fig = figure();
ax = axes(fig);
h = plot(ax,rand(1,5));
delete(ax) % delete the axes and line
idx = isDeletedObj_2([fig, ax, h])
idx = 1x3 logical array
0 1 1
Comparison with other methods
Test deleted axes.
tf = [ishandle(ax), ...
ishghandle(ax), ...
isvalid(ax), ...
isgraphics(ax), ...
isDeletedAxes(ax), ... % ✅
isDeletedObj(ax), ... % ✅
isDeletedObj_2(ax)] % ✅
tf = 1x7 logical array
0 0 0 0 1 1 1
Test existing object handle.
tf = [ishandle(fig), ...
ishghandle(fig), ...
isvalid(fig), ...
isgraphics(fig), ...
isDeletedAxes(fig), ... % ✅
isDeletedObj(fig), ... % ✅
isDeletedObj_2(fig)] % ✅
tf = 1x7 logical array
1 1 1 1 0 0 0
Test graphics placeholder (gobjects).
obj = gobjects(1);
tf = [ishandle(obj), ...
ishghandle(obj), ...
isvalid(obj), ...
isgraphics(obj), ...
isDeletedAxes(obj), ... % ✅
isDeletedObj(obj), ... % ❌
isDeletedObj_2(obj)] % ✅
tf = 1x7 logical array
0 0 1 0 0 1 0
Test integers that could be interpreted as double handles from MATLAB graphics prior to r2014b.
% isvalid() removed, will cause error
tf = [ishandle(1), ...
ishghandle(1), ...
isgraphics(1), ...
isDeletedAxes(1), ... % ✅
isDeletedObj(1), ... % ✅
isDeletedObj_2(1)] % ✅
tf = 1x6 logical array
1 1 1 0 0 0
Test a non-handle numeric value.
% isvalid() removed; will cause error
tf = [ishandle(pi), ...
ishghandle(pi), ...
isgraphics(pi), ...
isDeletedAxes(pi), ... % ✅
isDeletedObj(pi), ... % ✅
isDeletedObj_2(pi)] % ✅
tf = 1x6 logical array
0 0 0 0 0 0
Test string objects
% isvalid() removed, will cause error
str = "test";
tf = [ishandle(str), ...
ishghandle(str), ...
isgraphics(str), ...
isDeletedAxes(str), ... % ✅
isDeletedObj(str), ... % ❌
isDeletedObj_2(str)] % ✅
tf = 1x6 logical array
0 0 0 0 1 0

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Asked:

K E
on 10 Nov 2015

Edited:

on 18 Feb 2024

Community Treasure Hunt

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

Start Hunting!