【问题标题】:Plotting with a Specific Marker使用特定标记绘图
【发布时间】:2011-06-25 18:03:11
【问题描述】:

我想将一个由 0 和 1 组成的矩阵绘制成一个图形,这样对于每一个 1,我都有一个形状像垂直条的标记被绘制为“|”。这样当一系列 1 在同一个 x 轴上时,看起来就像一条长直线。

这个例子说明了我的意图:

给定以下矩阵:

0 0 1 1 0 1 0
0 1 0 1 1 1 0
0 1 0 1 1 1 0
1 0 0 1 1 1 0

我明白了:

【问题讨论】:

    标签: matlab plot gnuplot


    【解决方案1】:

    编辑:

    下面的解决方案虽然比目前接受的解决方案长一点,但它的优点是它创建了一个LINE 对象(如果创建的图形对象较少,UI 性能会更好)。它通过使用NaN 分隔段来工作:

    %#A = [1 1 1 ; 0 0 0 ; 1 1 1];
    A = [
        0 0 1 1 0 1 0
        0 1 0 1 1 1 0
        0 1 0 1 1 1 0
        1 0 0 1 1 1 0
    ];
    
    %# build line x/y points
    [m n] = size(A);
    [x y] = meshgrid(1:n, 1:m);    %# grid coordinates
    x(~A) = NaN;                   %# place NaNs where A is zero
    y(~A) = NaN;
    x = [x;NaN(1,n)];              %# separate columns by NaNs
    y = [y;NaN(1,n)];
    x = [x(:) x(:)]';              %'# add endpoints
    y = [y(:) y(:)+1]';            %'#
    x = x(:);                      %# linearize
    y = y(:);
    
    %# plot
    line('XData',x, 'YData',y-0.5, 'Color','k', 'LineStyle','-', 'LineWidth',4)
    set(gca, 'XGrid','on', 'Box','on', 'FontSize',8, 'LineWidth',2, ...
        'XLim',[0 n]+0.5, 'YLim',[0 m]+0.5, 'XTick',1:n, 'YTick',1:m, ...
        'YDir','reverse')
    %#set(gca, 'XTick',[], 'YTick',[])
    

    【讨论】:

    • 这个方法有两个问题: 1- 如果在任何特定的 x 轴上两个 1 之间有一个 0,则该方法将这些线连接在一起,尝试 A=[1 1 1 ; 0 0 0 ; 1 1 1] 2- 线条不以 Y 轴为中心
    • @alandalusi:第二个问题很容易解决,只需绘制y-0.5 而不是y。至于第一个,鉴于您首先给出的矩阵,我们假设每列中最多有一系列连接的1s ......无论如何,最近的编辑应该解决这两个问题。
    【解决方案2】:

    解决方案 2

    这是另一种解决方案,看起来很简单。每个数字由一条垂直线表示。全部在一个情节陈述中。

    %# create the matrix and get coordinates of 1s.
    a = logical([
    0 0 1 1 0 1 0
    0 1 0 1 1 1 0
    0 1 0 1 1 1 0
    1 0 0 1 1 1 0]);
    [r c] = find(flipud(a));
    plot([c c]',[r-0.5 r+0.5]','k-')
    xlim([min(c)-0.5 max(c)+0.5])
    set(gca,'xtick',[],'ytick',[])
    box on
    


    解决方案 1

    您也可以使用 TEXT 函数来放置 '|'特定坐标处的符号。

    [r c] = find(flipud(a));
    clf
    text(c,r,repmat('|',numel(r),1),'FontSize',70,'hor','center','vert','middle')
    xlim([min(c)-0.5 max(c)+0.5])
    ylim([min(r)-0.6 max(r)+0.4])
    set(gca,'xtick',[],'ytick',[])
    box on
    

    缺点是您必须使用字体大小和 y 轴限制来关闭线条。

    旁注:很奇怪,我不能只使用“|”没有repmat。因为这个字符实际上可以分隔不同的字符串。使用char(124) 具有相同的效果。我想知道是否有任何其他解决方法。

    【讨论】:

    • 解决方案有效,但正如您所说,我们需要解决 y 轴限制
    • @alandalusi,检查另一个。
    • +1 为简单起见,顺便说一句,调用 IND2DUB 是不必要的,你可以有:[r c] = find(flipud(a));
    【解决方案3】:

    这是一种方法,将 1 转换为显式点并在它们之间画一条线:

    B=logical([A(1,:);A;A(end,:)]);    %# A is your matrix of 1's and 0's
    
    %# create a mesh of indices
    x=1:size(B,2);
    y=0:size(A,1)+1;
    [X,Y]=meshgrid(x,y);
    
    %# plot the lines
    figure(1);clf;hold on
    arrayfun(@(i)plot(X(B(:,i),i)',Y(B(:,i),i)','color','k','linewidth',1.25),x)
    hold off 
    set(gca,'box','on','xlim',[min(x),max(x)]+[-1/2 1/2],...
    'ydir','r','ytick',[])
    

    这是你应该得到的:

    您可能可以取消 arrayfun,但如果您愿意,我会将其留给您。

    【讨论】:

    • 这个方法有 3 个问题: 1- 如果在任何特定 x 轴的两个 1 之间有一个 0,则该方法将线连接在一起,尝试 A=[1 1 1 ; 0 0 0 ; 1 1 1] 2- 在您制作的示例中,x 轴上不同点上的垂直线未连接 3- 线未以 Y 轴为中心
    猜你喜欢
    • 2019-04-26
    • 2017-12-04
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2016-07-08
    • 2016-12-10
    相关资源
    最近更新 更多