I would like to plot a matrix of zeros and ones into a figure such that for every 1 i have a marker shaped like a vertical bar is plotted " | ". Such that when a series of 1s are on the same x axis, the look like a long straight 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:
The solution below, although a bit longer than the currently accepted one, has the advantage that it creates a single LINE object (UI performance is better if you create fewer graphics objects). It works by using NaN
to separate the 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
[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',[])
SOLUTION 2
Here is another solution, which looks quite simple. Each number represented by a single 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]);
[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
SOLUTION 1
As an alternative you can use TEXT function to place '|' symbol at certain coordinates.
[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
The drawback is that you have to play with the font size and y axis limits to close the lines.
Side note: It's weird, that I couldn't use just '|' without repmat. Because this character can actually separate different strings. Using char(124)
has the same effect. I wonder if there is any other workaround.
Here is one way of doing it by converting the 1's to explicit points and drawing a line through them:
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',[])
Here is what you should get:
You can probably do away with the arrayfun
, but I'll leave that to you if you so wish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With