boxchart vs boxplot
>with r2020 there is finally a grouped boxplot called "boxchart".
The boxplot() function also has grouping options, has been around for much longer, and is often easier to customize than the newer standalone visualzation boxchart function. ColorGroup & Notches
>How does one apply any property simultaneously to all boxes instead of looping? For instance like b.Notch = 'on' or a colormap to the ColorGroup?
See examples in the boxplot documentation for notches, and a description of ColorGroup. To apply changes to a group of handles to existing graphics objects, follow this example, although the loop you mentioned is also fine and just as fast (faster?),
set(h, {'BoxFaceColor'}, mat2cell(jet(numel(h)),ones(numel(h),1),3))
Separation lines
>How could I add separation lines?
For boxchart, this option currently doesn't exist (r2020b). If the x-axis is numeric, add divider lines using,
If the x-axis is categorical it's a lot more complicated because divider lines cannot be added between categories. To add divider lines on a categorical x-axis you have to add additional categories to the x axis ticks, set their order, and then use xline() (or plot() or line()) with categorical x-values.
monthNum = randi(12,200,1);
data = rand(200,1)*100.*(normpdf(monthNum,6,1)+.25);
monthAbrv = categorical(monthNum,1:12,month(datetime(1, 1:12, 1), 's'));
h = boxchart(monthAbrv, data);
'Mar' 'Apr' 'May' 'Summer',...
'Jun' 'Jul' 'Aug' 'Fall',...
'Sep' 'Oct' 'Nov' 'Winter',...
arrayfun(@(x)xline(x,'r-','LineWidth',1.5),categorical({'Spring','Summer','Fall','Winter'}))
ax.XTickLabel([3,7,11,15]) = {''};
Fix overlapping boxes in boxchart
>Why can't I seem to get a correct looking diagram when plotting [with grouped data]?
You can fix the overlapping boxes by making the grouping variable categorical
boxchart(categorical(xgroupdata),ydata, 'GroupByColor', group);
Adding text labels
> I would like to be able to add a textlabel to any of the boxes
Use the text() function. See the bottom of this answer to learn how to get the x value of the boxplot centers. For numeric axes it's as easy as using the text() function but for categorical axes, you must use categorical coordinates. This demo below shows the number of samples in each category and plots that number above the median lines.
h = boxchart(randi(5,100,1),rand(100,1));
[groupID, groups] = findgroups(h.XData);
medians = splitapply(@median,h.YData,groupID);
nSamples = splitapply(@numel,h.YData,groupID);
text(groups, medians, compose('n=%d',nSamples),...
'HorizontalAlignment','Center','VerticalAlignment','bottom', ...
Extracting location of boxs
>I need to a) figure out the position of the boxes but I don't manage to understand the structure of the handle
Extracting the location of the boxes from the graphics handle involves accessing each graphics element and examining its coordinates. It's not easy but achievable with boxplot (see this answer). I haven't figured out a way to achieve this with boxchart as of r2020b. Of course many of the parameters can be computed using the raw data.
The median marker are easy to get using,
[groupID, groups] = findgroups(h.XData);
medians = splitapply(@median,h.YData,groupID);
The upper and lower edges of the boxes are the 25th and 75th quartiles,
[groupID, groups] = findgroups(h.XData);
bounds = splitapply(@(y)quantile(y,[.25,.75]),h.YData,groupID);
The whisker ends are a bit more difficult. They mark the max/min values that are not outliers so first you have to compute the outlier thresholds. Outliers are any values that are greater than 1.5*IQR from the medians. IQR is computed for each box below. See documentation for more info. [groupID, groups] = findgroups(h.XData);
IQR = splitapply(@iqr,h.YData,groupID);
The box centers and Left/Right edges for numeric axes are calculated using
boxCenters = unique(h.XData);
boxEdges = boxCenters(:) + h.BoxWidth.*[-1,1];
Best Answer