# Tuning BoxWhiskerChart

I have a large set of experimental data points (n) and I want perform some statistics on them. Particularly instead of showing all data points using ListPlot I want to narrow this set into several smaller intervals with defined width (m) and show some statistical information characterizing data in these intervals. To start with I tried to do it with BoxWhiskerChart. Below is an example code I wrote:

m = 10000;
n = 5;
data = RandomVariate[NormalDistribution[0, 1], m];
BoxWhiskerChart[Table[data[[IntegerPart[m/n]*(i-1)+1;;IntegerPart[m/n]*i]],{i,n}],
ChartLabels->Table[ToString[i],{i,n}]]


It returned me the a nice Box-Whisker chart of my data. However, I believe, by default (please correct me if I am wrong) it shows median for the middle of the box, first and third quartiles for the top and bottom of the box, min and max values for whiskers.

Is it possible to tune this so that it will show the mean (average) for the middle of the box and chosen confidence bands or standard error for whiskers?

Another question: is it possible to color boxes for different intervals differently?

• – kglr Jun 6 '17 at 23:51

Update: We can use the "BoxRange" sub-option of Method combined with the option "IQRCoefficient" in ChartElementDataFunction to get the boxes and fences placed at x StandardDeviation distance below and above the Mean without having to use a custom ChartElementFunction.

The elements of BoxWhiskerChart are determined by the 5 quantiles of the data (namely, Quantile[data, {0,.25, .5, .75, 1}]). The location of the fences are controlled by the option IQRCoefficient that can be specified in the setting of the option ChartElementFunction as in

ChartElementFunction -> ChartElementDataFunction["BoxWhisker", "IQRCoefficient" -> iqr]


so that the lower fence is placed at Quartile[data][[1]] - iqr InterquartileRange[data] and the upper fence at Quartile[data][[3]] + iqr InterquartileRange[data].

One way to base the BoxWhiskerChart elements on the Mean and StandardDeviation (rather than on quantiles) is to use the sub-option "BoxRange" in the Method option of BoxWhiskerChart. This can be done defining

boxRange = Through[{Min, Mean[#] - StandardDeviation[#] &, Mean,
Mean[#] + StandardDeviation[#] &, Max}@#] &;


and using it as in

Method -> {"BoxRange" -> boxRange}


Combined with the option

ChartElementFunction -> ChartElementDataFunction["BoxWhisker", "IQRCoefficient" -> 1/2]


we will get a box defined by Mean - StandardDeviation and Mean + StandardDeviation (as opposed to a box defined by the first and third quartiles) and fences at 2 StandardDeviation below and above the Mean.

Example:

bwcdata = Table[data[[IntegerPart[m/n]*(i - 1) + 1 ;;  IntegerPart[m/n]*i]], {i, n}];

options = {{{"MedianMarker", 1, None}, {"Outliers", Green},
{"MeanMarker", 1, Directive[Thickness[.01], CapForm["Butt"], Red]},
{"Fences", 1, Directive[Thickness[.01], Purple]},
{"Whiskers",  Directive[Thickness[.025], CapForm["Butt"], Orange]}},
ChartLabels -> Table[ToString[i], {i, n}], ChartStyle -> 1,
ChartElementFunction -> ChartElementDataFunction["BoxWhisker", "IQRCoefficient" -> 1/2],
Method -> {"BoxRange" -> boxRange}};

BoxWhiskerChart[bwcdata, ## & @@ options]


BoxWhiskerChart[#, ## & @@ options, ImageSize -> 200,
GridLines -> {None, boxRange@#}] & /@ bwcdata // Row


Original post:

You can use the second argument of BoxWhiskerChart to show the MeanMarker instead of the default MedianMarker.

BoxWhiskerChart[Table[data[[IntegerPart[m/n]*(i - 1) + 1 ;; IntegerPart[m/n]*i]], {i, n}],
{{"MedianMarker", None}, {"MeanMarker", 1, White}},
ChartLabels -> Table[ToString[i], {i, n}], ChartStyle -> 1]


• I think OP is asking to customize the whisker limits as well. Can this be done in BoxWhiskerChart? – jjc385 Jun 6 '17 at 22:50
• Thank you @jjc385. I think/hope the update handles the positioning of the boxes and the fences. – kglr Jun 7 '17 at 1:38

As @kglr shows, one can use the Method option of BoxWhiskerChart to control the location of the fences. On the other hand, it is also possible to control the appearance of the chart by using a custom ChartElementFunction. For example:

custom[{{l_,r_}, {b_, t_}}, values_, _] := Module[{mean, q25, q75, lf, uf, mid, sl, sr},
mid = (l+r)/2;
{sl, sr} = mid+{-1,1}(r-l)/4;
mean = Mean[values];
{lf, q25, q75, uf} = Quantile[values, {.05,.25,.75,.95}];
{
(* whiskers *)
Line[{{mid,lf},{mid,uf}}],

(* upper fence *)
Line[{{sl,uf},{sr,uf}}],

(* lower fence *)
Line[{{sl,lf},{sr,lf}}],

(* box *)
FaceForm[Cyan], Rectangle[{l,q25},{r,q75}],

(* mean *)
Line[{{l,mean},{r,mean}}]
}
]


And here is how it looks:

SeedRandom[1];
data = RandomVariate[NormalDistribution[0,1],100];

BoxWhiskerChart[data, ChartElementFunction->custom]