Reputation: 183
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
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.
Upvotes: 2
Views: 3226
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))])
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
Upvotes: 3