Box charts move positions when applying the colour function

7 views (last 30 days)
Hi
I am trying to code a funtion to assign a clour to the box plots based on the value in CB5_16B_FilteredData.P_Ps_S. I have ran the code without adding on the colour function and all box plots align with the x-axis tital. however as soon as i plot this 'GroupByColor', cgroupdata); it moves the box plots either to the left or right of the axis based on if it is P, Ps, or S
I have includedmy current code. there are a few filters on the code currently where i first filter by sample. No then by mineral type and lastly P_Ps_S. I have asked chatGPT but kinda failing with it. i like the look of the first graph i just want to change the colours.
All help is welcome
%% Box and Whisker plot Grouped by Min Type
% close all
% Input data as a table called AllFluidinclusiondata
% Filter for 'CB5_16B'
CB5_16B_FilteredData = AllFluidinclusiondata(strcmp(AllFluidinclusiondata.Sample_No, 'CB5_16B'), :);
% Ensure 'Min_Type' and 'P_Ps_S' are categorical for proper grouping
CB5_16B_FilteredData.Min_Type = categorical(CB5_16B_FilteredData.Min_Type, {'Cst', 'Qtz'}, 'Ordinal', true);
CB5_16B_FilteredData.P_Ps_S = categorical(CB5_16B_FilteredData.P_Ps_S, {'P', 'Ps', 'S'}, 'Ordinal', true);
% Sort data first by 'Min_Type' and then by 'P_Ps_S'
CB5_16B_FilteredData = sortrows(CB5_16B_FilteredData, {'Min_Type', 'P_Ps_S'});
% Create group labels by combining 'Min_Type' and 'P_Ps_S'
groupLabels = strcat(string(CB5_16B_FilteredData.Min_Type), '(', string(CB5_16B_FilteredData.P_Ps_S), ')');
% Ensure groupLabels is a categorical array
groupLabels = categorical(groupLabels);
% Count the number of samples in each group
[groupCounts, groupNames] = groupcounts(groupLabels);
% Extract data for box plots
THValues = CB5_16B_FilteredData.TH; % Replace 'TH' with your numeric column for Th data
SalinityValues = CB5_16B_FilteredData.Salinity_Cla; % Replace 'Salinity_Cla' with your numeric column for salinity data
% Create a color grouping vector based on 'P_Ps_S' values
cgroupdata = CB5_16B_FilteredData.P_Ps_S;
% Plot Setup --------------------
figure;
set(gcf, 'Color', 'w'); % Set background to white
t = tiledlayout(2, 1); % Create a 2-row tiled layout
t.TileSpacing = 'Compact';
t.Padding = 'Compact';
% Top Plot: Th Data (Boxchart)
nexttile;
boxchart(groupLabels, THValues, ... 'GroupByColor', cgroupdata);
title('CB5-16B Microthermometry Data', 'FontSize', 15, 'FontWeight', 'bold');
ylabel('TH (°C)', 'FontSize', 12);
ylim([0 450]);
grid off; % Ensure grid is on
% Add counts below X-axis labels
ax1 = gca;
ax1.XAxis.TickLength = [0 0]; % Remove tick marks from the X-axis
ax1.FontSize = 11; % Increase font size of X-axis labels
countsStr = compose('(%d)', groupCounts); % Create strings for counts
% Calculate position for counts
xLocations = 1:length(groupNames); % Get X locations for each group
yOffset = ax1.YLim(1) - 25; % Set a fixed offset below the X-axis
for i = 1:length(xLocations)
text(xLocations(i), yOffset, countsStr{i}, ...
'HorizontalAlignment', 'center', 'VerticalAlignment', 'top', 'FontSize', 10);
end
% Adjust X-label to avoid overlap
%xlabel('\newlineFluid Inclusion Population', 'FontSize', 12, 'FontWeight', 'bold');
% Bottom Plot: Salinity Data (Boxchart)
nexttile;
boxchart(groupLabels, SalinityValues, 'GroupByColor', cgroupdata);
xlabel('\newlineFluid Inclusion Population', 'FontSize', 1); % Add spacing using \newline
ylabel('Salinity (W% NaCl)', 'FontSize', 12);
ylim([0 25]);
grid off; % Ensure grid is on
% Add counts below X-axis labels
ax2 = gca;
ax2.XAxis.TickLength = [0 0]; % Remove tick marks from the X-axis
ax2.FontSize = 11; % Increase font size of X-axis labels
% Calculate position for counts
yOffset2 = ax2.YLim(1) - 1.5; % Set a fixed offset below the X-axis
for i = 1:length(xLocations)
text(xLocations(i), yOffset2, countsStr{i}, ...
'HorizontalAlignment', 'center', 'VerticalAlignment', 'top', 'FontSize', 10);
end
% Ensure the box appears on all four sides of each boxplot
ax1.Box = 'on';
ax2.Box = 'on';

Answers (1)

Voss
Voss on 10 Dec 2024
First I'll construct a table T similar to your table CB5_16B_FilteredData (except without the 'Salinity_Cla' column because for simplicity I'm only going to create boxcharts based on 'TH'):
N = 100;
tmp = {'Cst';'Qtz'};
Min_Type = tmp(randi(numel(tmp),N,1));
tmp = {'P';'Ps';'S'};
P_Ps_S = tmp(randi(numel(tmp),N,1));
TH = 150+300*rand(N,1);
T = table(Min_Type,P_Ps_S,TH);
Your data doesn't appear to have any entries where Min_Type is 'Qtz' and P_Ps_S is 'Ps', so I remove those from my table too:
idx = strcmp(Min_Type,'Qtz') & strcmp(P_Ps_S,'Ps');
T(idx,:) = [];
disp(T);
Min_Type P_Ps_S TH ________ ______ ______ {'Cst'} {'S' } 296.99 {'Cst'} {'S' } 260.35 {'Qtz'} {'P' } 191.01 {'Cst'} {'S' } 445.1 {'Cst'} {'P' } 236.53 {'Qtz'} {'P' } 416.09 {'Cst'} {'Ps'} 330.18 {'Cst'} {'Ps'} 197.54 {'Qtz'} {'S' } 256.65 {'Cst'} {'Ps'} 190.6 {'Cst'} {'P' } 314.3 {'Qtz'} {'P' } 428.09 {'Cst'} {'Ps'} 358.27 {'Cst'} {'P' } 294.65 {'Qtz'} {'P' } 319.07 {'Cst'} {'P' } 247.02 {'Qtz'} {'S' } 158.64 {'Cst'} {'S' } 362.64 {'Cst'} {'P' } 302.28 {'Cst'} {'P' } 183.1 {'Cst'} {'S' } 267.95 {'Cst'} {'P' } 358.63 {'Cst'} {'P' } 332.93 {'Cst'} {'P' } 172.79 {'Cst'} {'S' } 268.74 {'Qtz'} {'P' } 342.84 {'Qtz'} {'S' } 331.34 {'Qtz'} {'P' } 442.02 {'Qtz'} {'S' } 231.49 {'Qtz'} {'S' } 361.02 {'Cst'} {'S' } 195.75 {'Cst'} {'S' } 167.35 {'Cst'} {'P' } 325.07 {'Cst'} {'S' } 216.51 {'Cst'} {'Ps'} 349.79 {'Qtz'} {'S' } 355.07 {'Cst'} {'S' } 238 {'Qtz'} {'S' } 292.34 {'Qtz'} {'P' } 414.38 {'Qtz'} {'P' } 351.03 {'Cst'} {'Ps'} 182.48 {'Cst'} {'S' } 181.62 {'Cst'} {'Ps'} 300.25 {'Qtz'} {'S' } 305.35 {'Cst'} {'Ps'} 273.51 {'Cst'} {'P' } 249.09 {'Cst'} {'Ps'} 237.62 {'Cst'} {'S' } 170.46 {'Qtz'} {'S' } 280.3 {'Cst'} {'S' } 414.86 {'Qtz'} {'S' } 222.67 {'Cst'} {'Ps'} 314.12 {'Qtz'} {'S' } 246.32 {'Cst'} {'S' } 405.03 {'Cst'} {'P' } 301.82 {'Cst'} {'Ps'} 169.21 {'Cst'} {'P' } 313.48 {'Cst'} {'P' } 235.36 {'Cst'} {'Ps'} 253.67 {'Qtz'} {'P' } 389.7 {'Cst'} {'Ps'} 242.21 {'Qtz'} {'S' } 412.17 {'Cst'} {'S' } 321.76 {'Cst'} {'S' } 275.11 {'Qtz'} {'S' } 215.79 {'Cst'} {'Ps'} 324.34 {'Qtz'} {'P' } 207.79 {'Qtz'} {'S' } 226.51 {'Cst'} {'P' } 371.27 {'Qtz'} {'S' } 256.11 {'Cst'} {'Ps'} 221.15 {'Qtz'} {'P' } 404.78 {'Qtz'} {'P' } 306.57 {'Cst'} {'Ps'} 422.91 {'Cst'} {'S' } 208.63 {'Cst'} {'Ps'} 160.81 {'Qtz'} {'S' } 361.11 {'Cst'} {'S' } 190.71 {'Cst'} {'Ps'} 424.38 {'Qtz'} {'S' } 181.12 {'Cst'} {'P' } 330.92 {'Qtz'} {'P' } 248.26 {'Qtz'} {'S' } 411.34 {'Cst'} {'Ps'} 404.29 {'Qtz'} {'P' } 215.99 {'Cst'} {'S' } 419.91 {'Cst'} {'Ps'} 389.18 {'Qtz'} {'P' } 377.63 {'Cst'} {'S' } 447.89 {'Cst'} {'S' } 251.77
The next part is the same as your code to prepare for creating the boxcharts:
% Ensure 'Min_Type' and 'P_Ps_S' are categorical for proper grouping
T.Min_Type = categorical(T.Min_Type, {'Cst', 'Qtz'}, 'Ordinal', true);
T.P_Ps_S = categorical(T.P_Ps_S, {'P', 'Ps', 'S'}, 'Ordinal', true);
% Sort data first by 'Min_Type' and then by 'P_Ps_S'
T = sortrows(T, {'Min_Type', 'P_Ps_S'});
% Create group labels by combining 'Min_Type' and 'P_Ps_S'
% Ensure groupLabels is a categorical array
groupLabels = categorical(strcat(string(T.Min_Type), '(', string(T.P_Ps_S), ')'));
% Extract data for box plots
THValues = T.TH; % Replace 'TH' with your numeric column for Th data
% Create a color grouping vector based on 'P_Ps_S' values
cgroupdata = T.P_Ps_S;
Now, I'll create three plots, with the first two being the same as your two TH plots (i.e., the first without and the second with 'GroupByColor', to illustrate that the problem is reproduced), and the third plot showing one way to work around the problem.
figure('Position',[10 10 700 800])
tiledlayout(3,1)
nexttile()
boxchart(groupLabels, THValues);
title('No Color Variation')
nexttile()
boxchart(groupLabels, THValues, 'GroupByColor', cgroupdata);
title('Using "GroupByColor"')
nexttile()
hold on
C = categories(groupLabels);
NC = numel(C);
colors = gca().ColorOrder;
[~,idx] = ismember(cgroupdata,categories(cgroupdata));
colors = colors(idx,:);
for ii = 1:NC
tmp = groupLabels == C(ii);
boxchart(groupLabels(tmp), THValues(tmp), 'BoxFaceColor', colors(find(tmp,1),:))
end
title('Ungrouped, Manual Coloring')
  1 Comment
kiara Brooksby
kiara Brooksby on 22 Dec 2024 at 16:55
HI thanks for this - ive been wrapped up in other work but this looks like it will do me wonders

Sign in to comment.

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!