Boxplot divided by color with combined labels

조회 수: 21 (최근 30일)
Lorenzo Marucchi
Lorenzo Marucchi 2024년 10월 23일
댓글: Voss 2024년 11월 7일 1:28
I have a datasetthat I recreated with random numbers, which contains two variables with different combinations and associated Y values. I have different subjects for which I want to build boxplots.
% Unique value of 2 variables
Var1unique = ["Type 1", "Type 2", "Type 3"];
Var2unique = ["Group A" , ...
"Group B", ...
"Group C", ...
"Group D", ...
"Group E"
];
% Create the variable value of the same lenght to put in the table
Var1single = categorical(repelem(Var1unique', 5));
Var2single = categorical(repmat(Var2unique', 3, 1));
Var1 =[]; Var2 = []; Yvalue = [];
for i=1:10 % cycle over number of subjects
Var1 =[Var1; Var1single];
Var2 =[Var2; Var2single];
Yvalue = [Yvalue; rand(15,1)];
end
data = table( Var1, Var2, Yvalue);
LegendLabels = ["(A) Option A" , ...
"(B) Option B", ...
"(C) Option C", ...
"(D) Option D", ...
"(E) Option E", ...
];
AxisLabels = {"A", "B", "C", "D", "E"};
In order to create a boxplot I used the boxchart function and 'GroupByColor' property to generate the following plot. Which is pretty much similar to what I want to generate. For the sake of clarity (since not everyone can see color properly) I want to add xtick labels for individual boxplots within a group. But the boxchart function doesn't allow to add xtickslabels for single boxplots of a group as shown here.
Following this I have tired the function boxplotGroup. None of the other alternatives are precise
So I tried an alternative way to display my plots with the function boxplotGroup but it proves to be very limited since is based on boxplot() properties, which doesn't allow to change color of the BoxFaceColor (I have tried this , this and this but I cannot get it work with boxplotGroup) and use a continuous line for the whiskers.
Here are the two alternatives and the relative results.
Alternative 1:
%% ALTERNATIVE 1
plot1 = figure;
boxchart(reordercats(data.Var1, Var1unique), ...
data.Yvalue, ...
'GroupByColor', reordercats(data.Var2, Var2unique), ...
'BoxWidth',0.5);
% Assign Colors
colororder([[0 0.4470 0.7410]; ...
[0.8500 0.3250 0.0980]; ...
[0.9290 0.6940 0.1250]; ...
[0.4940 0.1840 0.5560]; ...
[0.4660 0.6740 0.1880] ...
] )
% Separate group with lines
for iDivide = 0:height(gca().XAxis.Categories)
line([iDivide+0.5, iDivide+0.5],[min(ylim),max(ylim)],'Color','black','LineStyle','--', 'LineWidth', 1)
end
set(findobj(gcf,'type','axes'),'FontName','Helvetica','FontSize',10, ...
'FontWeight','Bold', 'LineWidth', 1.5);
set(gca,'LineWidth',2, ...
'YGrid','on', ...
'GridLineWidth', 1);
l = legend([LegendLabels, '', '', '', '' ], 'Location','eastoutside');
Alternative 2:
%% Alternative 2
colorGroup = [[0 0.4470 0.7410]; ...
[0.8500 0.3250 0.0980]; ...
[0.9290 0.6940 0.1250]; ...
[0.4940 0.1840 0.5560]; ...
[0.4660 0.6740 0.1880] ...
];
colors = repmat(colorGroup, 3, 1);
% Reshape data
datacell = cell(1, numel(Var2unique));
for var2Idx = 1:numel(Var2unique)
Idx1 = (data.Var1 == Var1unique(1) & data.Var2 == Var2unique(var2Idx));
Idx2 = (data.Var1 == Var1unique(1) & data.Var2 == Var2unique(var2Idx));
Idx3 = (data.Var1 == Var1unique(3) & data.Var2 == Var2unique(var2Idx));
datacell{1,var2Idx} = [table2array(data(Idx1, 3)), table2array(data(Idx2, 3)), table2array(data(Idx3, 3))];
end
plot2 = figure;
boxplotGroup(datacell,'groupLines', true , 'interGroupSpace',2, ...
'primaryLabels', AxisLabels, ...
'secondaryLabels',{'Type 1', 'Type 2', 'Type 3'}, ...
'Colors', colorGroup, ...
'Symbol', "o");
set(gca,'LineWidth',2, ...
'YGrid','on', ...
'GridLineWidth', 1);
set(findobj(gcf,'type','axes'),'FontName','Helvetica','FontSize',10, ...
'FontWeight','Bold', 'LineWidth', 1.5);
l = legend([featureTypeLegend, '', '', '', '' ], 'Location','northwest');

채택된 답변

Voss
Voss 2024년 10월 23일
I gather that you want to have the boxes filled as in Alternative 1 and the x-ticks and labels as in Alternative 2.
See if using the option 'BoxStyle','filled' in boxplotGroup is sufficient:
% Unique value of 2 variables
Var1unique = ["Type 1", "Type 2", "Type 3"];
Var2unique = ["Group A", "Group B", "Group C", "Group D", "Group E"];
% Create the variable value of the same length to put in the table
Var1single = categorical(repelem(Var1unique.', 5));
Var2single = categorical(repmat(Var2unique.', 3, 1));
Var1 = repmat(Var1single,10,1);
Var2 = repmat(Var2single,10,1);
Yvalue = rand(150,1);
data = table( Var1, Var2, Yvalue);
LegendLabels = [ ...
"(A) Option A", ...
"(B) Option B", ...
"(C) Option C", ...
"(D) Option D", ...
"(E) Option E", ...
];
AxisLabels = {"A", "B", "C", "D", "E"};
%% Alternative 2
colorGroup = [ ...
0 0.4470 0.7410; ...
0.8500 0.3250 0.0980; ...
0.9290 0.6940 0.1250; ...
0.4940 0.1840 0.5560; ...
0.4660 0.6740 0.1880; ...
];
colors = repmat(colorGroup, 3, 1);
% Reshape data
datacell = cell(1, numel(Var2unique));
for var2Idx = 1:numel(Var2unique)
Idx1 = (data.Var1 == Var1unique(1) & data.Var2 == Var2unique(var2Idx));
Idx2 = (data.Var1 == Var1unique(1) & data.Var2 == Var2unique(var2Idx));
Idx3 = (data.Var1 == Var1unique(3) & data.Var2 == Var2unique(var2Idx));
datacell{1,var2Idx} = [table2array(data(Idx1, 3)), table2array(data(Idx2, 3)), table2array(data(Idx3, 3))];
end
plot2 = figure;
boxplotGroup(datacell,'groupLines', true , 'interGroupSpace',2, ...
'primaryLabels', AxisLabels, ...
'secondaryLabels',{'Type 1', 'Type 2', 'Type 3'}, ...
'Colors', colorGroup, ...
'Symbol', "o", 'BoxStyle','filled');
set(gca,'LineWidth',2, ...
'YGrid','on', ...
'GridLineWidth', 1);
set(findobj(gcf,'type','axes'),'FontName','Helvetica','FontSize',10, ...
'FontWeight','Bold','LineWidth', 1.5);
  댓글 수: 4
Lorenzo Marucchi
Lorenzo Marucchi 2024년 10월 26일
편집: Lorenzo Marucchi 2024년 10월 26일
Thank you @Voss, yes this was what I was looking for. I've already tired with patch but I wasn't able to get the color order right.
I would be nice to have also the whiskers in solid black line, and a coherent legend. I will figure it out and post here the solution.
Thanks Again
Voss
Voss 2024년 11월 7일 1:28
Sounds good. I look forward to seeing the completed solution.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Graphics Object Programming에 대해 자세히 알아보기

제품


릴리스

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by