Skip to content

Instantly share code, notes, and snippets.

@mukhtyar
Last active September 20, 2018 22:41
Show Gist options
  • Save mukhtyar/8e4bc63357515e554e4e6b8aa900c9ef to your computer and use it in GitHub Desktop.
Save mukhtyar/8e4bc63357515e554e4e6b8aa900c9ef to your computer and use it in GitHub Desktop.
D3.js Boxplot with Axes and Labels
license: mit

A box-and-whisker plot with axes. Based on Mike Bostock's implementation. Instead of using individual svg elements as in Mike's implementation, here all boxplots are rendered with in one root element. This makes it easy to add axes.

Further differences between the two implementations are:

  • visibility of boxplot labels can be switched with the labels variable
  • CSV files are supported in which each column is an independent variable and each row contains measurements for all variables (see data.csv)
  • transitions are not used here but can be easily added again

forked from jensgrubert's block: D3.js Boxplot with Axes and Labels

forked from sdalo2's block: D3.js Boxplot with Axes and Labels

(function() {
// Inspired by http://informationandvisualization.de/blog/box-plot
d3.box = function() {
var width = 1,
height = 1,
duration = 0,
domain = null,
value = Number,
whiskers = boxWhiskers,
quartiles = boxQuartiles,
showLabels = true, // whether or not to show text labels
numBars = 4,
curBar = 1,
tickFormat = null;
// For each small multiple…
function box(g) {
g.each(function(data, i) {
//d = d.map(value).sort(d3.ascending);
//var boxIndex = data[0];
//var boxIndex = 1;
var d = data[1].sort(d3.ascending);
// console.log(boxIndex);
//console.log(d);
var g = d3.select(this),
n = d.length,
min = d[0],
max = d[n - 1];
// Compute quartiles. Must return exactly 3 elements.
var quartileData = d.quartiles = quartiles(d);
// Compute whiskers. Must return exactly 2 elements, or null.
var whiskerIndices = whiskers && whiskers.call(this, d, i),
whiskerData = whiskerIndices && whiskerIndices.map(function(i) { return d[i]; });
// Compute outliers. If no whiskers are specified, all data are "outliers".
// We compute the outliers as indices, so that we can join across transitions!
var outlierIndices = whiskerIndices
? d3.range(0, whiskerIndices[0]).concat(d3.range(whiskerIndices[1] + 1, n))
: d3.range(n);
// Compute the new x-scale.
var x1 = d3.scale.linear()
.domain(domain && domain.call(this, d, i) || [min, max])
.range([height, 0]);
// Retrieve the old x-scale, if this is an update.
var x0 = this.__chart__ || d3.scale.linear()
.domain([0, Infinity])
// .domain([0, max])
.range(x1.range());
// Stash the new scale.
this.__chart__ = x1;
// Note: the box, median, and box tick elements are fixed in number,
// so we only have to handle enter and update. In contrast, the outliers
// and other elements are variable, so we need to exit them! Variable
// elements also fade in and out.
// Update center line: the vertical line spanning the whiskers.
var center = g.selectAll("line.center")
.data(whiskerData ? [whiskerData] : []);
//vertical line
center.enter().insert("line", "rect")
.attr("class", "center")
.attr("x1", width / 2)
.attr("y1", function(d) { return x0(d[0]); })
.attr("x2", width / 2)
.attr("y2", function(d) { return x0(d[1]); })
.style("opacity", 1e-6)
.transition()
.duration(duration)
.style("opacity", 1)
.attr("y1", function(d) { return x1(d[0]); })
.attr("y2", function(d) { return x1(d[1]); });
center.transition()
.duration(duration)
.style("opacity", 1)
.attr("y1", function(d) { return x1(d[0]); })
.attr("y2", function(d) { return x1(d[1]); });
center.exit().transition()
.duration(duration)
.style("opacity", 1e-6)
.attr("y1", function(d) { return x1(d[0]); })
.attr("y2", function(d) { return x1(d[1]); })
.remove();
// Update innerquartile box.
var box = g.selectAll("rect.box")
.data([quartileData]);
box.enter().append("rect")
.attr("class", "box")
.attr("x", 0)
.attr("y", function(d) { return x0(d[2]); })
.attr("width", width)
.attr("height", function(d) { return x0(d[0]) - x0(d[2]); })
.transition()
.duration(duration)
.attr("y", function(d) { return x1(d[2]); })
.attr("height", function(d) { return x1(d[0]) - x1(d[2]); });
box.transition()
.duration(duration)
.attr("y", function(d) { return x1(d[2]); })
.attr("height", function(d) { return x1(d[0]) - x1(d[2]); });
// Update median line.
var medianLine = g.selectAll("line.median")
.data([quartileData[1]]);
medianLine.enter().append("line")
.attr("class", "median")
.attr("x1", 0)
.attr("y1", x0)
.attr("x2", width)
.attr("y2", x0)
.transition()
.duration(duration)
.attr("y1", x1)
.attr("y2", x1);
medianLine.transition()
.duration(duration)
.attr("y1", x1)
.attr("y2", x1);
// Update whiskers.
var whisker = g.selectAll("line.whisker")
.data(whiskerData || []);
whisker.enter().insert("line", "circle, text")
.attr("class", "whisker")
.attr("x1", 0)
.attr("y1", x0)
.attr("x2", 0 + width)
.attr("y2", x0)
.style("opacity", 1e-6)
.transition()
.duration(duration)
.attr("y1", x1)
.attr("y2", x1)
.style("opacity", 1);
whisker.transition()
.duration(duration)
.attr("y1", x1)
.attr("y2", x1)
.style("opacity", 1);
whisker.exit().transition()
.duration(duration)
.attr("y1", x1)
.attr("y2", x1)
.style("opacity", 1e-6)
.remove();
// Update outliers.
var outlier = g.selectAll("circle.outlier")
.data(outlierIndices, Number);
outlier.enter().insert("circle", "text")
.attr("class", "outlier")
.attr("r", 5)
.attr("cx", width / 2)
.attr("cy", function(i) { return x0(d[i]); })
.style("opacity", 1e-6)
.transition()
.duration(duration)
.attr("cy", function(i) { return x1(d[i]); })
.style("opacity", 1);
outlier.transition()
.duration(duration)
.attr("cy", function(i) { return x1(d[i]); })
.style("opacity", 1);
outlier.exit().transition()
.duration(duration)
.attr("cy", function(i) { return x1(d[i]); })
.style("opacity", 1e-6)
.remove();
// Compute the tick format.
var format = tickFormat || x1.tickFormat(8);
// Update box ticks.
var boxTick = g.selectAll("text.box")
.data(quartileData);
if(showLabels == true) {
boxTick.enter().append("text")
.attr("class", "box")
.attr("dy", ".3em")
.attr("dx", function(d, i) { return i & 1 ? 6 : -6 })
.attr("x", function(d, i) { return i & 1 ? + width : 0 })
.attr("y", x0)
.attr("text-anchor", function(d, i) { return i & 1 ? "start" : "end"; })
.text(format)
.transition()
.duration(duration)
.attr("y", x1);
}
boxTick.transition()
.duration(duration)
.text(format)
.attr("y", x1);
// Update whisker ticks. These are handled separately from the box
// ticks because they may or may not exist, and we want don't want
// to join box ticks pre-transition with whisker ticks post-.
var whiskerTick = g.selectAll("text.whisker")
.data(whiskerData || []);
if(showLabels == true) {
whiskerTick.enter().append("text")
.attr("class", "whisker")
.attr("dy", ".3em")
.attr("dx", 6)
.attr("x", width)
.attr("y", x0)
.text(format)
.style("opacity", 1e-6)
.transition()
.duration(duration)
.attr("y", x1)
.style("opacity", 1);
}
whiskerTick.transition()
.duration(duration)
.text(format)
.attr("y", x1)
.style("opacity", 1);
whiskerTick.exit().transition()
.duration(duration)
.attr("y", x1)
.style("opacity", 1e-6)
.remove();
});
d3.timer.flush();
}
box.width = function(x) {
if (!arguments.length) return width;
width = x;
return box;
};
box.height = function(x) {
if (!arguments.length) return height;
height = x;
return box;
};
box.tickFormat = function(x) {
if (!arguments.length) return tickFormat;
tickFormat = x;
return box;
};
box.duration = function(x) {
if (!arguments.length) return duration;
duration = x;
return box;
};
box.domain = function(x) {
if (!arguments.length) return domain;
domain = x == null ? x : d3.functor(x);
return box;
};
box.value = function(x) {
if (!arguments.length) return value;
value = x;
return box;
};
box.whiskers = function(x) {
if (!arguments.length) return whiskers;
whiskers = x;
return box;
};
box.showLabels = function(x) {
if (!arguments.length) return showLabels;
showLabels = x;
return box;
};
box.quartiles = function(x) {
if (!arguments.length) return quartiles;
quartiles = x;
return box;
};
return box;
};
function boxWhiskers(d) {
return [0, d.length - 1];
}
function boxQuartiles(d) {
return [
d3.quantile(d, .25),
d3.quantile(d, .5),
d3.quantile(d, .75)
];
}
})();
Q1 Q2 Q3 Q4
20000 15000 8000 20000
9879 9323 3294 5629
5070 9395 17633 5752
7343 8675 12121 7557
9136 5354 4319 5125
7943 6725 18712 5116
10546 10899 17270 5828
9385 9365 13676 6014
8669 8238 6587 5995
4000 7446 16754 8905
series value
HadGEM2-ES 28083.16796875
HadGEM2-ES 50544.6049804687
HadGEM2-ES 55854.076171875
HadGEM2-ES 22412.1064453125
HadGEM2-ES 36182.9033203125
HadGEM2-ES 35513.9340820312
HadGEM2-ES 17740.1616210938
HadGEM2-ES 60885.443359375
HadGEM2-ES 36016.474609375
HadGEM2-ES 22536.7919921875
HadGEM2-ES 36157.423828125
HadGEM2-ES 21342.513671875
HadGEM2-ES 13899.8208007813
HadGEM2-ES 41092.2939453125
HadGEM2-ES 30119.3500976562
HadGEM2-ES 89418.568359375
HadGEM2-ES 28083.16796875
HadGEM2-ES 50544.6049804687
HadGEM2-ES 55854.076171875
HadGEM2-ES 22412.1064453125
HadGEM2-ES 36182.9033203125
HadGEM2-ES 35513.9340820312
HadGEM2-ES 17740.1616210938
HadGEM2-ES 20121.603515625
HadGEM2-ES 29015.765625
HadGEM2-ES 36097.1298828125
HadGEM2-ES 42109.13671875
HadGEM2-ES 15394.478515625
HadGEM2-ES 34765.56640625
HadGEM2-ES 39775.9897460937
HadGEM2-ES 39506.0893554687
HadGEM2-ES 25989.7778320312
HadGEM2-ES 36954.02734375
HadGEM2-ES 29204.1064453125
HadGEM2-ES 22917.9204101563
HadGEM2-ES 37769.615234375
HadGEM2-ES 45983.8427734375
HadGEM2-ES 20454.6474609375
HadGEM2-ES 30070.4350585938
HadGEM2-ES 39222.982421875
HadGEM2-ES 58211.9619140625
HadGEM2-ES 55338.1494140625
HadGEM2-ES 27520.169921875
HadGEM2-ES 46136.9765625
HadGEM2-ES 67569.6962890625
HadGEM2-ES 30587.0419921875
HadGEM2-ES 26698.689453125
HadGEM2-ES 41953.6162109375
HadGEM2-ES 22442.9624023437
HadGEM2-ES 25732.953125
HadGEM2-ES 29490.2802734375
HadGEM2-ES 23637.8857421875
HadGEM2-ES 27597.4418945313
HadGEM2-ES 33643.4819335937
HadGEM2-ES 53632.548828125
HadGEM2-ES 25197.345703125
HadGEM2-ES 36098.1284179688
HadGEM2-ES 25938.0854492187
HadGEM2-ES 59528.96875
HadGEM2-ES 24095.4301757812
HadGEM2-ES 28721.89453125
HadGEM2-ES 32860.1142578125
HadGEM2-ES 36870.263671875
HadGEM2-ES 48873.65625
HadGEM2-ES 34918.4614257812
HadGEM2-ES 45305.4331054688
HadGEM2-ES 16829.41015625
HadGEM2-ES 63068.14453125
HadGEM2-ES 43779.1552734375
HadGEM2-ES 21084.7202148437
HadGEM2-ES 19258.8735351563
HadGEM2-ES 16419.2858886719
HadGEM2-ES 11960.8356933594
HadGEM2-ES 42504.955078125
HadGEM2-ES 50421.0903320312
HadGEM2-ES 29211.7626953125
HadGEM2-ES 26618.4301757812
HadGEM2-ES 61257.521484375
HadGEM2-ES 28233.4296875
HadGEM2-ES 10291.302734375
HadGEM2-ES 20733.8388671875
HadGEM2-ES 20336.8122558594
HadGEM2-ES 55173.5888671875
HadGEM2-ES 30957.5200195312
HadGEM2-ES 23266.6958007812
HadGEM2-ES 13732.9514160156
HadGEM2-ES 21880.86328125
HadGEM2-ES 32731.1625976562
HadGEM2-ES 35309.6650390625
HadGEM2-ES 22178.6843261719
HadGEM2-ES 34353.6987304687
HadGEM2-ES 54090.705078125
HadGEM2-ES 16744.2993164063
HadGEM2-ES 9241.1567382813
HadGEM2-ES 14391.3835449219
HadGEM2-ES 26244.330078125
HadGEM2-ES 18836.814453125
HadGEM2-ES 54311.0893554688
HadGEM2-ES 26142.83203125
HadGEM2-ES 14692.4680175781
HadGEM2-ES 24097.103515625
HadGEM2-ES 25704.900390625
HadGEM2-ES 18325.3249511719
HadGEM2-ES 24837.0373535156
HadGEM2-ES 16507.1831054688
HadGEM2-ES 54409.7958984375
HadGEM2-ES 28054.9135742188
HadGEM2-ES 15810.7309570312
HadGEM2-ES 44970.4848632813
HadGEM2-ES 13417.8278808594
HadGEM2-ES 52244.1181640625
HadGEM2-ES 26627.7939453125
HadGEM2-ES 17067.0727539063
HadGEM2-ES 32046.0988769531
HadGEM2-ES 9462.9721679688
HadGEM2-ES 29191.6298828125
HadGEM2-ES 14151.6899414062
HadGEM2-ES 17806.5734863281
HadGEM2-ES 25605.3530273438
HadGEM2-ES 29078.4877929687
HadGEM2-ES 20139.8864746094
HadGEM2-ES 18325.2065429688
HadGEM2-ES 43612.00390625
HadGEM2-ES 14469.2080078125
HadGEM2-ES 14184.6533203125
HadGEM2-ES 35578.4479980469
HadGEM2-ES 13072.6958007813
HadGEM2-ES 21984.9458007812
HadGEM2-ES 10630.6577148438
HadGEM2-ES 18268.75
HadGEM2-ES 13492.748046875
HadGEM2-ES 10326.865234375
HadGEM2-ES 18737.8286132813
HadGEM2-ES 54024.90625
HadGEM2-ES 34090.2666015625
HadGEM2-ES 10233.8532714844
HadGEM2-ES 17648.1755371094
HadGEM2-ES 10696.0454101563
HadGEM2-ES 38365.73046875
HadGEM2-ES 12032.6162109375
HadGEM2-ES 30236.0849609375
HadGEM2-ES 15749.9653320313
HadGEM2-ES 10933.7194824219
HadGEM2-ES 36899.6748046875
HadGEM2-ES 33583.0883789062
CNRM-CM5 70478.705078125
CNRM-CM5 31880.1391601562
CNRM-CM5 56322.462890625
CNRM-CM5 22774.7807617187
CNRM-CM5 32202.1552734375
CNRM-CM5 19605.5776367188
CNRM-CM5 49018.0107421875
CNRM-CM5 42319.099609375
CNRM-CM5 27262.40625
CNRM-CM5 29050.3002929687
CNRM-CM5 67460.212890625
CNRM-CM5 29389.1225585938
CNRM-CM5 67755.1220703125
CNRM-CM5 64469.904296875
CNRM-CM5 42290.3671875
CNRM-CM5 36739.11328125
CNRM-CM5 70478.705078125
CNRM-CM5 31880.1391601562
CNRM-CM5 56322.462890625
CNRM-CM5 22774.7807617187
CNRM-CM5 32202.1552734375
CNRM-CM5 19605.5776367188
CNRM-CM5 49018.0107421875
CNRM-CM5 42319.099609375
CNRM-CM5 27262.40625
CNRM-CM5 29050.3002929687
CNRM-CM5 67460.212890625
CNRM-CM5 25646.8056640625
CNRM-CM5 28104.8471679687
CNRM-CM5 17619.4741210938
CNRM-CM5 27274.1264648437
CNRM-CM5 45412.8173828125
CNRM-CM5 19561.9418945313
CNRM-CM5 40657.42578125
CNRM-CM5 27569.6123046875
CNRM-CM5 37119.3515625
CNRM-CM5 23151.44140625
CNRM-CM5 24059.7690429687
CNRM-CM5 73818.2197265625
CNRM-CM5 25993.7778320312
CNRM-CM5 56773.7275390625
CNRM-CM5 19736.5043945313
CNRM-CM5 24358.2294921875
CNRM-CM5 32045.0439453125
CNRM-CM5 39067.5336914062
CNRM-CM5 28086.2749023437
CNRM-CM5 45682.7055664063
CNRM-CM5 37749.0415039062
CNRM-CM5 71021.8115234375
CNRM-CM5 18271.1335449219
CNRM-CM5 23707.3676757812
CNRM-CM5 47566.1499023438
CNRM-CM5 51059.4936523438
CNRM-CM5 34017.107421875
CNRM-CM5 29739.8515625
CNRM-CM5 20314.6796875
CNRM-CM5 24141.9521484375
CNRM-CM5 34236.578125
CNRM-CM5 44029.2260742188
CNRM-CM5 14261.6638183594
CNRM-CM5 39167.47265625
CNRM-CM5 24897.763671875
CNRM-CM5 37154.466796875
CNRM-CM5 34234.4741210937
CNRM-CM5 19241.3100585938
CNRM-CM5 28413.3022460937
CNRM-CM5 18039.9680175781
CNRM-CM5 46348.955078125
CNRM-CM5 20115.6215820312
CNRM-CM5 49574.5322265625
CNRM-CM5 67013.720703125
CNRM-CM5 18797.7573242188
CNRM-CM5 26465.6967773437
CNRM-CM5 52328.7529296875
CNRM-CM5 29081.0639648437
CNRM-CM5 50072.1982421875
CNRM-CM5 29145.3330078125
CNRM-CM5 34172.0234375
CNRM-CM5 14304.412109375
CNRM-CM5 49898.13671875
CNRM-CM5 22550.59765625
CNRM-CM5 34976.3793945313
CNRM-CM5 35084.5346679688
CNRM-CM5 24359.4165039062
CNRM-CM5 36860.32421875
CNRM-CM5 77024.1103515625
CNRM-CM5 86365.251953125
CNRM-CM5 24967.7749023438
CNRM-CM5 56352.64453125
CNRM-CM5 19692.6364746094
CNRM-CM5 32439.9931640625
CNRM-CM5 19374.3588867188
CNRM-CM5 39841.2670898438
CNRM-CM5 24931.9619140625
CNRM-CM5 48823.3779296875
CNRM-CM5 54275.0190429688
CNRM-CM5 33056.7158203125
CNRM-CM5 32002.0610351562
CNRM-CM5 30694.4086914062
CNRM-CM5 28257.6337890625
CNRM-CM5 22734.083984375
CNRM-CM5 16546.9877929688
CNRM-CM5 18093.61328125
CNRM-CM5 24582.685546875
CNRM-CM5 59186.876953125
CNRM-CM5 45679.8012695313
CNRM-CM5 38949.072265625
CNRM-CM5 19120.1635742188
CNRM-CM5 35304.4946289062
CNRM-CM5 60289.9150390625
CNRM-CM5 25971.7104492187
CNRM-CM5 12757.0446777344
CNRM-CM5 45208.0581054688
CNRM-CM5 19858.9045410156
CNRM-CM5 33991.3857421875
CNRM-CM5 19336.3212890625
CNRM-CM5 18912.8010253906
CNRM-CM5 16539.9895019531
CNRM-CM5 24551.37109375
CNRM-CM5 21459.896484375
CNRM-CM5 32409.3193359375
CNRM-CM5 21742.2163085938
CNRM-CM5 43332.51953125
CNRM-CM5 26736.8349609375
CNRM-CM5 45162.3095703125
CNRM-CM5 24341.7514648437
CNRM-CM5 57337.591796875
CNRM-CM5 43620.02734375
CNRM-CM5 55777.7841796875
CNRM-CM5 22577.4262695312
CNRM-CM5 33672.87890625
CNRM-CM5 18433.0825195313
CNRM-CM5 43024.1123046875
CNRM-CM5 50996.056640625
CNRM-CM5 33598.923828125
CNRM-CM5 20627.9326171875
CNRM-CM5 55977.3959960938
CNRM-CM5 30785.7426757813
CNRM-CM5 29290.0502929687
CNRM-CM5 31953.0771484375
CNRM-CM5 44648.4409179688
CNRM-CM5 47470.2583007813
CNRM-CM5 25069.138671875
CNRM-CM5 28197.62109375
CNRM-CM5 35461.4985351562
CNRM-CM5 23995.3920898437
CNRM-CM5 65051.3471679688
CNRM-CM5 33781.8793945313
CNRM-CM5 27659
CNRM-CM5 16533.8049316406
CanESM2 50613.453125
CanESM2 57082.5092773438
CanESM2 34148.8896484375
CanESM2 50595.564453125
CanESM2 29006.9306640625
CanESM2 50082.7236328125
CanESM2 41920.1025390625
CanESM2 79057.12890625
CanESM2 33529.7939453125
CanESM2 47898.544921875
CanESM2 65785.62109375
CanESM2 25872.423828125
CanESM2 22858.8076171875
CanESM2 47425.8203125
CanESM2 60654.501953125
CanESM2 15109.8208007813
CanESM2 50613.453125
CanESM2 57082.5092773438
CanESM2 34148.8896484375
CanESM2 50595.564453125
CanESM2 29006.9306640625
CanESM2 50082.7236328125
CanESM2 41920.1025390625
CanESM2 79057.12890625
CanESM2 33529.7939453125
CanESM2 47898.544921875
CanESM2 65785.62109375
CanESM2 33459.4780273438
CanESM2 22665.7954101562
CanESM2 62463.267578125
CanESM2 32269.8090820312
CanESM2 31946.705078125
CanESM2 33235.8251953125
CanESM2 37991.193359375
CanESM2 27355.0043945312
CanESM2 24547.931640625
CanESM2 22165.4091796875
CanESM2 17251.8095703125
CanESM2 34516.22265625
CanESM2 42688.7021484375
CanESM2 44315.2099609375
CanESM2 32202.0263671875
CanESM2 26314.7788085937
CanESM2 59376.9482421875
CanESM2 51771.033203125
CanESM2 32770.025390625
CanESM2 18627.154296875
CanESM2 31841.7016601563
CanESM2 33466.1616210937
CanESM2 22470.9165039062
CanESM2 37324.0659179688
CanESM2 51251.2690429687
CanESM2 14534.755859375
CanESM2 18951.7607421875
CanESM2 25042.2426757813
CanESM2 43029.078125
CanESM2 21909.0942382812
CanESM2 24018.2314453125
CanESM2 48389.109375
CanESM2 26852.04296875
CanESM2 46568.623046875
CanESM2 20700.8603515625
CanESM2 24084.3510742187
CanESM2 51254.05078125
CanESM2 75159.6005859375
CanESM2 43804.2275390625
CanESM2 39175.9736328125
CanESM2 23667.6977539063
CanESM2 33106.1909179687
CanESM2 33933.6625976562
CanESM2 24301.4877929687
CanESM2 76148.4404296875
CanESM2 22845.8110351563
CanESM2 28116.08203125
CanESM2 22701.962890625
CanESM2 27546.1645507812
CanESM2 26289.7055664062
CanESM2 33263.822265625
CanESM2 22603.7758789063
CanESM2 33899.8232421875
CanESM2 33402.0034179687
CanESM2 36923.9506835937
CanESM2 29703.66015625
CanESM2 47604.3486328125
CanESM2 28141.791015625
CanESM2 22665.6767578125
CanESM2 28379.1567382812
CanESM2 22902.521484375
CanESM2 24540.9692382812
CanESM2 26343.6337890625
CanESM2 20781.2866210937
CanESM2 27507.576171875
CanESM2 17892.62890625
CanESM2 35404.01171875
CanESM2 43090.7666015625
CanESM2 56616.681640625
CanESM2 27596.1591796875
CanESM2 34120.6586914062
CanESM2 24479.2758789062
CanESM2 24243.5532226562
CanESM2 24469.2270507812
CanESM2 23311.64453125
CanESM2 22919.2250976562
CanESM2 30856.6030273438
CanESM2 27165.513671875
CanESM2 17271.41796875
CanESM2 47320.40234375
CanESM2 23188.0244140625
CanESM2 22804.0043945313
CanESM2 46263.0283203125
CanESM2 30956.1870117188
CanESM2 30569.1528320312
CanESM2 21221.298828125
CanESM2 25136.8178710937
CanESM2 30311.85546875
CanESM2 59926.8471679688
CanESM2 48144.3110351563
CanESM2 28561.1889648438
CanESM2 24853.6064453125
CanESM2 53740.4638671875
CanESM2 59200.7534179688
CanESM2 20597.7846679687
CanESM2 25132.2934570313
CanESM2 22341.6899414062
CanESM2 27247.982421875
CanESM2 28411.5600585937
CanESM2 55426.9331054688
CanESM2 22921.1069335937
CanESM2 26076.189453125
CanESM2 28358.9946289062
CanESM2 47874.3549804688
CanESM2 19151.2150878906
CanESM2 59793.3984375
CanESM2 44098.6010742188
CanESM2 17102.9521484375
CanESM2 62113.431640625
CanESM2 23029.755859375
CanESM2 36201.0043945312
CanESM2 28890.91015625
CanESM2 31063.9345703125
CanESM2 17792.3220214844
CanESM2 14757.0185546875
CanESM2 35311.8720703125
CanESM2 28294.5063476562
CanESM2 20836.9990234375
CanESM2 17326.6318359375
CanESM2 38711.9096679687
CanESM2 40262.10546875
CanESM2 29997.4770507812
CanESM2 12608.1208496094
MIROC5 19292.236328125
MIROC5 52053.8515625
MIROC5 31655.703125
MIROC5 42468.1806640625
MIROC5 23998.875
MIROC5 29298.046875
MIROC5 26790.2236328125
MIROC5 46274.369140625
MIROC5 18627.060546875
MIROC5 33008.8217773437
MIROC5 27788.2568359375
MIROC5 13899.8208007813
MIROC5 28969.525390625
MIROC5 16017.3208007813
MIROC5 39083.216796875
MIROC5 25562.3344726563
MIROC5 19292.236328125
MIROC5 52053.8515625
MIROC5 31655.703125
MIROC5 42468.1806640625
MIROC5 23998.875
MIROC5 29298.046875
MIROC5 26790.2236328125
MIROC5 46274.369140625
MIROC5 18627.060546875
MIROC5 33008.8217773437
MIROC5 27788.2568359375
MIROC5 70337.6708984375
MIROC5 27773.3686523437
MIROC5 53391.318359375
MIROC5 28227.4624023438
MIROC5 33003.8510742187
MIROC5 55804.4580078125
MIROC5 49352.03515625
MIROC5 73600.5615234375
MIROC5 54031.81640625
MIROC5 61027.3427734375
MIROC5 31610.5341796875
MIROC5 61548.8681640625
MIROC5 25149.91015625
MIROC5 80023.91015625
MIROC5 27802.9262695313
MIROC5 37618.0693359375
MIROC5 24127.8657226563
MIROC5 29385.55859375
MIROC5 29430.1918945312
MIROC5 41970.05859375
MIROC5 45648.109375
MIROC5 25612.9252929688
MIROC5 22771.01953125
MIROC5 29671.0634765625
MIROC5 23576.9453125
MIROC5 24610.2578125
MIROC5 32432.392578125
MIROC5 21838.3154296875
MIROC5 20849.640625
MIROC5 17118.3051757813
MIROC5 29391.8681640625
MIROC5 29610.8310546875
MIROC5 45381.8203125
MIROC5 35217.9716796875
MIROC5 19730.6938476563
MIROC5 34377.009765625
MIROC5 29437.37890625
MIROC5 41886.18359375
MIROC5 41095.63671875
MIROC5 24245.9711914062
MIROC5 59589.7587890625
MIROC5 33644.322265625
MIROC5 37863.3388671875
MIROC5 44340.8828125
MIROC5 22174.4399414063
MIROC5 24668.7202148438
MIROC5 22920.3793945313
MIROC5 26867.1303710937
MIROC5 23414.9331054688
MIROC5 50295.4931640625
MIROC5 35870.2783203125
MIROC5 24505.1142578125
MIROC5 23688.2841796875
MIROC5 31761.4672851562
MIROC5 23390.443359375
MIROC5 33164.4150390625
MIROC5 28425.5043945313
MIROC5 21799.1630859375
MIROC5 60293.4013671875
MIROC5 21221.5703125
MIROC5 44581.880859375
MIROC5 15833.5874023438
MIROC5 47646.1713867188
MIROC5 28595.1528320312
MIROC5 19616.0078125
MIROC5 38104.1860351562
MIROC5 39425.3852539062
MIROC5 18234.9223632813
MIROC5 23091.0712890625
MIROC5 28346.158203125
MIROC5 35483.0576171875
MIROC5 28287.4858398438
MIROC5 21260.6298828125
MIROC5 42611.1372070312
MIROC5 16248.794921875
MIROC5 14407.7133789063
MIROC5 27807.5732421875
MIROC5 27978.591796875
MIROC5 23115.9189453125
MIROC5 28195.6015625
MIROC5 11113.4260253906
MIROC5 34816.82421875
MIROC5 21016.3872070312
MIROC5 36692.9174804687
MIROC5 21531.9262695313
MIROC5 37882.5908203125
MIROC5 17962.9301757813
MIROC5 22896.3076171875
MIROC5 43485.8686523438
MIROC5 32043.4870605469
MIROC5 20830.978515625
MIROC5 19282.3115234375
MIROC5 15518.5141601563
MIROC5 40506.4838867188
MIROC5 14909.8393554688
MIROC5 45882.177734375
MIROC5 46442.0668945313
MIROC5 26862.3833007813
MIROC5 14830.125
MIROC5 18615.412109375
MIROC5 25187.5185546875
MIROC5 18587.0161132813
MIROC5 27934.2626953125
MIROC5 22763.2546386719
MIROC5 18355.423828125
MIROC5 10294.509765625
MIROC5 29091.8657226563
MIROC5 36903.6201171875
MIROC5 15766.4868164063
MIROC5 21728.3657226562
MIROC5 15493.197265625
MIROC5 20755.7153320312
MIROC5 17401.3188476563
MIROC5 42483.4301757813
MIROC5 35392.4057617187
MIROC5 19162.9111328125
MIROC5 37271.9741210937
MIROC5 9691.3742675781
MIROC5 12501.8442382813
MIROC5 31881.2036132812
MIROC5 14603.1674804688
MIROC5 23049.4155273437
Observed 40980.1443415432
Observed 28374.6916964687
Observed 13218.3327342569
Observed 40433.5215592995
Observed 26121.9432605552
Observed 45982.5710154098
Observed 34636.0072021693
Observed 21666.1393689323
Observed 22958.1568542356
Observed 12539.1953381359
Observed 24415.8176068855
Observed 25707.8350921888
Observed 16464.9407742498
Observed 51150.640956623
Observed 26618.8730625949
Observed 38926.1678264456
Observed 61072.672670683
Observed 17260.0284575133
Observed 39505.9192621586
Observed 63308.8567798618
Observed 49494.2082831572
Observed 35778.9457468606
Observed 21964.2972501561
Observed 29086.9577460589
Observed 28523.7706370806
Observed 23852.6304979071
Observed 59896.6054725223
Observed 28606.5922707539
Observed 28010.2765083062
Observed 28175.9197756528
Observed 54778.228511513
Observed 41543.3314505215
Observed 41940.8752921533
Observed 29550.7588946293
Observed 41443.9454901136
Observed 37170.3491925719
Observed 65412.5262751633
Observed 24018.2737652537
Observed 27165.4958448386
Observed 28755.6712113658
Observed 28457.5133301419
Observed 64783.0818592463
Observed 21351.4171609738
Observed 45054.968718269
Observed 28821.9285183044
Observed 58488.6377000764
Observed 23852.6304979071
Observed 51233.4625902963
Observed 24614.5895277014
Observed 45402.8195796968
Observed 29368.5513005481
Observed 31074.6769542179
Observed 55573.3161947766
Observed 47291.1528274478
Observed 20688.8440915875
Observed 14311.5782987443
Observed 44740.2465103105
Observed 27248.3174785119
Observed 28772.2355381004
Observed 23869.1948246418
Observed 60807.6434429284
Observed 69570.1722855624
Observed 29517.63024116
Observed 20241.6072697517
Observed 28954.4431321817
Observed 17773.5225862877
Observed 21069.8236064846
Observed 27264.8818052466
Observed 24299.8673197429
Observed 20175.3499628131
Observed 20755.1013985261
Observed 50703.4041347872
Observed 16564.3267346577
Observed 65429.0906018979
Observed 41427.3811633789
Observed 23918.8878048457
Observed 74754.8065535102
Observed 40168.4923315449
Observed 35248.8872913516
Observed 22560.6130126038
Observed 24647.7181811707
Observed 49080.1001147908
Observed 26502.9227754523
Observed 52923.0239172314
Observed 78548.0373757468
Observed 17723.8296060837
Observed 21136.0809134232
Observed 29782.6594689146
Observed 43497.9220052111
Observed 52343.2724815184
Observed 33443.3756772739
Observed 19794.370447916
Observed 17574.7506654718
Observed 13831.2128234392
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.box {
font: 10px sans-serif;
}
.box line,
.box rect,
.box circle {
fill: steelblue;
stroke: #000;
stroke-width: 1px;
}
.box .center {
stroke-dasharray: 3,3;
}
.box .outlier {
fill: none;
stroke: #000;
}
.axis {
font: 12px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3.v3.min.js"></script>
<script src="box.js"></script>
<script>
var labels = true; // show the text labels beside individual boxplots?
var margin = {top: 30, right: 50, bottom: 70, left: 50};
var width = 800 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var min = Infinity,
max = -Infinity;
// parse in the data
d3.csv("data2.csv", function(error, csv) {
var data = [];
var nested = d3.nest()
.key(d => d.series)
.entries(csv);
nested.forEach((series, i) => {
var item = [];
item[0] = series.key;
var values = series.values.map(d => +d.value);
item[1] = values.sort();
data.push(item);
});
min = d3.min(csv, d => +d.value);
max = d3.max(csv, d => +d.value);
var chart = d3.box()
.whiskers(iqr(1.5))
.height(height)
.domain([min, max])
.showLabels(labels);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "box")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// the x-axis
var x = d3.scale.ordinal()
.domain( data.map(function(d) { console.log(d); return d[0] } ) )
.rangeRoundBands([0 , width], 0.7, 0.3);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
// the y-axis
var y = d3.scale.linear()
.domain([min, max])
.range([height + margin.top, 0 + margin.top]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
// draw the boxplots
svg.selectAll(".box")
.data(data)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x(d[0]) + "," + margin.top + ")"; } )
.call(chart.width(x.rangeBand()));
// draw y axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text") // and text1
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("font-size", "16px")
.text("Revenue in €");
// draw x axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height + margin.top + 10) + ")")
.call(xAxis)
.append("text") // text label for the x axis
.attr("x", (width / 2) )
.attr("y", 10 )
.attr("dy", ".71em")
.style("text-anchor", "middle")
.style("font-size", "16px")
.text("Quarter");
});
// Returns a function to compute the interquartile range.
function iqr(k) {
return function(d, i) {
console.log('d', d)
var q1 = d.quartiles[0],
q3 = d.quartiles[2],
iqr = (q3 - q1) * k,
i = -1,
j = d.length;
while (d[++i] < q1 - iqr);
while (d[--j] > q3 + iqr);
return [i, j];
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment