grouped box plots

by jlbriggs

HTML

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="width:500px;height:400px;margin:1.5em 1em;"></div>

<script>
var d          = new Date();
var pointStart = d.getTime();
Highcharts.setOptions({
    global: {
        useUTC:false
    },
    colors: [
        'rgba( 0,   154, 253, 0.9 )', //bright blue
        'rgba( 253, 99,  0,   0.9 )', //bright orange
        'rgba( 40,  40,  56,  0.9 )', //dark
        'rgba( 253, 0,   154, 0.9 )', //bright pink
        'rgba( 154, 253, 0,   0.9 )', //bright green
        'rgba( 145, 44,  138, 0.9 )', //mid purple
        'rgba( 45,  47,  238, 0.9 )', //mid blue
        'rgba( 177, 69,  0,   0.9 )', //dark orange
        'rgba( 140, 140, 156, 0.9 )', //mid
        'rgba( 238, 46,  47,  0.9 )', //mid red
        'rgba( 44,  145, 51,  0.9 )', //mid green
        'rgba( 103, 16,  192, 0.9 )'  //dark purple
    ],
    chart: {
        alignTicks:false,
        type:'',
        margin:[60,25,100,90],
        //borderRadius:10,
        //borderWidth:1,
        //borderColor:'rgba(156,156,156,.25)',
        //backgroundColor:'rgba(204,204,204,.25)',
        //plotBackgroundColor:'rgba(255,255,255,1)',
        style: {
            fontFamily: 'Abel,serif'
        },
        events:{
            load: function() {
                this.credits.element.onclick = function() {
                    window.open(
                      'http://stackoverflow.com/users/1011544/jlbriggs?tab=profile'
                    );
                 }
            }
        }           
    },
    credits: {
        text : 'http://stackoverflow.com/users/1011544/jlbriggs',
        href : 'http://stackoverflow.com/users/1011544/jlbriggs?tab=profile'
    },
    title: {
        text:'Grouped Box Plot Calculation',
        align:'left',
        margin:10,
        x: 50,
       ...

CSS

@import url(https://fonts.googleapis.com/css?family=Changa+One|Loved+by+the+King|Fredericka+the+Great|Droid+Serif:400,700,400italic|Abel|Oswald:400,300,700);

body {
    font-family:Abel, Calibri, Helvetica, sans-serif;
    font-size:95%;
}

JavaScript

var chart;
var boxesPerSeries = 4;
var numberOfSeries = 4;
var numberOfPoints = 100;

$(function() {
    $('#container').highcharts({
        chart      : { margin    : [75,25,90,100]           },
        legend     : { enabled   : true                     },
        xAxis      : { 
            title      : { text : 'Group' },
            categories : ['A', 'B', 'C', 'D'],           
            labels     : {
                style      : {
                    fontWeight  : 'bold'
                }
            }
        },
        yAxis      : { title    : { text : 'Distribution' } }
    });	
    chart = $('#container').highcharts();

    //-----------------------------------------------------
    //build the data and add the series to the chart
    var offset
    for(var i = 0; i < numberOfSeries; i++) {
        //generate random data, then calculate box plot values
        var boxData = [];
        for(var j = 0; j < boxesPerSeries; j++) {
            var data = randomData(
                numberOfPoints, 
                false, 
                (10*Math.random())
            );
            var boxValues  = getBoxValues(data);
            boxData.push(boxValues);
        }
        //add additional grouping within each group 
        offset = (i < (numberOfSeries / 2) ? -0.05 : 0.05);
        //add the data to the chart as a boxplot series 
        chart.addSeries({
            pointPlacement: offset,
            name: 'Box Plots '+i,
            type: 'boxplot',
            color: Highcharts.getOptions().colors[i],
            fillColor: Highcharts.getOptions().colors[i],
            data: boxData
        });
    }
    //-----------------------------------------------------
    
})
//-----------------------------------------------
//wrap the percentile calls in one method
function getBoxValues(data) {
    var boxValues = {};
    boxValues.low    = Math.min.apply(Math,data);
    boxValues.q1     = getPercentile(data, 25);
    boxValues.median =...