How to use boxchart and GroupByColor when having a matrix?
64 次查看(过去 30 天)
显示 更早的评论
Amelie
2023-8-15
Dear all,
I am trying to use a boxchart for plotting a (10000,10) matrix, where each column represents a single box.
In other words, I would like to plot a boxchart consisting of 10 boxes and 10,000 data points.
The problem is that all Answers in the forum I have read so far are related to vectors, not matrices. All my attempts of using boxchart have resulted in an error, which states that I cannot use a matrix but vectors. Transforming the matrix into a vector is not possible. Additionally, I would like to group the 10 columns in 3 categories by assigning each box the respective color:
column [1 2 3 4 5 6 7 8 9 10]
group [A A B C C B A B C A]
color: [r r g b b g r g b r ]
However, I cannot provide a vector with values and tell Matlab to group the columns of the matrix on the basis of a specific threshold (e.g. temperature), but I have to do this manually by paper and pencil and inform Matlab which column belongs to which group myself.
I use the following code:
figure (2)
groupname={'A','A','B','C','C','B','A','B','C','A'}';
boxchart(AX.t_k,'MarkerStyle', 'none','GroupByColor', groupname); % AX.t_k = (10000,10) matrix
And I get the following error:
Error using boxchart
'GroupByColor' parameter is not supported when the sample data argument is a matrix.
Could someone tell me, how I can use boxchart when using a matrix and how I can group each column with their respective color?
Thank you very much for your help!
采纳的回答
Voss
2023-8-15
Maybe something like this:
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
colors = 'rgb';
colors = colors(findgroups(groupname));
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
boxchart(AX.t_k(:,ii),'MarkerStyle','none','BoxFaceColor',colors(ii),'XData',ii*ones(N,1))
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
23 个评论
Amelie
2023-8-15
Great, thank you very much, that was very helpful! It worked perfectly.
One more quick follow-up question for me to understand:
What is XData and ii*ones(N,1) for?
Thank you !
Voss
2023-8-15
编辑:Voss
2023-8-15
You're welcome!
ii*ones(N,1) is a 10000-by-1 column vector whose elements are all ii. As the loop iterates, ii goes from 1 to 10, so that's a column vector of 10000 1's the first time, then a column vector of 10000 2's the second time, and so on.
Including "'XData',ii*ones(N,1)" in the call to boxchart sets each respective boxchart's XData to the corresponding 10000-by-1 column vector. (XData has to be a vector the same size as the vector YData, which in this case is a column from your matrix, so that's why it's 10000-by-1.)
Setting the XData of each boxchart is necessary for the 10 different boxcharts to be located different x-locations (i.e., one boxchart at x = 1, one at x = 2, etc.). If you didn't specify that, they'd all be at x = 1 and overlapping.
Here's how it would look without specifying the XData:
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
colors = 'rgb';
colors = colors(findgroups(groupname));
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
boxchart(AX.t_k(:,ii),'MarkerStyle','none','BoxFaceColor',colors(ii))%,'XData',ii*ones(N,1))
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
Amelie
2023-8-17
Oh wow, thanks a lot for the detailed explanation ! It was very helpful, thank you !
Amelie
2023-9-13
I'm very sorry to bother you again but I have another question and cannot find the answer in this particular context in the forum.
Is it possible to reorder the boxchart by color? So that all green boxes are next to each other, red boxes are next to each other etc.
Unfortunately, the columns of the initial matrix are fixed and can't be adjusted.
Thank you very much for your help!
Voss
2023-9-13
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
colors = 'rgb';
[g,g_id] = findgroups(groupname);
order = [];
for ii = 1:numel(g_id)
order = [order find(g == ii)];
end
colors = colors(g(order));
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
boxchart(AX.t_k(:,order(ii)),'MarkerStyle','none','BoxFaceColor',colors(ii),'XData',ii*ones(N,1))
end
ax = gca();
ax.XAxis.Categories = categorical(order);
Amelie
2023-9-14
Great! It workes perfectly fine! Thank you very much for your help.
I forgot to ask: I would like to add a legend, i.e. so that in your example above the first 4 boxes in red are labeled "A" in the legend, the 3 green boxes are labeled "B" in the legend etc.
However, I failed up to now with any attempts, which are mostly based on
h1= boxchart(AX.t_k(:,1:4),'MarkerStyle','none','BoxFaceColor','r','XData',ii*ones(N,1));
h2= boxchart(AX.t_k(:,5:7),'MarkerStyle','none','BoxFaceColor','g','XData',ii*ones(N,1));
h3= boxchart(AX.t_k(:,7:10),'MarkerStyle','none','BoxFaceColor','b','XData',ii*ones(N,1));
legend([h1(1), h2(1) h2(1)], 'A', 'B', 'C');
But I haven't found another way in the forum how one can implement a legend that displayes collected groups.
If you have an idea, that would be great. But I don't want to bother you too much. You have helped me already a lot.
Voss
2023-9-14
Like this?
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
colors = 'rgb';
[g,g_id] = findgroups(groupname);
n_groups = numel(g_id);
order = [];
idx_for_legend = zeros(1,n_groups);
for ii = 1:n_groups
idx = find(g == ii);
order = [order idx];
idx_for_legend(ii) = idx(1);
end
colors = colors(g(order));
[N,M] = size(AX.t_k);
hold on
h = gobjects(1,M);
for ii = 1:M
h(order(ii)) = boxchart(AX.t_k(:,order(ii)),'MarkerStyle','none','BoxFaceColor',colors(ii),'XData',ii*ones(N,1));
end
legend(h(idx_for_legend),g_id)
ax = gca();
ax.XAxis.Categories = categorical(order);
Dan Houck
2023-10-25
How do you control the xticks and xticklabels? Say you want each group to have one tick mark and label. How would you do that?
Voss
2023-10-25
@Dan Houck: See below for how to do that in this example.
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
colors = 'rgb';
[g,g_id] = findgroups(groupname);
n_groups = numel(g_id);
order = [];
idx_for_legend = zeros(1,n_groups);
xticks = zeros(1,n_groups);
for ii = 1:n_groups
idx = find(g == ii);
order = [order idx];
idx_for_legend(ii) = idx(1);
xticks(ii) = idx((end+rem(numel(idx),2))/2);
end
colors = colors(g(order));
[N,M] = size(AX.t_k);
hold on
h = gobjects(1,M);
for ii = 1:M
h(order(ii)) = boxchart(AX.t_k(:,order(ii)),'MarkerStyle','none','BoxFaceColor',colors(ii),'XData',ii*ones(N,1));
end
legend(h(idx_for_legend),g_id)
ax = gca();
ax.XAxis.Categories = categorical(order);
ax.XTick = categorical(xticks);
ax.XTickLabels = g_id;
Voss
2024-4-3
@Amelie: Yes. Define an n_groups-by-3 matrix where each row is an RGB triplet; index that matrix by row when ordering the colors; use one row at a time when creating the boxcharts.
See below for an example.
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
% matrix of RGB triplets:
colors = [ ...
0 0.6 0; ...
0.6 0.6 0; ...
0.6 0 0.6; ...
];
% indexing by row:
colors = colors(findgroups(groupname),:);
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
% using one row of the colors matrix at a time:
boxchart(AX.t_k(:,ii),'MarkerStyle','none','BoxFaceColor',colors(ii,:),'XData',ii*ones(N,1))
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
Amelie
2024-4-19
I'm very sorry to bother you again but I have one follow-up question. Do you know if I can incorporate grids behind the boxcharts? If so, do you have an idea how to do it? The reason I ask is that I have problems to get the the grids in the background with 'Layer, 'bottom' or other commands suggested in the forum.
Many thanks !
Voss
2024-4-19
You should just be able to just use the grid function, as shown below:
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
% matrix of RGB triplets:
colors = [ ...
0 0.6 0; ...
0.6 0.6 0; ...
0.6 0 0.6; ...
];
% indexing by row:
colors = colors(findgroups(groupname),:);
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
% using one row of the colors matrix at a time:
boxchart(AX.t_k(:,ii),'MarkerStyle','none','BoxFaceColor',colors(ii,:),'XData',ii*ones(N,1))
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
grid(ax,'on')
Voss
2024-4-19
Oh, I see. I thought you wanted them to be visible through the boxchart.
To make the boxcharts obscure the grid lines, you'd have to increase the BoxFaceAlpha property of the boxcharts, which controls their opacity. Default BoxFaceAlpha for a boxchart is 0.2; here I'll change it to 1 to completely obscure whatever is behind it:
% generate some random data:
N = 10000;
M = 10;
AX = struct('t_k',zeros(N,M));
for ii = 1:M
AX.t_k(:,ii) = rand()*rand(N,1)+rand();
end
% plot 10 separate boxcharts, and color each one appropriately:
groupname = {'A','A','B','C','C','B','A','B','C','A'};
% matrix of RGB triplets:
colors = [ ...
0 0.6 0; ...
0.6 0.6 0; ...
0.6 0 0.6; ...
];
% indexing by row:
colors = colors(findgroups(groupname),:);
figure
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
% using one row of the colors matrix at a time:
boxchart(AX.t_k(:,ii), ...
'MarkerStyle','none', ...
'BoxFaceColor',colors(ii,:), ...
'XData',ii*ones(N,1), ...
'BoxFaceAlpha',1)
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
grid(ax,'on')
Unfortunately with that, as you can see, there's no longer a visual distinction between the box face and the box edge and median lines. To fix that, I'll make the BoxFaceColor lighter by changing the colors matrix, and keep the edge and median line colors as they were.
% matrix of RGB triplets:
colors = [ ...
0 1 0; ...
1 1 0; ...
1 0 1; ...
];
% indexing by row:
colors = colors(findgroups(groupname),:);
figure
[N,M] = size(AX.t_k);
hold on
for ii = 1:M
% using one row of the colors matrix at a time:
boxchart(AX.t_k(:,ii), ...
'MarkerStyle','none', ...
'BoxFaceColor',colors(ii,:), ...
'XData',ii*ones(N,1), ...
'BoxFaceAlpha',1, ...
'BoxEdgeColor',colors(ii,:)*0.6, ...
'BoxMedianLineColor',colors(ii,:)*0.6)
end
ax = gca();
ax.XAxis.Categories = categorical(1:M);
grid(ax,'on')
Voss
2024-4-20
You're welcome!
Hey, I'll take a fruit basket, sure. As long as the fruits are grouped by color.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)