Передача varargs функции plot () - PullRequest
4 голосов
/ 13 декабря 2011

Я пишу оболочку для plot, которая автоматизирует некоторые задачи, которые я часто выполняю.

Пример кода может выглядеть как

function myplot(x,y,varargin)
    plot(x,y,varargin{:})
    xlabel('x axis')
    ylabel('y axis')
end

Я использую Matlab varargin для передачи дополнительных аргументов plot. Тем не менее, я считаю, что я могу передать свои необязательные аргументы в varargin. Например, я мог бы написать что-то вроде

>> myplot(1:10, 1:10, 'r', 'LineWidth', 2, 'legend', {'Series 1'})

чтобы функция автоматически включала в график легенду, то есть я хочу иметь возможность смешивать свои собственные аргументы ключевых слов с теми, которые вы можете предоставить для построения. Если не считать полного парсера для моих varargs, есть ли способ сделать это просто и повторно в Matlab?

Я пытался использовать объект inputParser, но это потребовало бы от меня вручную добавить каждый возможный дополнительный аргумент для заговора (и значение по умолчанию для него), который не кажется идеальным.

Ответы [ 3 ]

6 голосов
/ 13 декабря 2011

inputParser все еще может быть лучшим выбором.Вы можете создать объект для ваших дополнительных аргументов и объединить все пары имя_параметра / имя_параметра, которые вы хотите передать в plot в Unmatched.

function myplot(x,y,varargin)

    parserObj = inputParser;
    parserObj.KeepUnmatched = true;
    parserObj.AddParamValue('legend',false); 
    %# and some more of your special arguments

    parserObj.parse(varargin);

    %# your inputs are in Results
    myArguments = parserObj.Results;

    %# plot's arguments are unmatched
    tmp = [fieldnames(parserObj.Unmatched),struct2cell(parserObj.Unmatched)];
    plotArgs = reshape(tmp',[],1)'; 


    plot(x,y,plotArgs{:})
    xlabel('x axis')
    ylabel('y axis')

    if myArguments.legend
       %# add your legend
    end
end
1 голос
/ 26 мая 2015

Для поддержки аргумента Linespec без вмешательства в параметры входного синтаксического анализатора, которые имеют имя из 4 символов или менее (например, 'grid' или 'bins'), у вас должен быть немного более сложный способ проверки правильности Linespec. аргумент чем '@ (x) ischar (x) && цифра (x) <= 4'. Эта проверка вернула бы true также для 'grid' и 'bins', хотя они не являются действительными аргументами Linespec. </p>

Следующая функция вернет true, только если введен действительный аргумент Linespec:

function isls = islinespec(x)
isls    = false;

if ~ischar(x)
    return;
end

lineStyleSpecifiers     = {'--','-.','-',':'};
markerSpecifiers        = {'square','diamond','pentagram','hexagram','+','o','*','.','x','s','d','^','v','>','<','p','h'};
colorSpecifiers         = {'r','g','b','c','m','y','k','w'};

for oo=1:length(lineStyleSpecifiers)
    k = strfind(x,lineStyleSpecifiers{oo});
    if ~isempty(k)
        x(k:(k+length(lineStyleSpecifiers{oo})-1)) = [];
        break;
    end
end

for oo=1:length(markerSpecifiers)
    k = strfind(x,markerSpecifiers{oo});
    if ~isempty(k)
        x(k:(k+length(markerSpecifiers{oo})-1)) = [];
        break;
    end
end

for oo=1:length(colorSpecifiers)
    k = strfind(x,colorSpecifiers{oo});
    if ~isempty(k)
        x(k:(k+length(colorSpecifiers{oo})-1)) = [];
        break;
    end
end

if isempty(x)
    isls = true;
end

(Следует признать, что функция могла бы быть написана более элегантно с помощью регулярных выражений, но она делает свое дело.)

Пример использования:

parserObj = inputParser;
parserObj.KeepUnmatched = true;
parserObj.AddParamValue('legend',false);
parserObj.AddParamValue('grid',true);
parserObj.addOptional('LineSpec','-', @(x) islinespec(x));
0 голосов
/ 24 марта 2013

Чтобы добавить поддержку LineSpec с использованием синтаксического анализатора в однозначной форме с парами / парал / вал, выполните:

function myplot(x,y,varargin)
    parserObj = inputParser;
    parserObj.KeepUnmatched = true;
    parserObj.AddParamValue('legend',false);
    parserObj.addOptional('LineSpec','-',@(x) ischar(x) && (numel(x) <= 4));
    %# and some more of your special arguments

    parserObj.parse(varargin{:});

    %# your inputs are in Results
    myArguments = parserObj.Results;

    %# plot's arguments are unmatched
    plotArgs = struct2pv(parserObj.Unmatched); 

    plot(x,y,myArguments.LineSpec,plotArgs{:})
    xlabel('x axis')
    ylabel('y axis')

    if myArguments.legend
       %# add your legend
    end
end

function [pv_list, pv_array] = struct2pv (s)
    p = fieldnames(s);
    v = struct2cell(s);
    pv_array = [p, v];
    pv_list = reshape(pv_array', [],1)';
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...