Box Plots

Data from the Michelson–Morley experiment. Implementation contributed by Jason Davies. The “update” button randomizes the values slightly to demonstrate transitions.

Source Code

 1 var w = 120,
 2     h = 500,
 3     m = [10, 50, 20, 50], // top right bottom left
 4     min = Infinity,
 5     max = -Infinity;
 6 
 7 var chart = d3.chart.box()
 8     .whiskers(iqr(1.5))
 9     .width(w - m[1] - m[3])
10     .height(h - m[0] - m[2]);
11 
12 d3.csv("../data/morley.csv", function(csv) {
13   var data = [];
14 
15   csv.forEach(function(x) {
16     var e = ~~x.Expt - 1,
17         r = ~~x.Run - 1,
18         s = ~~x.Speed,
19         d = data[e];
20     if (!d) d = data[e] = [s];
21     else d.push(s);
22     if (s > max) max = s;
23     if (s < min) min = s;
24   });
25 
26   chart.domain([min, max]);
27 
28   var vis = d3.select("#chart").selectAll("svg")
29       .data(data)
30     .enter().append("svg:svg")
31       .attr("class", "box")
32       .attr("width", w)
33       .attr("height", h)
34     .append("svg:g")
35       .attr("transform", "translate(" + m[3] + "," + m[0] + ")")
36       .call(chart);
37 
38   chart.duration(1000);
39   window.transition = function() {
40     vis.map(randomize).call(chart);
41   };
42 });
43 
44 function randomize(d) {
45   if (!d.randomizer) d.randomizer = randomizer(d);
46   return d.map(d.randomizer);
47 }
48 
49 function randomizer(d) {
50   var k = d3.max(d) * .02;
51   return function(d) {
52     return Math.max(min, Math.min(max, d + k * (Math.random() - .5)));
53   };
54 }
55 
56 // Returns a function to compute the interquartile range.
57 function iqr(k) {
58   return function(d, i) {
59     var q1 = d.quartiles[0],
60         q3 = d.quartiles[2],
61         iqr = (q3 - q1) * k,
62         i = -1,
63         j = d.length;
64     while (d[++i] < q1 - iqr);
65     while (d[--j] > q3 + iqr);
66     return [i, j];
67   };
68 }
Copyright © 2011 Mike Bostock
Fork me on GitHub