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
<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>
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]
};
})