Matlab - необязательный аргумент дескриптора, сначала для функций, подобных графику
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,___)
, Если это двойной, то это должен быть формат 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}
и т.д., это было только для иллюстрации того, что представляет собой каждый из различных элементов ячейки, если 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
это остальные входные аргументы. Если нет то ax
пусто и args
содержит все входные аргументы.
Надеюсь, это поможет!
Изменить: Больше информации о 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
и много других.