分层分组的箱图

时间:2016-09-26 16:47:00

标签: matlab plot matlab-figure boxplot

我想绘制一个包含两组数据的箱线图进行比较。我愿意使用Hierarchically grouped boxplot。我可以使用这个函数绘制一组我的数据。我想知道如何使用此功能将两组数据绘制在一起。我手工绘制了第二组红色数据,以显示我想要绘制的内容!

我的问题是我不能在hold on的一个图表上放置两组数据。

1 个答案:

答案 0 :(得分:2)

嗯,这不是您要求的,并且不使用函数hierarchicalBoxplot,但它可能是一种解决方法。我使用MATLAB示例数据演示它:

load carsmall
% cleaning the data a little
Origin = categorical(cellstr(Origin));
MPG(Origin=='Italy') = [];
Origin(Origin=='Italy') = [];
% this part is just for readability:
data1 = MPG;
groups1 = Origin;
data2 = MPG*3;
groups2 = Origin;
% And we start:
% =============
% we need a wider figure, with a white background:
figure('Color',[1 1 1],'Position',[178 457 1114 521])
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:
group_number = 6;
width = pos(3)/group_number; % the width of each group
% the bottom left corner of each group:
corner = linspace(pos(1),pos(3)+pos(1),group_number+1);
clf % clear the area!
% Now we plot everything in a loop:
for k = 1:group_number
    % create a different axes for each group:
    ax = axes;
    boxplot(ax,data1,groups1); % plot the first set
    hold on
    boxplot(ax,data2,groups2) % plot the second set
    % set the ylim to include all data:
    ax.YLim = [min([data1; data2])-5 max([data1; data2])+10];
    ax.XTickLabelRotation = 90; % rotate xlables if needed
    box off
    if k == 1 
        ylabel('Miles per Gallon (MPG)') % only for the most right axes 
    else
        ax.YTick = [];
    end
    xlabel(['Group ' num2str(k)])
    ax.Position = [corner(k) 0.2 width 0.7];
end
% and finally we place the title:
main_ax = axes('Position',[corner(1) 0.11 width*group_number 0.815]);
title('Miles per Gallon by Vehicle Origin')
axis off

% and this will color the data:
f = gcf;
colors = [1 0 0;0 0 1]; % red and blue
for g = 2:numel(f.Children)
    for k = 1:numel(f.Children(g).Children(1).Children)
        f.Children(g).Children(1).Children(k).Color = colors(1,:);
        f.Children(g).Children(1).Children(k).MarkerEdgeColor = colors(1,:);
        f.Children(g).Children(2).Children(k).Color = colors(2,:);
        f.Children(g).Children(2).Children(k).MarkerEdgeColor = colors(2,:);
    end
end

所有这些程序都给出了:

multi_boxplot

可能需要进行一些最后的调整,但这是从一开始的事情;)

修改

对于并排视图,您可以将所有组一起绘制,只需移动x-ticks:

% Making some data:
% MAKE SURE YOU UNDERSTAND HOW THE DATA IS ARRANGED WITHIN THE GRAPH
years = 6; % try to change this number
groups = 5; % try to change this number
data1 = rand(100,years);
data2 = rand(100,years)+0.3;
groups1 = randi(groups,100,1)*2-1; % groups 1 3 5 7 9
groups2 = randi(groups,100,1)*2; % groups 2 4 6 8 10
legendEntries = {'A' 'B'};
colors = [1 0 0;0 0 1]; % red and blue

% And we start:
% =============
% we need a wider figure, with a white background:
figure('Color',[1 1 1],'Position',[178 457 1400 521])
main_ax = axes; % create a temporary axes
% we get the measurements of the plotting area:
pos = main_ax.Position;
% and divide it to our data:
width = pos(3)/years; % the width of each group
% the bottom left corner of each group:
corner = linspace(pos(1),pos(3)+pos(1),years+1);
clf % clear the area!
% Now we plot everything in a loop:
for k = 1:years
    % create a different axes for each group:
    ax = axes;
    boxplot(ax,[data1(:,k); data2(:,k)],[groups1; groups2]);
    ax.XTick = 1.5:2:(groups*2-0.5); % to "combine" the groups in pairs
    ax.XTickLabel = {'a','b','c','v','f'};
    % set the ylim to include all data:
    ax.YLim = [min([data1(:); data2(:)]) max([data1(:); data2(:)])];
    box off
    if k == 1 
        ylabel('Miles per Gallon (MPG)') % only for the most right axes 
    else
        ax.YTick = [];
    end
    xlabel(num2str(2000+k)) % the labels for the years
    ax.Position = [corner(k) 0.11 width 0.8];
    % this will color the data:
    for g = 1:2:numel(ax.Children.Children)-1
       ax.Children.Children(g).Color = colors(1,:);
       ax.Children.Children(g).MarkerEdgeColor = colors(1,:);
       ax.Children.Children(g+1).Color = colors(2,:);
       ax.Children.Children(g+1).MarkerEdgeColor = colors(2,:);
    end
    if k == years
        % you can try to change here the index to 1:2 and see if you like it:
        leg = legend(ax.Children.Children(20:21),legendEntries);
        leg.Position(1) = 0.92;
    end
end
% and finally we place the title:
main_ax = axes('Position',[corner(1) 0.11 width*years 0.815]);
title('Miles per Gallon by Vehicle Origin')
axis off

我们得到了拥挤的情节:

sbs_boxplot