plotting two types of data on one graph

17 ビュー (過去 30 日間)
Kitt
Kitt 2024 年 10 月 8 日
コメント済み: Voss 2024 年 10 月 21 日
This may not be possible but if anyone can figure it out, it's someone on here.
I have a matrix, 20 timesteps x 1000 individuals, and each element is either 1, 2, or NaN. I want to plot the number of 1 compared to 2 for each timestep.
However, I also have another vector, env, that is either 1, 2, 3, or 4 for each timestep. Is there anyway to also identify, at each timestep, not only the 1/2 count but also the env element as well?
For context, this is a patch choice model. An individual can either choose patch 1 (1) or patch 2 (2) or be dead (NaN). The environment (env) is changing between timesteps, with all combinations of patch 1 being good or bad and patch 2 being good or bad (1,2,3,4). I want to see how many individuals chose each patch and what states the patches were in at that time.
I'm envisioning something like this:
  4 件のコメント
Rahul
Rahul 2024 年 10 月 9 日
編集済み: Rahul 2024 年 10 月 9 日
Hi @Kitt, I understood that you're trying to create a grouped bar graph with custom shading for each timestep. Although, the condition for shading or background color for a timestep using " ..with all combinations of patch 1 being good or bad and patch 2 being good or bad (1,2,3,4)" doesn't seem apparent, as in how are "good" or "bad" being defined based on the 'env' vector values. I've provided a sample snippet, that could resemble your solution:
% Initialize data (example setup)
data = randi([1 2], 20, 1000); % Replace with your actual data
data(rand(20, 1000) < 0.1) = NaN; % Insert some NaN values as example
env = randi([1 4], 1, 20); % Replace with your actual env vector
figure;
hold on;
for t = 1:20
% Count choices for path 1 and path 2, ignoring NaN values
count_path1 = sum(data(t, :) == 1);
count_path2 = sum(data(t, :) == 2);
% Plot bar for the current timestep
bar(t, [count_path1, count_path2]);
% Shading based on 'env' value
if env(t) == 1
color = [0.9, 0.9, 0.9];
elseif env(t) == 2
color = [0.8, 0.8, 1];
elseif env(t) == 3
color = [1, 0.8, 0.8];
else
color = [0.8, 1, 0.8];
end
% Add shading for the current timestep
fill([t-0.5 t-0.5 t+0.5 t+0.5], [0 1000 1000 0], color, 'FaceAlpha', 0.5, 'EdgeColor', 'none');
end
legend off;
% Custom legend for shaded regions (env values)
hGray = fill(NaN, NaN, [0.9, 0.9, 0.9], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hBlue = fill(NaN, NaN, [0.8, 0.8, 1], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hRed = fill(NaN, NaN, [1, 0.8, 0.8], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hGreen = fill(NaN, NaN, [0.8, 1, 0.8], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
% Create a custom legend for the shading colors
legend([hGray, hBlue, hRed, hGreen], {'Env = 1', 'Env = 2', 'Env = 3', 'Env = 4'}, 'Location', 'Best');
xlim([0 20])
xlabel('Timestep');
ylabel('Count of Individuals');
title('Individuals Choosing Path 1 and Path 2 Over Time');
hold off;
Here, the first bar in each of the group represents choice (1) and the latter choice (2). You can modify the conditions stating "Shading based on 'env' value" as per your use-case, to change the shading colors for each timestep.
Kitt
Kitt 2024 年 10 月 9 日
This worked perfectly, thank you!
Sorry for not being more clear on the patch quality values; env =1 means that patch 1 is "good" and patch 2 is "bad", env = 2 means that patch 1 is "good" and patch 2 is "good", etc.
"good" and "bad" in these cases refer to the likelihood an individual is going to find food if they forage there. A higher chance of finding food means it's "good" and vice versa.

サインインしてコメントする。

回答 (2 件)

Rahul
Rahul 2024 年 10 月 16 日
Hi @Kitt,
I understand that you're trying to create a grouped bar graph using timestep data with custom color shading of each bar group depending on values of another given array ‘env’, where the values indicate the following conditions:
env = 1 means that patch 1 is "good" and patch 2 is "bad",
env = 2 means that patch 1 is "good" and patch 2 is "good",
env = 3 means that patch 1 is "bad" and patch 2 is "bad",
env = 4 means that patch 1 is "bad" and patch 2 is "good",
You can iterate over each timestep and count choices of path “1” and “2” for all individuals in two vectors and then shade the respective region before plotting their grouped bars on the figure. Here’s how you can structure your code:
data = randi([1 2], 20, 1000); % Replace with your actual data
data(rand(20, 1000) < 0.1) = NaN; % Insert some NaN values as example
env = randi([1 4], 1, 20); % Replace with your actual env vector
figure;
hold on;
for t = 1:20
% Count choices for path 1 and path 2, ignoring NaN values
count_path1 = sum(data(t, :) == 1);
count_path2 = sum(data(t, :) == 2);
% Shading based on 'env' value
if env(t) == 1
color = [0.9, 0.9, 0.9];
elseif env(t) == 2
color = [0.8, 0.8, 1];
elseif env(t) == 3
color = [1, 0.8, 0.8];
else
color = [0.8, 1, 0.8];
end
% Add shading for the current timestep
fill([t-0.5 t-0.5 t+0.5 t+0.5], [0 1000 1000 0], color, 'FaceAlpha', 0.5, 'EdgeColor', 'none');
% Plot bar for the current timestep
b = bar(t, [count_path1, count_path2]);
b(1).FaceColor = 'b';
b(2).FaceColor = 'r';
end
legend off;
% Custom legend for shaded regions (env values)
hGray = fill(NaN, NaN, [0.9, 0.9, 0.9], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hBlue = fill(NaN, NaN, [0.8, 0.8, 1], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hRed = fill(NaN, NaN, [1, 0.8, 0.8], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hGreen = fill(NaN, NaN, [0.8, 1, 0.8], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
% Create a custom legend for the shading colors
legend([hGray, hBlue, hRed, hGreen], {'patch 1 is "good" and patch 2 is "bad"', 'patch 1 is "good" and patch 2 is "good"', 'patch 1 is "bad" and patch 2 is "bad"', 'patch 1 is "bad" and patch 2 is "good"'});
xticks(0:20);
xlim([0 20])
xlabel('Timestep')
ylabel('Count of Individuals');
title('Individuals Choosing Path 1 and Path 2 Over Time');
hold off;
Here, the first bar in each group represents choice “1“ and the latter choice “2”. You can modify the conditions stating "Shading based on 'env' value" as per your use-case, to change the shading colors for each timestep.
For more information regarding the functions mentioned above, refer to the documentation links specified below:

Voss
Voss 2024 年 10 月 9 日
% Initialize data (example setup)
data = randi([1 2], 20, 1000); % Replace with your actual data
data(rand(20, 1000) < 0.1) = NaN; % Insert some NaN values as example
env = randi([1 4], 1, 20); % Replace with your actual env vector
N = size(data,1);
t = 1:N;
figure
hold on
% Shading based on 'env' value
colors = [ ...
0 0 1; ...
0 0.6 0 ; ...
0.6 0 0.6; ...
0 0.8 0.8; ...
];
NC = 4;
hreg = cell(1,NC);
emptyhreg = false(1,NC);
for ii = 1:NC
if ~any(env == ii)
emptyhreg(ii) = true;
continue
end
hreg{ii} = xregion(t(env==ii)+0.5*[-1;1],'FaceColor',colors(ii,:),'FaceAlpha',1);
end
% Count choices for patch 1 and patch 2, ignoring NaN values
count_patch1 = sum(data == 1, 2);
count_patch2 = sum(data == 2, 2);
hbar = bar(t,[count_patch1, count_patch2],'EdgeColor','none');
hbar(1).FaceColor = 'r';
hbar(2).FaceColor = 'y';
xlim('tight')
xticks(t)
xlabel('timestep')
ylabel('# of individuals')
h = cellfun(@(x)x(1),hreg(~emptyhreg));
s = ["good","bad"];
idx = dec2bin(circshift(NC-1:-1:0,2),2)-'0'+1;
str = join("patch "+[1 2]+" "+s(idx),"/");
str = str(~emptyhreg);
h = [h hbar];
str = [str; "went to patch "+[1;2]];
legend(h,str,'Location','NorthOutside')
  1 件のコメント
Voss
Voss 2024 年 10 月 21 日
@Kitt: If this answer worked for you, please "Accept" it. Thanks!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeData Distribution Plots についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by