A graphical toolkit for visualization
Protovis
Overview
Examples
Documentation
Download
Index
« Previous / Next »

Box-and-Whisker Plots

View full screen.

A box-and-whisker plot uses simple glyphs that summarize a quantitative distribution with five standard statistics: the smallest value, lower quartile, median, upper quartile, and largest value. This summary approach is similar to a candlestick chart, and allows the viewer to easily recognize significant differences (or lack thereof) between distributions.

Next: Histograms

Source

<html>
  <head>
    <title>Box-and-Whisker Plot</title>
    <link rel="stylesheet" type="text/css" href="ex.css"/>
    <script type="text/javascript" src="../protovis-r3.2.js"></script>
    <script type="text/javascript" src="box-and-whisker.js"></script>
    <style type="text/css">

#fig {
  width: 900px;
  height: 340px;
}

    </style>
  </head>
  <body><div id="center"><div id="fig">
    <script type="text/javascript+protovis">

var w = 860,
    h = 300,
    x = pv.Scale.ordinal(experiments, function(e) e.id).splitBanded(0, w, 3/5)
    y = pv.Scale.linear(0, 1).range(0, h)
    s = x.range().band / 2;

var vis = new pv.Panel()
    .width(w)
    .height(h)
    .margin(20);

/* Add the y-axis rules */
vis.add(pv.Rule)
    .data(y.ticks())
    .bottom(y)
    .strokeStyle(function(d) (d == 0 || d == 1) ? "#000" : "#ccc")
  .anchor("left").add(pv.Label)
    .text(y.tickFormat);

/* Add a panel for each data point */
var points = vis.add(pv.Panel)
    .data(experiments)
    .left(function(d) x(d.id))
    .width(s * 2);

/* Add the experiment id label */
points.anchor("bottom").add(pv.Label)
    .textBaseline("top")
    .text(function(d) d.id);

/* Add the range line */
points.add(pv.Rule)
    .left(s)
    .bottom(function(d) y(d.min))
    .height(function(d) y(d.max) - y(d.min));

/* Add the min and max indicators */
points.add(pv.Rule)
    .data(function(d) [d.min, d.max])
    .bottom(y)
    .left(s / 2)
    .width(s);

/* Add the upper/lower quartile ranges */
points.add(pv.Bar)
    .bottom(function(d) y(d.lq))
    .height(function(d) y(d.uq) - y(d.lq))
    .fillStyle(function(d) d.median > .5 ? "#aec7e8" : "#ffbb78")
    .strokeStyle("black")
    .lineWidth(1)
    .antialias(false);

/* Add the median line */
points.add(pv.Rule)
    .bottom(function(d) y(d.median));

vis.render();

    </script>
  </div></div></body>
</html>

Data

var experiments = "ABCDEFGHIJKLM".split("").map(function(i) {
  var offset = Math.random()*3/4;
  var data = pv.range(0,15).map(function(i) {
    return offset + Math.random()/4;
  }).sort();

  return {
    id:i,
    median:data[7],
    uq:data[11],
    lq:data[3],
    max:data[data.length-1],
    min:data[0]
  };
})
Copyright 2010 Stanford Visualization Group