在Matlab/Octave中为绘图重置ColorOrder索引

14

我有包含可变数量的行向量的矩阵x1,x2,...。 我进行连续的绘图

figure
hold all % or hold on
plot(x1')
plot(x2')
plot(x3')

Matlab或Octave通常会遍历ColorOrder并以不同的颜色绘制每条线。 但我希望每个plot命令都从colororder中的第一种颜色重新开始,因此在默认情况下,矩阵中的第一个向量应为蓝色,第二个为绿色,第三个为红色等。

不幸的是,我找不到与颜色索引相关的属性,也没有其他方法可以重置它。


所有的 x 矩阵绘制的线条数量都相同吗? - Dan
2
你使用的Matlab版本是哪个?如果你使用的是2014b之前的版本,你可以简单地使用hold on代替hold all...然后所有的plot命令都将从颜色顺序的开头开始。 - Hoki
实际上,我现在使用Octave,因为我没有Matlab许可证了。@Dan 我可以想象设置正确长度的颜色映射,但不幸的是,行数是变化的。这就是我提出问题的原因。 - Honza
@Honza,那么你可能需要循环。我将在下面编辑我的答案为您创建一个函数... - Dan
循环并不优雅,但不幸的是似乎是唯一的方法... - Honza
@Honza 如果你将它封装在一个函数中,说实话我并不觉得它不优雅。我非常怀疑它会给你带来性能问题。 - Dan
5个回答

18

这个答案在Octave中不适用,因为ColorOrderIndex属性在Octave中没有使用。 - Georg W.

10

您可以转移当前坐标轴中原始的 ColorOrder,以便新的绘图从相同的颜色开始:

h=plot(x1');
set(gca, 'ColorOrder', circshift(get(gca, 'ColorOrder'), numel(h)))
plot(x2');

您可以将其封装在一个函数中:

function h=plotc(X, varargin)
h=plot(X, varargin{:});
set(gca, 'ColorOrder', circshift(get(gca, 'ColorOrder'), numel(h)));
if nargout==0,
    clear h
end
end

并且呼叫

hold all
plotc(x1')
plotc(x2')
plotc(x3')

2
似乎在MATLAB 2020a中不再起作用。但是,Luis Mendo的答案使用set(h,'ColorOrderIndex', 1)似乎有效。 - taciteloquence

5

定义一个函数,拦截调用plot并在实际绘图之前将'ColorOrderIndex'设置为1

function plot(varargin)
if strcmp(class(varargin{1}), 'matlab.graphics.axis.Axes')
    h = varargin{1}; %// axes are specified
else
    h = gca; %// axes are not specified: use current axes
end
set(h, 'ColorOrderIndex', 1) %// reset color index
builtin('plot', (varargin{:})) %// call builtin plot function

我在Matlab R2014b中进行了测试。


不错的解决方案。我相信它在当前的Matlab中可以工作,但不幸的是Octave不知道'ColorOrderIndex'属性。 - Honza
1
哦,可惜 :-) 我没有访问Octave的权限。 - Luis Mendo
Octave v5.1.0确实具有ColorOrderIndex - sancho.s ReinstateMonicaCellio

2
我找到了一个链接,里面的人最终解决了这个问题。他使用了以下代码:
t = linspace(0,1,lineCount)';
s = 1/2 + zeros(lineCount,1);
v = 0.8*ones(lineCount,1);
lineColors = colormap(squeeze(hsv2rgb(t,s,v)))
ax=gca
ax.ColorOrder = lineColors;

假设每个矩阵都有相同的行数,那么这应该适用于您。如果它们不是,则我有一种感觉您将不得不循环并单独绘制每条线,使用上面的lineColors指定plot'Color' linespec属性的RBG三元组。因此,您可以使用以下函数:
function h = plot_colors(X, lineCount, varargin)

    %// For more control - move these four lines outside of the function and make replace lineCount as a parameter with lineColors
    t = linspace(0,1,lineCount)';                              %//'
    s = 1/2 + zeros(lineCount,1);
    v = 0.8*ones(lineCount,1);
    lineColors = colormap(squeeze(hsv2rgb(t,s,v)));


    for row = 1:size(X,1)
        h = plot(X(row, :), 'Color', lineColors(row,:), varargin{:}); %// Assuming I've remembered how to use it correctly, varargin should mean you can still pass in all the normal plot parameters like line width and '-' etc
        hold on;
    end

end

其中lineCount是你的x矩阵中最多行数的数字。

1
如果您想要一个稍微有些hacky的、最小化代码行数的方法,也许您可以在每个矩阵图的末尾绘制适当数量的(0,0)点来将您的颜色序列推回到开头——这就像Mohsen Nosratinia的解决方案,但不太优雅... 假设有七种颜色需要循环使用,就像Matlab一样,您可以这样做
% number of colours in ColorOrder
nco = 7;
% plot matrix 1
plot(x1');
% work out how many empty plots are needed and plot them
nep = nco - mod(size(x1,1), nco); plot(zeros(nep,nep));
% plot matrix 2
plot(x2');
...
% cover up the coloured dots with a black one at the end
plot(0,0,'k');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接