Boxplot group within group

28 views (last 30 days)
Emma Jacobs
Emma Jacobs on 17 Apr 2023
Answered: Dave B on 17 Apr 2023
I'm trying to create a boxplot where I split my data into two groups and then am able to overlay a scatterplot with multiple colors. Something like this:
Here's the code I have so far with the output below, I just need to add the colors to the subgroups. Any suggestions?
PSD2 = randn(12,1);
cond1 = [1 1 1 1 1 1];
cond2 = [2 2 2 2 2 2];
cond = [cond1,cond2];
hold on
scatter(cond, PSD2(1:12,1), 'filled', 'r')
boxplot(PSD2(1:12,1), cond, 'width', 0.5)

Accepted Answer

Dave B
Dave B on 17 Apr 2023
To choose colors for your overlay, you can create multiple Scatter objects, or you can create one scatter object with multiple colors.
Here's an example, I'm taking some liberties with your code to make it a little easier to see.
First, I'm going to pick a few more random numbers (so that there's a little more to look at) and I'll seed the random number generator so that the results are reproducible.
rng(0)
psd = [randn(50,1);randn(50,1)+2];
cond1 = ones(50,1);
cond2 = ones(50,1)*2;
cond = [cond1;cond2];
Next, I'll use boxchart instead of boxplot. The boxchart interface is a little more modern, and I think it has better looking visuals. Because we want the scatter to be an overlay, I'll plot the boxchart first.
boxchart(cond,psd)
To simulate the color grouping, I'll just take rounded absolute values, which will make some discrete groups:
clrs = round(abs(psd));
Now I'll add a scatter. The x and y correspond to the condition and y values, I'll let MATLAB choose the default size, and I'll specify the colors as the group id above. I'll add a little random jitter in the x direction (to look like your sketch).
hold on
scatter(cond, psd, [], clrs, 'filled', 'XJitter', 'rand', 'XJitterWidth', .2)
Scatter will choose colors from the current colormap, and the axes will have color limits that tightly fit the data. That's a little awkward here because colormaps are designed for continuous data but the color axis is really discrete. I can work around that by tweaking the color limits and changing the colormap to use lines. I'll add a colorbar to show what the colors mean
clim([min(clrs)-.5 max(clrs)+.5])
colormap(lines(diff(clim)))
colorbar
Personally, I'm not super fond of this approach for indicating color. It's nice to be able to caputre everything with a single Scatter object (specifying the color argument), but it's using a continuous coloring system for a discrete set of groups. Here's an alternate approach, with a loop, that creates a scatter object for each group. The graphic comes out about the same (you'll see different jitter), but it can be readily labeled with a legend instead of a colorbar.
figure
boxchart(cond,psd,'DisplayName','Box')
groups = round(abs(psd));
hold on
grp=unique(groups);
for i = 1:numel(grp)
scatter(cond(groups==grp(i)), psd(groups==grp(i)), 'filled', ...
'XJitter', 'rand', 'XJitterWidth', .2, 'DisplayName', string(grp(i)), ...
'SeriesIndex', i)
end
legend('Location','NorthEastOutside')

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!