How to plot discrete array with colors
조회 수: 10 (최근 30일)
I have 'nodes' which each have a status. The status of these nodes are contained in an array 'status_array' and have the values "waiting" or "busy". I would like to plot an array with colors indicating what state each node is in, for example, green = 'waiting' and red = 'busy'. This way I can visualize how the node transistion from their states. I want it to look something like this:
I tried using imagesc or bar but it doesn't look quite right.
Thanks in advance for any suggestions!
Star Strider 2023년 6월 20일
One approach —
status = randi([0 1], 1, 9) % 'Waiting' = 0, 'Busy' = 1
status = flip(status);
cv = ["g" "r"]; % Coluur Vector
xv = repmat([0 1], size(status,2), size(status,1));
yv = xv + (0:size(status,2)-1).';
% patch([xv fliplr(xv)], [yv fliplr(yv)], cv(status+1))
for k = 1:numel(status)
patch([xv(k,:) fliplr(xv(k,:))], [[1 1]*yv(k,1) [1 1]*(yv(k,2))], cv(status(k)+1))
daspect([0.1 1 1])
yt = yticks;
I could not get this to work correctly without the loop.
Askic V 2023년 6월 20일
I would also like to offer my solution. It is not so elegant comparing to @Star Strider, but it can show you how bar can be used to achieve something similar:
red = [1 0 0];
green = [0 1 0];
% Example data
data = [1; 0; 1; 0; 0; 1; 1; 0; 1];
% Adjust the width of the bars
barWidth = 0.8; % Specify the desired width of the bars
barWidthRatio = barWidth / numel(data); % Calculate the ratio of the desired width to the number of bars
h = bar(1, ones(size(data, 1), 1), 'stacked');
for i = 1:numel(data)
h(i).BarWidth = barWidthRatio;
if data(i) == 1
h(i).FaceColor = green;
h(i).FaceColor = red;
text(0.95, i, num2str(i), 'HorizontalAlignment', 'right', 'VerticalAlignment', 'bottom');
axis ij; % invert axis
ylim([0 size(data, 1)+1]);
yticks(1:size(data, 1)); % Set the y-axis tick locations
yticklabels(); % Hide the y-axis tick labels
dpb 2023년 6월 20일
편집: dpb 님. 2023년 6월 21일
I looked at the vectorized version issue a little -- it doesn't work easily for the purpose because even if you create multiple polygons, it's then a one-object patch with only a single .FaceColor property. To set the colors by face then have to set the initial color vector as a nx1x3 rgb array which is more of a pain to generate than the lookup of the color vector or 2D array.
While doable and does create the same overall effect, I think it's handier to leave it as the separate patch objects above -- although I guess once one writes the code once, even if it was harder initially, then it doesn't really matter to use...
The following works...
x=[0 1 1 0].'; y=[0 0 1 1].';
G=[0 1 0];G=reshape(G,1,1,);
R=[1 0 0];R=reshape(R,1,1,);
daspect([0.1 1 1])
prior to the cleanup of tick labels, etc., ...