Matlab "auto-squeeze" 图
Matlab "auto-squeeze" plot
Matlab 绘图要求数据具有相同的维度。意思是,您不能用 1x1x10 向量绘制 1x10 向量。这有时是必要的。出于这些目的,您可以使用 squeeze 函数来摆脱单一维度。
但是,这有点麻烦。对于 plot 函数特别是,让参数总是 squeezed 会很有用。如何创建一个新函数,让我们称之为 splot,它压缩每个输入并将其传递到 plot。这是一个尝试(不起作用)
function splot(varargin)
for i=1:length(varargin)
varargin{i}=squeeze(varargin{i});
end
plot(varargin)
end
plot(varargin) 部分失败,因为这根本不是 matlab 语法的工作方式。但是有什么办法可以实现我想要的吗?我想我可以写一个很长的 if elseif 链,在其中我手动编写带有每个可能数量的输入参数的案例,例如:
if length(varargin)==2
plot(varargin{1},varargin{2})
if length(varargin)==3
plot(varargin{1},varargin{2},varargin{3})
但这会很烦人。有什么更好的想法。
此题与相似,但不够相似,因为另一道题是挤压每个向量,这是一个坏主意。在这里,我要求一种方法来仅压缩绘图函数的输入并需要语法帮助。
从 docs 有几种方法可以调用 plot
。一般
只是数值数组,它们可以是单独的,也可以是一对或多对
plot(Y)
、plot(X,Y)
或 plot(X1,Y1,...,Xn,Yn)
数字数组和以前一样,带有一个字符数组给出行规范
plot(X,Y,LineSpec)
或 plot(Y,LineSpec)
前两个中的任意一个,加上名称-值对选项
plot(___,Name,Value)
在任何这些情况下,您都希望压缩前 N
个数字输入,因为任一可选添加项都将第一个不可绘制的输入作为字符。
我们可以通过下面的代码实现,具体见评论:
function h = splot( varargin )
% Check if there are any optional inputs, which will either be
% LineSpec (which is a char) or name-value pairs (which the
% first of will be a char)
bNumericArg = cellfun( @isnumeric, varargin );
% By default, assume all inputs are arrays to plot
lastArrayArg = numel(varargin);
if ~all(bNumericArg)
% In this case, there are some optional inputs, get last array index
lastArrayArg = find( ~bNumericArg, 1 ) - 1;
end
% Squeeze the arrays
for ii = 1:lastArrayArg
varargin{ii} = squeeze(varargin{ii});
end
% Plot with all inputs, optional output
if nargout > 0
h = plot( varargin{:} );
else
plot( varargin{:} );
end
end
有两种可能的情况我没有在这里处理,plot
函数可以处理,
将第一个输入作为目标轴,即 plot(ax,___)
,可以通过稍微改变循环以从 1 或 2 开始来实现,具体取决于第一个输入是轴对象
有一对数组,每个数组都有自己的行规范参数,即 plot(X1,Y1,LineSpec1,...,Xn,Yn,LineSpecn)
。后面的对将被忽略。这将更难处理,因为您可能必须解析所有输入并检查 char 是否只是一个行规范,或者您是否正在处理名称 - 值对。也许是与“两个数组然后一个字符,重复”有关的启发式方法。我从来没有使用过这种语法,所以现在省略了过于复杂的部分。
Matlab 绘图要求数据具有相同的维度。意思是,您不能用 1x1x10 向量绘制 1x10 向量。这有时是必要的。出于这些目的,您可以使用 squeeze 函数来摆脱单一维度。
但是,这有点麻烦。对于 plot 函数特别是,让参数总是 squeezed 会很有用。如何创建一个新函数,让我们称之为 splot,它压缩每个输入并将其传递到 plot。这是一个尝试(不起作用)
function splot(varargin)
for i=1:length(varargin)
varargin{i}=squeeze(varargin{i});
end
plot(varargin)
end
plot(varargin) 部分失败,因为这根本不是 matlab 语法的工作方式。但是有什么办法可以实现我想要的吗?我想我可以写一个很长的 if elseif 链,在其中我手动编写带有每个可能数量的输入参数的案例,例如:
if length(varargin)==2
plot(varargin{1},varargin{2})
if length(varargin)==3
plot(varargin{1},varargin{2},varargin{3})
但这会很烦人。有什么更好的想法。
此题与
从 docs 有几种方法可以调用 plot
。一般
只是数值数组,它们可以是单独的,也可以是一对或多对
plot(Y)
、plot(X,Y)
或plot(X1,Y1,...,Xn,Yn)
数字数组和以前一样,带有一个字符数组给出行规范
plot(X,Y,LineSpec)
或plot(Y,LineSpec)
前两个中的任意一个,加上名称-值对选项
plot(___,Name,Value)
在任何这些情况下,您都希望压缩前 N
个数字输入,因为任一可选添加项都将第一个不可绘制的输入作为字符。
我们可以通过下面的代码实现,具体见评论:
function h = splot( varargin )
% Check if there are any optional inputs, which will either be
% LineSpec (which is a char) or name-value pairs (which the
% first of will be a char)
bNumericArg = cellfun( @isnumeric, varargin );
% By default, assume all inputs are arrays to plot
lastArrayArg = numel(varargin);
if ~all(bNumericArg)
% In this case, there are some optional inputs, get last array index
lastArrayArg = find( ~bNumericArg, 1 ) - 1;
end
% Squeeze the arrays
for ii = 1:lastArrayArg
varargin{ii} = squeeze(varargin{ii});
end
% Plot with all inputs, optional output
if nargout > 0
h = plot( varargin{:} );
else
plot( varargin{:} );
end
end
有两种可能的情况我没有在这里处理,plot
函数可以处理,
将第一个输入作为目标轴,即
plot(ax,___)
,可以通过稍微改变循环以从 1 或 2 开始来实现,具体取决于第一个输入是轴对象有一对数组,每个数组都有自己的行规范参数,即
plot(X1,Y1,LineSpec1,...,Xn,Yn,LineSpecn)
。后面的对将被忽略。这将更难处理,因为您可能必须解析所有输入并检查 char 是否只是一个行规范,或者您是否正在处理名称 - 值对。也许是与“两个数组然后一个字符,重复”有关的启发式方法。我从来没有使用过这种语法,所以现在省略了过于复杂的部分。