Shraddha
Shraddha

Reputation: 183

Single boxplot for multiple group comparison

Here is the sample code that i used to compare two groups with random mean and standard deviation. However, i want to plot both groups in a single box in the box plot as shown in the attached figure where x-axis is group 1 and y-axis is group 2. I could not find any code doing this. Can some one please help me with this?

    clc 
clear 

x=[rand(1,10) rand(1,10) rand(1,10) rand(1,10) rand(1,10) rand(1,10)]; 
n=10 ; xx=([1:6])'; % example 
r=repmat(xx,1,n)'; 
g=r(:)'; 


positions = [1 2 3 4 5 6 ]; 
h=boxplot(x,g, 'positions', positions); 
set(h,'linewidth',2) 

set(gca,'xtick',[mean(positions(1:2)) mean(positions(3:4)) mean(positions(5:6)) ]) 
set(gca,'xticklabel',{'exp1','exp2','exp3'},'Fontsize',28) 

color = ['c', 'y', 'c', 'y','c', 'y']; 
h = findobj(gca,'Tag','Box'); 
for j=1:length(h) 
patch(get(h(j),'XData'),get(h(j),'YData'),color(j),'FaceAlpha',.5); 
end 

enter image description here

now i want yellow and blue for exp1 in one box as shown below.. similarly for exp2 and exp3 so on.. so 3 boxes in one boxplot..Ideally this should work for any number of experiments.

enter image description here

Upvotes: 2

Views: 3226

Answers (1)

EBH
EBH

Reputation: 10440

For a single two-sided boxplot, we can use the 'Orientation' property, and overlay 2 boxplots one above the other:

x = [1 2 3 4 5 6 7 1 2 3 4 5 6 7];
group = [1,1,1,1,1,1,1,2,2,2,2,2,2,2];
% we need the precntiles of the groups so the boxes will overlap.
% on each boxplot we set the width to the other boxplot hight:
p1 = prctile(x(group==1),[25 75]);
p2 = prctile(x(group==2),[25 75]);
ax = axes;
% first group is vertical:
boxplot(x(group==2),'Positions',mean(x(group==1)),...
    'Orientation','vertical','Widths',p1(2)-p1(1),'Colors','r');
lims1 = axis;
hold on
% secound group is horizontal:
boxplot(x(group==1),'Positions',mean(x(group==2)),...
    'Orientation','horizontal','Widths',p2(2)-p2(1),'Colors','k');
% the values of the axis are no longer relevant, since they have two
% different meanings, depend on the group. So we hide them.
ax.XAxis.Visible = 'off';
ax.YAxis.Visible = 'off';
hold off
lims2 = axis;
% because each axis represent to different things, we make sure we see
% everything:
axis([max(lims1(1),lims2(1)),...
    min(lims1(2),lims2(2)),...
    min(lims1(3),lims2(3)),...
    max(lims1(4),lims2(4))])

two-sided box-plots

To create multiple two-sided box-plots you need to use an axes for each experiment:

x = rand(10,6); 
nsp = floor(size(x,2)/2); % the number of subplots
meanx = mean(x);
% we need the precntiles of the groups so the boxes will overlap.
% on each boxplot we set the width to the other boxplot hight:
width = range(prctile(x,[25; 75]));
main_ax = axes; % create a tmporary axes
% we get the measurements of the ploting area:
pos = main_ax.Position;
% and divide it to our data:
axwidth = pos(3)/nsp; % the width of each group
% the bottom left corner of each group:
corner = linspace(pos(1),pos(3)+pos(1),nsp+1);
clf % clear the area!
% now we plot each pair of boxplot on a different subplot:
for k = 1:2:size(x,2)
    ax = axes('Position',[corner((k+1)/2) pos(2) axwidth pos(4)]);
    hold on
    % first group is vertical:
    boxplot(x(:,k),'Positions',meanx(k+1),...
        'Orientation','vertical','Widths',width(k+1),'Colors','r');
    % secound group is horizontal:
    boxplot(x(:,k+1),'Positions',meanx(k),...
        'Orientation','horizontal','Widths',width(k),'Colors','k');
    % the values of the y-axis are no longer relevant, since they have two
    % different meanings, depend on the group. So we hide them.
    ax.YAxis.Visible = 'off';
    % we use the x-axis to label the pairs of boxplots:
    ax.XAxis.TickLabels = ['Exp ' num2str((k+1)/2)];
    % because each axis represent to different things, we make sure we see
    % everything:
    minx = min(min(x(:,k:k+1)))*0.1;
    maxx = max(max(x(:,k:k+1)))*1.1;
    axis ([minx maxx minx maxx])
    hold off
    box off
    % set the locations to the exact same place:
    bx = findobj(ax,'tag','Box'); % get the boxes
    posXdif = bx(2).XData(1)-bx(1).XData(1); % get the horizontal difference
    posYdif = bx(2).YData(1)-bx(1).YData(1); % get the vertical difference
    bx2Xdata = get(ax.Children(2).Children,{'XData'}); % get all X-data of box 2
    bx2Ydata = get(ax.Children(2).Children,{'YData'}); % get all Y-data of box 2
    % substruct horizontal difference X-data:
    set(ax.Children(2).Children,{'XData'},... 
        cellfun(@(x) x-posXdif,bx2Xdata,'UniformOutput',false))
    % substruct vertical difference Y-data:
    set(ax.Children(2).Children,{'YData'},...
        cellfun(@(y) y-posYdif,bx2Ydata,'UniformOutput',false))
end

multiple two-sided box-plots

Upvotes: 3

Related Questions