Last active
August 29, 2015 13:57
-
-
Save michalskop/9633867 to your computer and use it in GitHub Desktop.
Pie chart vs. Bar chart fight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name | group | a1 | a2 | a3 | a4 | a5 | b1 | b2 | b3 | b4 | b5 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Person 1 | 1 | 0.380952381 | 0.2857142857 | 0.1428571429 | 0.1428571429 | 0.0476190476 | 0.35 | 0.25 | 0.15 | 0.2 | 0.05 | |
Person 2 | 1 | 0.3 | 0.25 | 0.2 | 0.2 | 0.05 | 0.4 | 0.3 | 0.15 | 0.1 | 0.05 | |
Person 3 | 1 | 0.31 | 0.23 | 0.2 | 0.2 | 0.06 | 0.3 | 0.25 | 0.18 | 0.15 | 0.12 | |
Person 4 | 1 | 0.35 | 0.25 | 0.15 | 0.15 | 0.1 | 0.3 | 0.25 | 0.2 | 0.15 | 0.1 | |
Person 5 | 1 | 0.4 | 0.35 | 0.1 | 0.1 | 0.05 | 0.37 | 0.25 | 0.15 | 0.13 | 0.1 | |
Person 6 | 1 | 0.25 | 0.2391304348 | 0.2065217391 | 0.2065217391 | 0.097826087 | 0.2696629213 | 0.2471910112 | 0.1685393258 | 0.1685393258 | 0.1460674157 | |
Person 7 | 1 | 0.375 | 0.3125 | 0.125 | 0.125 | 0.0625 | 0.3157894737 | 0.2631578947 | 0.1578947368 | 0.1578947368 | 0.1052631579 | |
Person 8 | 1 | 0.3157894737 | 0.2631578947 | 0.1578947368 | 0.1578947368 | 0.1052631579 | 0.2772277228 | 0.2376237624 | 0.1782178218 | 0.1683168317 | 0.1386138614 | |
Person 9 | 1 | 0.4 | 0.3 | 0.12 | 0.12 | 0.06 | 0.35 | 0.25 | 0.2 | 0.15 | 0.05 | |
Person 10 | 1 | 0.3076923077 | 0.2435897436 | 0.1666666667 | 0.1666666667 | 0.1153846154 | 0.2947368421 | 0.2736842105 | 0.1894736842 | 0.1473684211 | 0.0947368421 | |
Person 11 | 1 | 0.27 | 0.23 | 0.2 | 0.2 | 0.1 | 0.29 | 0.26 | 0.18 | 0.15 | 0.12 | |
Person 12 | 2 | 0.2947368421 | 0.2315789474 | 0.1789473684 | 0.2105263158 | 0.0842105263 | 0.3 | 0.25 | 0.2 | 0.15 | 0.1 | |
Person 13 | 2 | 0.33 | 0.22 | 0.18 | 0.16 | 0.11 | 0.3203883495 | 0.2330097087 | 0.1747572816 | 0.145631068 | 0.1262135922 | |
Person 14 | 2 | 0.2678571429 | 0.25 | 0.1696428571 | 0.1607142857 | 0.1517857143 | 0.2857142857 | 0.2244897959 | 0.2040816327 | 0.1530612245 | 0.1326530612 | |
Person 15 | 2 | 0.3296703297 | 0.3076923077 | 0.1318681319 | 0.1648351648 | 0.0659340659 | 0.3 | 0.25 | 0.2 | 0.15 | 0.1 | |
Person 16 | 2 | 0.2545454545 | 0.2363636364 | 0.1909090909 | 0.1818181818 | 0.1363636364 | 0.3225806452 | 0.2688172043 | 0.2150537634 | 0.1075268817 | 0.0860215054 | |
Person 17 | 2 | 0.35 | 0.25 | 0.18 | 0.1 | 0.12 | 0.36 | 0.3 | 0.2 | 0.1 | 0.04 | |
Person 18 | 2 | 0.2967032967 | 0.2637362637 | 0.1538461538 | 0.1758241758 | 0.1098901099 | 0.2777777778 | 0.2333333333 | 0.1888888889 | 0.1666666667 | 0.1333333333 | |
Person 19 | 2 | 0.3614457831 | 0.2048192771 | 0.1445783133 | 0.1686746988 | 0.1204819277 | 0.2830188679 | 0.2264150943 | 0.1886792453 | 0.1603773585 | 0.141509434 | |
Person 20 | 2 | 0.3333333333 | 0.2222222222 | 0.1666666667 | 0.1666666667 | 0.1111111111 | 0.3684210526 | 0.2631578947 | 0.2105263158 | 0.1052631579 | 0.0526315789 | |
Person 21 | 2 | 0.2830188679 | 0.2358490566 | 0.1886792453 | 0.2169811321 | 0.0754716981 | 0.4 | 0.28 | 0.16 | 0.1 | 0.06 | |
Person 22 | 2 | 0.3539823009 | 0.2212389381 | 0.1769911504 | 0.1592920354 | 0.0884955752 | 0.4838709677 | 0.3225806452 | 0.1075268817 | 0.0537634409 | 0.0322580645 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
g { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.x.axis path { | |
display: none; | |
} | |
.line { | |
fill: none; | |
stroke: #bbb; | |
stroke-width: 1px; | |
opacity: .5; | |
} | |
.line.active { | |
stroke-width: 5px; | |
stroke: #444 | |
} | |
.group-2 { | |
fill: none; | |
stroke: #bb0; | |
stroke-width: 1px; | |
} | |
.group-2.active { | |
stroke-width: 5px; | |
stroke: #880; | |
} | |
.zeroline { | |
fill: none; | |
stroke: red; | |
stroke-width: 3px; | |
} | |
.pie { | |
fill: green; | |
stroke: #222; | |
opacity: .5; | |
} | |
.pie.active { | |
fill: #222; | |
opacity: 1; | |
} | |
.bar { | |
fill: blue; | |
stroke: #222; | |
opacity: .5; | |
} | |
.bar.active { | |
fill: #222; | |
opacity: 1; | |
} | |
.vertical { | |
stroke-width: 3px; | |
opacity: 1; | |
} | |
.vertical.bar { | |
stroke: blue; | |
} | |
.vertical.pie { | |
stroke: green; | |
} | |
.vertical.active { | |
stroke-width: 5px; | |
} | |
.group { | |
font-size: 2em; | |
} | |
.g1 { | |
border:1px solid #bbb; | |
} | |
.g2 { | |
border:1px solid #bb0; | |
} | |
.e.pie { | |
border:3px solid green; | |
padding: 2px; | |
opacity: 1; | |
} | |
.e.bar { | |
border:3px solid blue; | |
padding: 2px; | |
opacity: 1; | |
} | |
p { | |
font: 1em sans-serif; | |
} | |
</style> | |
<body> | |
<h1>Pie chart vs. Bar chart figth</h1> | |
<div id="chart"></div> | |
<p> | |
Experiment conducted on 22 university students divided into 2 groups (11 each). Each group was shown 1 pie chart and 1 bar chart showing election results. The students were asked to estimate the percentage won by each party (later rescaled to sum 100%). | |
</p> | |
<p> | |
The chart above summarizes the experiment's results: | |
<ul> | |
<li>Every point is one error of estimate (by one student)</li> | |
<li>Green circles are error of estimates based on a pie chart</li> | |
<li>Blue squares are error of estimates based on a bar chart</li> | |
<li>Horizontal lines connect estimates by one person, colored by the election</li> | |
<li>Vertical lines show variance, the 2 extreme error of estimates in each groups are taken away</li> | |
<li>Green lines are for error of estimates from pie chart, blue lines are for bar chart</li> | |
<li>The values on x-axis are slightly randomly moved, so the overlapped points may be visible.</li> | |
</ul> | |
</p> | |
<p> | |
There is no clear evidence that any of the charts performs better, the results are slightly better for pie charts. But the sample is not big enough for better conclusions. | |
</p> | |
<p>The actual file used for the experiment is <a href="https://docs.google.com/document/d/1YqkQzXvi79k_Uoe_MFKD5uWy2oLxvnQkKU7TWc5y4qo/pub">here</a>. The table below shows the experimental design:</p> | |
<table> | |
<tr><th></th><th><span class="group g1">Election 1</span></th><th><span class="group g2">Election 2</span></th></th> | |
<tr><td><span class="group">Group 1:</span></td><td class="e pie"><image src="volby1998_2.png" title="Election 1, pie" /></td><td class="e bar"><image src="volby2002.png" title="Election 2, bar" /></td></tr> | |
<tr><td><span class="group">Group 2:</span></td><td class="e bar"><image src="volby1998.png" title="Election 1, bar" /></td><td class="e pie"><image src="volby2002_2.png" title="Election 2, pie" /></td></tr> | |
</table> | |
<p>The real values were:<br/> | |
Election 1: 0.2910, 0.2499, 0.1804, 0.1793, 0.0994<br/> | |
Election 2: 0.3024, 0.2450, 0.1853, 0.1429, 0.1244 | |
</p> | |
<script src="http://d3js.org/d3.v3.js"></script> | |
<script> | |
var realvalues = [ | |
[0.2910,0.2499,0.1804,0.1793,0.09935], | |
[0.3024,0.2450,0.1853,0.1429,0.1244] | |
]; | |
var margin = {top: 20, right: 20, bottom: 30, left: 50}, | |
width = 960 - margin.left - margin.right, | |
height = 400 - margin.top - margin.bottom; | |
var x = d3.scale.linear() | |
.range([0, width]) | |
.domain([0.05,0.35]); | |
var y = d3.scale.linear() | |
.range([height, 0]) | |
.domain([-0.15,0.2]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left"); | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
.append("text") | |
.attr("x", x(.35)) | |
.attr("dx", ".71em") | |
.style("text-anchor", "end") | |
.text("Real values of percentage"); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("Errors of Estimates"); | |
var line = d3.svg.line() | |
.x( | |
function(d) { | |
return d[0]; }) | |
.y(function(d) { return d[1]; }); | |
zeroline = Array([x(0.05),y(0)],[x(0.35),y(0)]); | |
var r = 3; | |
svg.append("path") | |
.datum(zeroline) | |
.attr("class", "zeroline") | |
.attr("d", line); | |
d3.csv("data.csv", function(error, data) { | |
points = [[],[]]; // 2 groups | |
realvalues.forEach(function(rd,ri) { | |
pdata = [[],[]]; // 2 chart types | |
for (i in realvalues[ri]) { | |
pdata[0][i] = []; | |
pdata[1][i] = []; | |
} | |
data.forEach(function(d) { | |
rdata = Array(); | |
for (i in realvalues[ri]) { | |
xx = realvalues[ri][i] + Math.random()/200-0.0025; | |
if (ri == 0) letter = "a"; | |
else letter = "b"; | |
k = parseInt(i) + 1; | |
yy = +d[letter+k]-realvalues[ri][i]; | |
rdata.push([x(xx),y(yy)]); | |
//type of chart: | |
if (((d.group == "1") && (ri == 0)) || ((d.group == "2") && (ri == 1))) | |
ct = 1; //bar | |
else | |
ct = 0; //pie | |
points[ct].push([xx,yy]); | |
pdata[ct][parseInt(i)].push(yy); | |
} | |
svg.append("path") | |
.datum(rdata) | |
.attr("class", function() {if (ri == 1) return "line group-2"; else return "line"}) | |
.attr("d", line) | |
.attr("title",d.name) | |
.on("mouseover", function() { | |
d3.select(this) | |
.classed("active", true ) // should then accept fill from CSS | |
}) | |
.on("mouseout", function() { | |
d3.select(this) | |
.classed("active", false) | |
}); | |
}); | |
//vertical lines | |
for (ct in pdata) { | |
for (i in pdata[ct]) { | |
pdata[ct][i] = pdata[ct][i].sort(compareNumbers); | |
} | |
} | |
//prepare ends (eliminate extremes) | |
pends = [[],[]]; //2 charts | |
pmid = [[],[]]; | |
for (ct in pdata) { | |
for (i in pdata[ct]) { | |
pends[ct][i] = []; | |
pends[ct][i].push([x(realvalues[ri][parseInt(i)])+3*parseInt(ct),y(pdata[ct][i][1])]); | |
pends[ct][i].push([x(realvalues[ri][parseInt(i)])+3*parseInt(ct),y(pdata[ct][i][pdata[ct][i].length-2])]); | |
pmid[ct][i] = [realvalues[ri], pdata[ct][i][Math.round(pdata[ct][i].length/2-1)]]; //approx, ok for odd numbers | |
svg.append("path") | |
.datum(pends[ct][i]) | |
.attr("class", function() {if (ct == "1") return "vertical bar"; else return "vertical pie"}) | |
.attr("d", line) | |
//.attr("title",d.name) | |
.on("mouseover", function() { | |
d3.select(this) | |
.classed("active", true ) // should then accept fill from CSS | |
}) | |
.on("mouseout", function() { | |
d3.select(this) | |
.classed("active", false) | |
}); | |
} | |
} | |
}); | |
//points | |
svg.selectAll('circle') | |
.data(points[0]) | |
.enter().append('circle') | |
.attr("cx", function(d) {return x(d[0]) }) | |
.attr("cy", function(d) {return y(d[1]) }) | |
.attr("r", 3) | |
.attr("class", "pie") | |
.attr("title",function(d) {return "Error of colour estimate: " + Math.round(d[1]*1000)/10 + "% (percentage points)"}) | |
.on("mouseover", function() { | |
d3.select(this) | |
.classed("active", true ) | |
}) | |
.on("mouseout", function() { | |
d3.select(this) | |
.classed("active", false) | |
}); | |
svg.selectAll('rect') | |
.data(points[1]) | |
.enter().append('rect') | |
.attr("x", function(d) {return x(d[0]) - r }) | |
.attr("y", function(d) {return y(d[1]) - r}) | |
.attr("height", 2*r) | |
.attr("width", 2*r) | |
.attr("class", "bar") | |
.attr("title",function(d) {return "Error of colour estimate: " + Math.round(d[1]*1000)/10 + "% (percentage points)"}) | |
.on("mouseover", function() { | |
d3.select(this) | |
.classed("active", true ) | |
}) | |
.on("mouseout", function() { | |
d3.select(this) | |
.classed("active", false) | |
}); | |
}); | |
function compareNumbers(a, b) { | |
return a - b; | |
} | |
</script> | |
<script> | |
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | |
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | |
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | |
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); | |
ga('create', 'UA-8592359-13', 'ocks.org'); | |
ga('send', 'pageview'); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment