Boxplot divided by color with combined labels

78 views (last 30 days)
Lorenzo Marucchi
Lorenzo Marucchi on 23 Oct 2024 at 15:27
Commented: Voss on 7 Nov 2024 at 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');

Accepted Answer

Voss
Voss on 23 Oct 2024 at 16:30
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 Comments
Lorenzo Marucchi
Lorenzo Marucchi on 26 Oct 2024 at 23:52
Edited: Lorenzo Marucchi on 26 Oct 2024 at 23:53
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 on 7 Nov 2024 at 1:28
Sounds good. I look forward to seeing the completed solution.

Sign in to comment.

More Answers (0)

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!