user1192748
user1192748

Reputation: 1015

How can I change 'PlotStyle' property of a given boxplot figure?

Given a .fig file of a Matlab boxplot (i.e. underlying data not available), is it possible to change the PlotStyle attribute (from 'traditional' to 'compact')?

Upvotes: 6

Views: 1390

Answers (1)

EBH
EBH

Reputation: 10440

This question is kind of tricky because not like other graphic objects in Matlab, boxplot is a group of lines. As so, all the properties that are set while you create it are inaccessible (and in fact does not exist) after plotting.

One option to deal with that is to create a 'dummy' boxplot, and then alter it to your data. Because boxplot has no simple properties of XData and YData, at least not as we use to them, it takes some work to do that.

Here is a short code to demonstrate that:

% this is just to make a figure for example:
X = normrnd(10,1,100,1);
boxplot(X) % this is the 'Traditional' figure that you load
% you start here, after you load your figure:
bx = findobj('tag','boxplot');
% get the properties of the axes:
axlimx = bx.Parent.XLim;
axlimy = bx.Parent.YLim;
% get all needed properties for plotting compact box plot
txt = bx.Parent.XAxis.TickLabels;
med = get(findobj(bx,'tag','Median'),'YData'); % Median
out = get(findobj(bx,'tag','Outliers'),'YData'); % Outliers
box = get(findobj(bx,'tag','Box'),'YData'); % the Box
whis = cell2mat(get([findobj(bx,'tag','Lower Whisker')...
    findobj(bx,'tag','Upper Whisker')],'YData')); % Whisker
minmax = @(R) [min(R(:)) max(R(:))]; % helper function
close all
% Now we closed the original figure, and create a new one for manipulation:
boxplot(normrnd(10,1,100,1),'PlotStyle','Compact');
bxc = findobj('tag','boxplot');
% set the properties of the axes:
bxc.Parent.XLim = axlimx;
bxc.Parent.YLim = axlimy;
% set all properties of the compact box plot:
bxc.Children(1).String = txt;
set(bxc.Children(2),'YData',out) % Outliers
set(bxc.Children(3:4),'YData',med(1)) % MedianInner & MedianOuter
set(bxc.Children(5),'YData',minmax(box)) % the Box 
set(bxc.Children(6),'YData',minmax(whis)) % Whisker

Another way to alter the boxplot to 'compact' style, is to change the graphics directly. In this case, we don't create a new dummy figure but work on the loaded figure.

Here is a code for that approach:

% this is just to make a figure for example:
X = normrnd(10,1,100,1);
boxplot(X) % this is the 'Traditional' figure that you load
% you start here, after you load your figure:
bx = findobj('tag','boxplot');
minmax = @(R) [min(R(:)) max(R(:))]; % helper function
% get the whisker limits:
whis = cell2mat(get([findobj(bx,'tag','Lower Whisker')...
    findobj(bx,'tag','Upper Whisker')],'YData')); % Whisker
set(findobj(bx,'tag','Upper Whisker'),{'YData','Color','LineStyle'},...
    {minmax(whis),'b','-'})
% set the median:
set(findobj(bx,'tag','Median'),{'XData','YData','LineStyle','Marker',...
    'Color','MarkerSize','MarkerFaceColor'},...
    {1,min(get(findobj(bx,'tag','Median'),'YData')),'none','o','b',6,'auto'}); 
% set the box:
set(findobj(bx,'tag','Box'),{'XData','YData','LineWidth'},...
    {[1 1],minmax(get(findobj(bx,'tag','Box'),'YData')),4});
im_med = copyobj(findobj(bx,'tag','Median'),bx);
im_med.Marker = '.';
% set the outliers:
out = get(findobj(bx,'tag','Outliers'),'YData'); % Outliers
set(findobj(bx,'tag','Outliers'),{'XData','LineStyle','Marker','MarkerEdgeColor',...
    'MarkerSize','MarkerFaceColor'},{0.9+0.2*rand(size(out)),'none','o','b',4,'none'});
% rotate x-axis labels:
bx.Parent.XAxis.TickLabelRotation = 90;
% delete all the rest:
delete(findobj(bx,'tag','Lower Whisker'))
delete(findobj(bx,'tag','Lower Adjacent Value'))
delete(findobj(bx,'tag','Upper Adjacent Value'))

Upvotes: 4

Related Questions