What is best practice to determine if input is a figure or axes handle?

82 visualizaciones (últimos 30 días)
I've been confused about MATLAB graphics since change to the new graphics system. I do not know how I can check for a variable being a handle to a figure or axes. Functions that come to mind are:
ishandle
isgraphics
ishghandle
isa(x,'matlab.ui.Figure') % x being the variable representing a Figure or Axes
isa(x,'matlab.graphics.axis.Axes') % wow, these really are cumbersome commands!
% etc.
What are best practices to ensure maximal compatibility with most MATLAB versions to detect what kind of input I'm dealing with? Why are there no
isfigure
or
isaxes
functions built-in?
  4 comentarios
Adam
Adam el 26 de Ag. de 2016
I use a test on the class in the new system, though usually I am doing it for validation so I use:
validateattributes( hAxes, { 'matlab.graphics.axis.Axes' }, { 'scalar' } )
which I wrapped up with another command in my own validateAxes( hAxes ) function. To return a boolean though I would just wrap the isa test in my own isAxes( hAxes ) function so that the ugly code is hidden under an intuitively named function.
I do also tend to get mixed up as to the difference between ishghandle and isgraphics for a more generic test though.
adams13
adams13 el 18 de En. de 2017
If you are talking about compatibility than I would use a method that works also in Octave:
function isAxes = IsAxes(ax)
try
isAxes = strcmp(get(ax, 'type'), 'axes');
catch
isAxes = false;
end
end

Iniciar sesión para comentar.

Respuesta aceptada

Bjorn Gustavsson
Bjorn Gustavsson el 25 de Ag. de 2016
Simples, write those functions yourself, something along the lines:
function OK = isfigure(h)
if strcmp(get(h,'type'),'figure')
OK = 1;
else
OK = 0;
end
You could decorate your code to handle array input, do error checking and make the output proper Boolean output but the core part is to look at the type field of the graphics handle.
HTH
  2 comentarios
Guillaume
Guillaume el 26 de Ag. de 2016
Well, if you're going to write your own test function, at least make it so it also works with arrays of handles:
function tf = isfigure(h)
tf = strcmp(get(h, 'type'), 'figure');
end
Adam Danz
Adam Danz el 4 de Mayo de 2019
Editada: Adam Danz el 2 de Mzo. de 2021
Like the other two answers here, this method also doesn't distinguish between a figure handle of class 'matlab.ui.Figure' and a double precision integer that happens to have the same value as a figure number ( I provided examples below the other two answers ). This becomes an issue in the case of a function with a variable number of input arguments (varargin) where an input could be a figure handle or an integer that has the same value as a figure number.
To make that distinction in r2014b and later, check the class of the variable as well.
tf = strcmp(get(h, 'type'), 'figure') & isa(h, 'matlab.ui.Figure');

Iniciar sesión para comentar.

Más respuestas (3)

Erik
Erik el 1 de Oct. de 2016
Another option I found inside the undocumented axescheck function is the specification of a type to check for when using isgraphics. The following function does the job for figures.
function tf = isfigure(f)
tf = isgraphics(f,'figure')
I didn't know isgraphics accepted the type to check for. This also works for 'axes'.
  2 comentarios
per isakson
per isakson el 11 de Jul. de 2018
isgraphics was introduced in R2014b
Adam Danz
Adam Danz el 4 de Mayo de 2019
Editada: Adam Danz el 2 de Mzo. de 2021
Take note that isgraphics() doesn't distinguish between a figure handle of class 'matlab.ui.Figure' and a double precision integer that happens to have the same value as a figure number (for backward compatibility prior to r2014b).
close all
fig = figure(); %assigned fig 1
isfig = isgraphics(fig,'figure')
isfig = logical
1
isfig = isgraphics(1,'figure')
isfig = logical
1
This is because
handle(1)
ans =
Figure (1) with properties: Number: 1 Name: '' Color: [1 1 1] Position: [509 657 583 437] Units: 'pixels' Show all properties
To accept only figure handles and not matching integers from r2014b and later,
close all
fig = figure(); %assigned fig 1
isfig = isgraphics(fig,'figure') && isa(fig,'matlab.ui.Figure')
isfig = logical
1
isfig = isgraphics(1,'figure') && isa(1,'matlab.ui.Figure')
isfig = logical
0

Iniciar sesión para comentar.


PepijnB
PepijnB el 11 de Jul. de 2018
Editada: PepijnB el 11 de Jul. de 2018
In the 'eyediagram'-function (build-in Matlab function), Mathworks checks the validity of a handle by the code:
ishghandle(h,'figure')
To check whether the handle is from an axes, use the following:
ishghandle(h, 'axes')
  3 comentarios
Adam
Adam el 10 de Abr. de 2019
It's documented in R2019a. Don't know about earlier versions.
Adam Danz
Adam Danz el 4 de Mayo de 2019
Editada: Adam Danz el 2 de Mzo. de 2021
I checked the archive and didn't find documentation for the 2nd input in r19a.
Note that ishghandle() doesn't distinguish between a figure handle of class matlab.ui.Figure and a double precision integer that happens to have the same value as a figure number (for backward compatibility prior to r2014b).
For example,
close all
fig = figure(); %assigned fig 1
isfig = ishghandle(fig,'figure')
isfig = logical
1
isfig = ishghandle(1,'figure')
isfig = logical
1
This is because
handle(1)
ans =
Figure (1) with properties: Number: 1 Name: '' Color: [1 1 1] Position: [509 657 583 437] Units: 'pixels' Show all properties
To accept only figure handles and not matching integers from r2014b and later,
isfig = ishghandle(fig,'figure') && isa(fig,'matlab.ui.Figure')
isfig = logical
1
isfig = ishghandle(1,'figure') && isa(1,'matlab.ui.Figure')
isfig = logical
0

Iniciar sesión para comentar.


Adam Danz
Adam Danz el 2 de Mzo. de 2021
Editada: Adam Danz el 2 de Mzo. de 2021
I find myself revisiting this page from time to time and wanted to share an alternative best practice to determine if an array of inputs are figures or axes. It's based on Erik's solution using isgraphics(h,type) which is documented at least as far back as r2015b and functions in even older releases but with two differences:
  1. Distinguishes between figure or axes handles and double precision values that match handle values, after r2014a. For example, close all; h=figure; isgraphics(1,'figure') returns true which could be problematic in some contexts after r14a.
  2. Includes polaraxes for the is-axes test
Tested in r2020b & r2014a after removing features in the demo that didn't exist then.
% h is an array; function return a logical array the same size as h.
isfigure = @(h)isgraphics(h,'figure') & (verLessThan('matlab','8.4') | ~isa(h,'double'));
isaxes = @(h)(isgraphics(h,'axes') | isgraphics(h,'polaraxes')) & (verLessThan('matlab','8.4') | ~isa(h,'double'));
Demo:
% 5 figures and 5 axes
close all
vis = 'off';
h(1) = figure('Visible',vis); % Visibility not needed for the demo
h(2) = figure('Visible',vis);
h(3) = figure('Visible',vis);
h(4) = uifigure('Visible',vis);
h(5) = uifigure('Visible',vis);
h(6) = axes(h(1));
h(7) = polaraxes(h(2));
h(8) = subplot(2,2,1,'Parent',h(3));
h(9) = uiaxes(h(4));
tlo = tiledlayout(h(5),1,2);
h(10) = nexttile(tlo);
cleanup = onCleanup(@()delete(h));
isfig = isfigure(h)
% isfig =
% 1×10 logical array
% 1 1 1 1 1 0 0 0 0 0
isax = isaxes(h)
% isax =
% 1×10 logical array
% 0 0 0 0 0 1 1 1 1 1
This method correctly rejects double precision values that match the figure and axis handles when converted to double (>r14a):
val = double(h(1:3))
% val =
% 1 2 3
isfig = isfigure(val)
% isfig =
% 1×3 logical array
% 0 0 0
If you are intentionally using the double precision version of graphics handles after r2014a you can either remove those conditions from the functions or convert to handles in the inputs,
isfig = isfigure(handle(val))
% isfig =
% 1×3 logical array
% 1 1 1

Categorías

Más información sobre Graphics Object Programming en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by