Matlab-необязательный аргумент дескриптора сначала для функций типа plot
Matlab включает в себя множество функций построения, которые принимают необязательный аргумент, являющийся дескриптором оси для построения. Существует много решений для добавления необязательных аргументов в пользовательские функции (varargin, inputParser), однако они обычно требуют, чтобы необязательные аргументы приходили только после обязательных аргументов, в то время как функции построения в matlab обычно имеют форму
plot(optional, mandatory, optional)
то есть, необязательные аргументы могут прийти как до, так и после обязательные аргументы.
Я хотел бы повторить это поведение для пользовательского типа графика, чтобы он следовал тому же стилю, что и встроенные функции графика. Представлены следующие варианты использования, демонстрирующие, что одной проверки количества аргументов недостаточно для достижения желаемого поведения:
x = [1:10];
y = x.^2;
ax(1) = subplot(1, 2, 1);
ax(2) = subplot(1, 2, 2);
myplot(x, y); %Mandatory
myplot(x, y, 'r+'); %Mandatory, optional
myplot(ax(1), x, y); %Optional, mandatory
myplot(ax(2), x, y, 'r+'); %Optional, mandatory, optional
мой вопрос в том, какие методы мы можем использовать для эмуляции этого поведения?
2 ответов
вы можете написать функцию, которая принимает varargin
в качестве входных данных. Затем вы проверяете количество аргументов. Если это меньше, чем 2
(или что-то еще, в зависимости от вашей функции), вызовите ошибку или предупреждение. Затем проверьте class
входных параметров.
если class
ваш первый вход 'matlab.graphics.axis.Axes'
, тогда ваша функция должна вызвать: plot(ax,___)
. Если это double, то это должен быть формат plot(X,Y,LineSpec)
.
что-то в этом роде должно работа
function [] = myplot(varargin)
if nargin < 2
error('Minimum two input must be given'); % You probably want something other than an error. This was just an example.
elseif nargin == 2
% Code for plotting
plot(x, y)
elseif nargin == 3
if strcmp(class(varargin{1}),'matlab.graphics.axis.Axes')
ax1 = varargin{1};
x = varargin{2};
y = varargin{3};
plot(ax1, x, y)
elseif isa(varargin{2}, 'double') && isa(varargin{3}, 'double') && isa(varargin{3}, 'char')
x = varargin{1};
y = varargin{2};
LineSpec = varargin{3};
else ...
PS! Вам не нужно делать x = varargin{1}
etc., это было просто, чтобы проиллюстрировать, что каждый из различных элементов ячейки представляет, если if
оценивает в true
.
вы можете продолжить с "аргументами пары имя-значение". Проверьте, является ли класс входного аргумента char
, и что он не может представлять что-то, кроме имени параметра. Если это имя параметра, то вы знаете, что следующий аргумент является значением параметра.
я обычно использую такой шаблон, который также используется многими функциями построения графиков, которые являются частью MATLAB:
function varargout = myplot(obj, varargin)
% Check the number of output arguments.
nargoutchk(0,1);
% Parse possible axes input.
[ax, args, ~] = axescheck(varargin{:}); %#ok<ASGLU>
% Get handle to either the requested or a new axis.
if isempty(ax)
hax = gca;
else
hax = ax;
end
% At this point, hax refers either to a specified axis, or
% to a fresh one if none was specified. args refers to the
% remainder of any arguments passed in varargin.
% Parse the rest of args
% Make the plot in hax
% Output a handle to the axes if requested.
if nargout == 1
varargout{1} = hax;
end
end
axescheck
является недокументированной функцией. Вы всегда идете на небольшой риск, делая это, но он присутствует и неизменен в MATLAB с тех пор навсегда, и он используется многими очень стабильными функциями построения графиков в MATLAB, поэтому вы должны быть в порядке.
он проверяет, является ли первый аргумент дескриптором оси. Если это, тогда ax
это ручка, и args
- Это остальные входные аргументы. Если нет, то ... --2--> пусто и args
содержит все входные аргументы.
надеюсь, что это поможет!
Edit: дополнительная информация о axescheck
как просили.
во-первых, вы можете увидеть расположение и исходный код axescheck
введя which axescheck
и edit axescheck
. Таким образом, вы можете точно видеть, что он делает.
синтаксис [AX, ARGS, NARGS] = AXESCHECK(ARG1, ARG2, ...)
.
во-первых, он проверяет, если ARG1
является ручкой оси. Если это так, он возвращается как AX
, остальные аргументы (ARG2, ...
) возвращены в ARGS
и NARGS
значение nargin
минус 1.
во-вторых, он проверяет, если любой из входных аргументов параметр-значение параметра Parent
. Если да, то все пары параметр-значение с параметром Parent
удаляются из списка. Указанная ось возвращается в AX
, в остальные аргументы возвращаются в ARGS
и NARGS
значение nargin
минус количество удаленных аргументов.
если ось не указана ни в одном из вышеуказанных способов, то AX
пустой ARGS
- это только входные аргументы, а NARGS
значение nargin
.
axescheck
работает как со старыми (Handle Graphics 1) двойными ручками, так и с новыми (Handle Graphics 2) ручками класса matlab.graphics.axis.Axes
.
он также проверяет является ли предоставленный дескриптор дескриптором удаленного объекта, вызывая ошибку, если это так.
он довольно широко используется во многих встроенных функциях построения графиков MATLAB-см., например,hist.m, polar.m, surfl.m, bar3.m, comet.m, pie.m
и многие другие.