Matlab includes many plotting functions which take an optional argument being the handle to the axis to plot to. There are many solutions online for adding optional arguments to user-defined functions (varargin, inputParser), however they usually require that the optional arguments come only after the mandatory arguments, whilst plotting functions in matlab typically are of the form
plot(optional, mandatory, optional)
That is, the optional arguments can come both before and after the mandatory arguments.
I would like to replicate this behaviour for a custom plot type so that it follows the same style as the built-in plot functions. The following use-cases are presented to demonstrate that checking the number of arguments alone is insufficient to accomplish the desired behaviour:
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
My question is, what techniques can we use to emulate this behaviour?
You can write a function that takes varargin
as input. Then, you check the number of arguments. If it's less than 2
(or something else, depending on your function), cast an error or warning. Then, check the class
of the input parameters.
If the class
of your first input is 'matlab.graphics.axis.Axes'
, then your function should call: plot(ax,___)
. If it's a double, then it must be the format plot(X,Y,LineSpec)
.
Something along these lines should work
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! You don't need to do x = varargin{1}
etc., this was just to illustrate what each of the different cell elements represents if the if
evaluates to true
.
You can continue with "Name-Value Pair Arguments". Check if the class of the input argument is char
, and that it can't represent something other than a parameter name. If it's a parameter name, then you know the next argument is a parameter value.