Calculation with a specific marker

I would like to build a matrix of zeros and ones into a figure, such that for every 1 I find a marker in the form of a vertical bar "|". Thus, when a series of 1s is on the same x axis, the view looks like a long line.

This example illustrates my intentions:

Given the following matrix:

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 

I get:

Bar figure

+6
source share
3 answers

EDIT:

The solution below, although a little longer than currently accepted, has the advantage of creating one LINE object (UI performance is better if you create fewer graphic objects). It works using NaN to separate segments:

 %#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 [mn] = size(A); [xy] = 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',[]) 

enter image description hereenter image description here

+4
source

SOLUTION 2

Here is another solution that looks pretty simple. Each number is represented by one vertical line. All in one plot statement.

 %# 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]); [rc] = find(flipud(a)); plot([cc]',[r-0.5 r+0.5]','k-') xlim([min(c)-0.5 max(c)+0.5]) set(gca,'xtick',[],'ytick',[]) box on 

enter image description here


SOLUTION 1

Alternatively, you can use the TEXT function to place '|' character in certain coordinates.

 [rc] = 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 

The disadvantage is that you have to play with font sizes and y axis constraints to close the lines.

enter image description here

Side note . It is strange that I could not use only '|' without repmat. Because this character can actually split different lines. Using char(124) has the same effect. I wonder if there is another workaround.

+3
source

Here is one way to do this by converting 1 to explicit points and laying a line through them:

 B=logical([A(1,:);A;A(end,:)]); %# A is your matrix of 1 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',[]) 

Here is what you should get:

enter image description here

You might be done away with arrayfun , but I will leave it to you if you wish.

+1
source

Source: https://habr.com/ru/post/891355/


All Articles