为阶梯阶段的线条添加颜色

时间:2016-08-09 06:33:53

标签: matlab plot

我正在尝试绘制一个睡眠图(显示睡眠周期的图表),并且我正在使用stairstep函数绘制它。下面是一个示例数据,因为我正在使用的数据非常庞大:

X = linspace(0,4*pi,10);
Y = sin(X);
stairs(X,Y)

如何使y轴上每个刻度/得分的线条具有独特的颜色?看起来像这样: enter image description here

3 个答案:

答案 0 :(得分:1)

下面的代码效率不高,但效果很好。

基本上,它从左到右逐行绘制。

首先,生成样本数据

num_stage = 6;

% generate sample point
x = linspace(0,1,1000)';
% generate its stage
y = round((sin(pi*x)+1)*(num_stage-1)/2)/(num_stage-1);

stage = unique(y); % find value of each stage

color_sample = rand(num_stage,3); % set color sample

然后我们可以像这样画画

idx = find([1;diff(y)]);     % find stage change
idx(end+1) = length(x)+1;      % add last point

% display routine
figure;

% left end stage
k = 1;

% find current stage level
c = find(stage == y(idx(k)));

% plot bold line
plot(x([idx(k),idx(k+1)-1]),y(idx(k))*ones(2,1),'color',color_sample(c,:),'linewidth',5);
hold on;
for k = 2 : length(idx)-1
    % find current stage level
    c = find(stage == y(idx(k)));

    % plot dashed line from left stage to current stage
    plot(x([idx(k)-1,idx(k)]),[y(idx(k-1));y(idx(k))],'--','color',[0.7,0.7,0.7]);

    % plot bold line for current stage with specified color
    plot(x([idx(k),idx(k+1)-1]),y(idx(k))*ones(2,1),'color',color_sample(c,:),'linewidth',5);
end

% set x-axis
set(gca,'xlim',[x(1),x(end)]);

以下是结果enter image description here

答案 1 :(得分:1)

一种方法是将数据分成与平坦级别一样多的数据集,然后用所需的属性绘制所有这些数据集。

但是有一种方法可以将原始数据集保持为一个整体。如果我们考虑您的初始示例数据:

X = linspace(0,4*pi,10);
Y = sin(X);

第1步:重新创建一个"楼梯"像数据集

然后通过重新组合XY的元素,我们可以获得与stairs函数完全相同的输出:

x = reshape( [X;X], 1,[] ); x(1) = [] ;   % duplicate each element, remove the first one
y = reshape( [Y;Y], 1,[] ); y(end) = [] ; % duplicate each element, remove the lastone
hp = plot(x,y) ;

simple stair plot

第2步:使用patch指定级别颜色

patch对象有很多用于着色面,顶点和边的选项。默认的patch对象将尝试关闭通过连接第一个和最后一个点在坐标中给出的任何配置文件。要覆盖此行为,您只需要在坐标集的末尾添加NaN元素,patch将生成一条简单的行(但所有着色选项仍然存在!)。

要确定我们需要多少级别和颜色,我们使用函数unique。这将告诉我们数据中存在多少个唯一级别,并且我们还可以将每个级别与指向颜色映射的索引相关联。

%% Basic level colored line patch
% create profile for patch object 
x = reshape([X;X],1,[]); x(1) = [] ;   % same as above to get a "stairs" shape
y = reshape([Y;Y],1,[]); y(end) = [] ; % idem
xp = [x,NaN] ; % add NaN in last position so the patch does not close the profile
yp = [y,NaN];  % idem

% prepare colour informations
[uy,~,colidx] = unique(Y) ;     
ncolor = length(uy) ;           % Number of unique level
colormap(hsv(ncolor))           % assign a colormap with this number of color

% create the color matrix wich will be sent to the patch object
% same method of interleaving than for the X and Y coordinates
cd = reshape([colidx.';colidx.'],1,[]); 

hp = patch(xp,yp,cd,'EdgeColor','interp','LineWidth',2) ;
colorbar

colored patch line

是的! ...现在我们的平坦水平有一个与它们对应的颜色......但是等等,那些讨厌的垂直线仍然存在并污染图形。我们可以用不同的方式给它们上色吗?很不幸的是,不行。不过不用担心,仍然有办法让它们完全消失......

第3步:使用NaN停用某些细分

那些NaN将再次拯救。使用NaN定义的任何细分都不会由图形函数绘制(无论是plotpatchsurf还是其他任何细分......)。所以我们可以做的是再次在原始坐标集中交错一些NaN,这样只会渲染水平行。创建补丁后,我们可以构建第二个#34;对立的坐标集,其中只有垂直线可见。对于第二组,由于我们不需要花哨的着色,我们可以使用plot简单地渲染它们(但是如果你想要对它们进行不同的着色,你也可以为它构建一个特定的补丁)。

%% invisible vertical line patch + dashed vertical lines
% prepare profile points, interleaving NaN between each pair
vnan = NaN(size(X)) ;
xp = reshape([X;vnan;X],1,[]); xp([1:2 end]) = [] ;
yp = reshape([Y;Y;vnan],1,[]); yp(end-2:end) = [] ;

% prepare the vertical lines, same method but we interleave the NaN at one
% element offset
xv = reshape([X;X;vnan],1,[]); xv([1:3 end]) = [] ;
yv = reshape([Y;vnan;Y],1,[]); yv([1:2 end-1:end]) = [] ;

% prepare colormap and color matrix (same method than above)
[uy,~,colidx] = unique(Y) ;     
ncolor = length(uy) ;           % Number of unique level
colormap(hsv(ncolor))           % assign a colormap with this number of color

% create the color matrix wich will be sent to the patch object
% same method of interleaving than for the X and Y coordinates
cd = reshape([colidx.';colidx.';vnan],1,[]); cd(end-2:end) = [] ;

% draw the patch (without vertical lines)
hp = patch(xp,yp,cd,'EdgeColor','flat','LineWidth',2) ;
% add the vertical dotted lines
hold on
hv = plot(xv,yv,':k') ;

% add a label centered colorbar
colorbar('Ticks',((1:ncolor)+.5)*ncolor/(ncolor+1),'TickLabels',sprintf('level %02d\n',1:ncolor))

flat coloured levels

我在最后一个示例中使用了hsv色彩映射,因为您的示例似乎表明您不需要逐渐进展颜色。您还可以使用每个级别所需的确切颜色定义自定义色彩映射(,但这将是另一个主题,如果您在Stack Overflow 上搜索它,则已经多次覆盖)。

快乐的R.E.M.睡觉!

答案 2 :(得分:0)

使用if语句并将其除以块。检查Y轴的标准是否在一定范围内,如果它在该范围内,则使用您想要的颜色将其绘制在那里。例如,如果(y> 1)绘制(x,y,'r'),则if(y some range)plot(x,y,'b')。希望它有所帮助