Matlab 向楼梯踏步打印的线条添加颜色

Matlab 向楼梯踏步打印的线条添加颜色,matlab,plot,Matlab,Plot,我正在尝试绘制一张催眠图(显示睡眠周期的图表),目前正在使用stairstep函数来绘制它。下面是一个示例数据,因为我正在处理的数据非常庞大: X = linspace(0,4*pi,10); Y = sin(X); stairs(X,Y) 如何使y轴上每个记号/分数的线具有唯一的颜色?看起来是这样的: 使用if语句并将其分块。检查Y轴的条件是否在某个范围内,如果它在该范围内,请使用所需的颜色将其绘制在该范围内。例如,如果(y>1)绘制(x,y,'r'),否则如果(y)绘制(x,y,'b')。

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

X = linspace(0,4*pi,10);
Y = sin(X);
stairs(X,Y)
如何使y轴上每个记号/分数的线具有唯一的颜色?看起来是这样的:

使用if语句并将其分块。检查Y轴的条件是否在某个范围内,如果它在该范围内,请使用所需的颜色将其绘制在该范围内。例如,如果(y>1)绘制(x,y,'r'),否则如果(y)绘制(x,y,'b')。希望对您有所帮助

下面的代码没有那么有效,但运行良好

基本上,它从左到右一行一行地画

首先,生成样本数据

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)]);

下面是结果

一种方法是将数据分离到尽可能多的数据集中,只要数据集有平面,然后用所需的属性绘制所有这些数据集

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

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

步骤1:重新创建类似“楼梯”的数据集

然后,通过重组
X
Y
的元素,我们可以获得与
楼梯
功能完全相同的输出:

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) ;


步骤2:使用
补丁
可以指定级别颜色

面片
对象有许多选项用于为面、顶点和边着色。默认的
面片
对象将尝试通过连接第一个点和最后一个点来关闭坐标中给定的任何轮廓。要覆盖此行为,只需将
NaN
元素添加到坐标集的末尾,
patch
将生成一条简单的线(但所有着色选项都保留!)

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

%% 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

是的。。。现在我们的水平仪有了相应的颜色。。。但是等等,那些讨厌的垂直线仍然存在,并且污染了图表。我们能不能换一种颜色?不幸的是,没有。但是,没有担心,仍然有办法让它们完全消失


步骤3:使用
NaN
禁用某些段

那些
NaN
将再次前来救援。使用
NaN
定义的任何段都不会通过图形功能进行打印(无论是
plot
patch
surf
还是任何其他…)。因此,我们可以做的是再次在原始坐标集中交错一些
NaN
,以便只渲染水平线。创建面片后,我们可以构建第二个“相反”坐标集,其中只有垂直线可见。对于第二组,因为我们不需要花哨的色彩,我们可以简单地用
绘图
来渲染它们(但是如果你想给它们涂上不同的颜色,你也可以为此构建一个特定的补丁)


在上一个示例中,我使用了
hsv
colormap,因为您的示例似乎表明您不需要逐渐增加颜色。您还可以为每个级别定义一个定制的颜色映射(但这将是另一个主题,如果您在堆栈溢出中搜索它,已经讨论了很多次)


祝R.E.M.睡眠愉快

您必须隔离不同的区域,并将其绘制为不同的图形实体。
楼梯
图形对象本身并不能提供您所要求的可能性。感谢您的贡献,但这只是一个如何接近它的提示,而不是一个完整的答案。它应该在原始问题的评论中发布。很抱歉,由于声誉不好,我不能这样做。我不得不在答案部分贴出提示。我会从下次开始照顾你的,谢谢!你真是个天才!
%% 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))