【问题标题】:Change color of 2D plot line depending on 3rd value根据第三个值更改 2D 绘图线的颜色
【发布时间】:2015-10-19 12:38:26
【问题描述】:

我有一个看起来像这样的数据集

 140400 70.7850 1
 140401 70.7923 2
 140402 70.7993 3
 140403 70.8067 4
 140404 70.8139 5
 140405 70.8212 3

其中第一列对应于时间(数据点之间的一秒间隔)并将位于 x 轴上,第二列对应于距离并将位于 y 轴上。第三列是一个数字(一到五),它是运动的限定。

我想制作一个图,根据前一个数据点的数量来改变两点之间线条的颜色。例如,我希望第一个和第二个数据点之间的线是红色的,因为限定值是 1。

我看过很多关于根据强度值制作颜色滑动比例的帖子,但我只想要 5 种颜色:分别为(红色、橙色、黄色、绿色和蓝色)。

我试着做这样的事情:

plot(x,y,{'r','o','y','g','b'})

但没有运气。

关于如何解决这个问题的任何想法?尽可能不循环。

【问题讨论】:

  • 循环有什么问题?您要求恕我直言,没有循环就无法完成。
  • 假设您的矩阵存储在A:colors='rmygb'; figure; hold on; for idx = 1 : size(A,1)-1, plot(A(idx:idx+1,1), A(idx:idx+1,2), colors(A(idx,3))); end 中尝试此操作。试一试,看看它是如何运行的。顺便说一句,o 不支持作为颜色,因为o 表示圆形标记。我已经用洋红色替换了颜色。
  • 你有什么样的数据在图表上绘制 100,000 个点会有用?人们只能从图表中收集到这么多信息,而且放置更多数据点通常会使弄清楚发生了什么变得更加困难。看到 100,000 条线段可能不是很有用,使用 scatter 会给你几乎相同的信息,我不保证它会有用!
  • 如果您想要一个散点图,您可以通过[i,j]=find(A==1) 等将数据划分为五个矩阵。这将为您提供第三个值等于1 的行。然后,您可以执行scatter(x(i),y(j),'r'); hold on,然后再重复四次。
  • @rayryeng 自 Matlab 2014b 以来,感谢 Yair Altman 现在可以在没有循环的情况下完成:undocumented Matlab

标签: matlab plot colors matlab-figure colormap


【解决方案1】:

您还可以使用适用于 2014b 之前的 Matlab 版本(至少早于 2009a)的技巧来做到这一点。
但是,它永远不会像您期望的那样简单(除非您为此处的解决方案之一编写包装器,否则您可以忘记plot(x,y,{'r','o','y','g','b'}))。

诀窍是使用surface 而不是line 对象。表面受益于它们的CData 属性和许多有用的功能来利用颜色贴图和纹理。

Matlab surf 不处理一维数据,它需要一个矩阵作为输入,因此我们将通过复制每个坐标集(例如 xx=[x,x])来提供它。
不过不用担心,表面会保持像线一样薄,所以最终的结果并不难看。

%% // your data
M=[140400 70.7850 1
 140401 70.7923 2
 140402 70.7993 3
 140403 70.8067 4
 140404 70.8139 5
 140405 70.8212 3];

x = M(:,1) ; %// extract "X" column
y = M(:,2) ; %// same for "Y"
c = M(:,3) ; %// extract color index for the custom colormap

%% // define your custom colormap
custom_colormap = [
    1  0 0 ; ... %// red
    1 .5 0 ; ... %// orange
    1  1 0 ; ... %// yellow
    0  1 0 ; ... %// green
    0  0 1 ; ... %// blue
    ] ;

%% // Prepare matrix data
xx=[x x];           %// create a 2D matrix based on "X" column
yy=[y y];           %// same for Y
zz=zeros(size(xx)); %// everything in the Z=0 plane
cc =[c c] ;         %// matrix for "CData"

%// draw the surface (actually a line)
hs=surf(xx,yy,zz,cc,'EdgeColor','interp','FaceColor','none','Marker','o') ;

colormap(custom_colormap) ;     %// assign the colormap
shading flat                    %// so each line segment has a plain color
view(2) %// view(0,90)          %// set view in X-Y plane
colorbar

会得到你:


作为更一般情况的示例:

x=linspace(0,2*pi);
y=sin(x) ;

xx=[x;x];
yy=[y;y];
zz=zeros(size(xx));

hs=surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
colormap('hsv')
view(2) %// view(0,90)

将为您提供与y 值相关联的颜色的正弦波:

【讨论】:

    【解决方案2】:

    你有 Matlab R2014b 或更高版本吗?

    那么你可以使用一些undocumented features introduced by Yair Altman:

    n = 100;
    x = linspace(-10,10,n); y = x.^2;
    p = plot(x,y,'r', 'LineWidth',5);
    
    %// modified jet-colormap
    cd = [uint8(jet(n)*255) uint8(ones(n,1))].' %'
    
    drawnow
    set(p.Edge, 'ColorBinding','interpolated', 'ColorData',cd)
    

    【讨论】:

    • 哇,太棒了!有什么方法可以直接将颜色图绑定/缩放到点的 Y 值,还是我们必须手动进行查找/缩放并创建适当的 cd
    • 看起来很不幸。颜色图需要与实际数据一样多的点。
    【解决方案3】:

    我想要的效果如下(简化):

            indices(1).index  = find( data( 1 : end - 1, 3) == 1);
            indices(1).color  = [1 0 0]; 
            indices(2).index  = find( data( 1 : end - 1, 3) == 2 | ...
                                      data( 1 : end - 1, 3) == 3);
            indices(2).color  = [1 1 0];
            indices(3).index  = find( data( 1 : end - 1, 3) == 4 | ...
                                      data( 1 : end - 1, 3) == 5);
            indices(3).color  = [0 1 0];
            indices(4).index  = find( data( 1 : end - 1, 3) == 10);
            indices(4).color  = [0 0 0];
            indices(5).index  = find( data( 1 : end - 1, 3) == 15);
            indices(5).color  = [0 0 1];
    
        % Loop through the locations of the values and plot their data points
        % together (This will save time vs. plotting each line segment
        % individually.)
    
        for iii = 1 : size(indices,2)
    
            % Store locations of the value we are looking to plot
            curindex = indices(iii).index;
    
            % Get color that corresponds to that value
            color = indices(iii).color;
    
                % Create X and Y that will go into plot, This will make the line
                % segment from P1 to P2 have the color that corresponds with P1
                x = [data(curindex, 1), data(curindex + 1, 1)]';
                y = [data(curindex, 2), data(curindex + 1, 2)]';
    
                % Plot the line segments
                hold on
                plot(x,y,'Color',color,'LineWidth',lineWidth1)            
    
        end
    

    【讨论】:

      【解决方案4】:

      当绘制的两个变量的结果图是一个圆圈时,需要在z轴上加上时间。

      例如在一项实验室测试中感应电机转子速度与电转矩的关系图为:2d plot figure

      在最后一个图中,时间点绘制的方向可以是顺时针或逆时针。最后一个原因将在 z 轴上添加时间。

      % Wr vs Te
      x =  logsout.getElement( 'Wr' ).Values.Data; 
      y =  logsout.getElement( '<Te>' ).Values.Data;
      z =  logsout.getElement( '<Te>' ).Values.Time;
      % % adapt variables for use surf function
      xx = zeros( length( x ) ,2 );
      yy = zeros( length( y ) ,2 );
      zz = zeros( length( z ) ,2 );
      xx (:,1) = x; xx (:,2) = x;
      yy (:,1) = y; yy (:,2) = y;
      zz (:,1) = z; zz (:,2) = z;
      % % figure(1) 2D plot
      figure (1)
      hs = surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
      colormap('hsv')
      view(2) 
      % %
      figure(2)
      hs = surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
      colormap('hsv')
      view(3) 
      

      最后我们可以查看3d表格,发现counterwise是时间绘制的真实方向是:3d plot

      【讨论】:

        【解决方案5】:

        Scatter 可以根据值绘制颜色并显示值范围的颜色图。如果您想要连续曲线,则很难插入颜色。

        试试:

        figure
        i = 1:20;
        t = 1:20;
        c = rand(1, 20) * 10;
        scatter(i, t, [], c, 's', 'filled')
        colormap(jet)
        

        人像

        【讨论】:

        • scatter 的问题在于,在这种情况下,它只绘制点,而不是问题提到的线。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 2021-11-27
        • 1970-01-01
        • 1970-01-01
        • 2020-05-28
        • 1970-01-01
        • 2017-07-10
        相关资源
        最近更新 更多