Reputation: 1015
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
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