Search code examples
matlabplotoptional-arguments

Matlab - Optional handle argument first for plot like functions


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?


Solution

  • 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.