Skip to content

Instantly share code, notes, and snippets.

@GerardoFurtado
Last active January 1, 2016 03:57
Show Gist options
  • Save GerardoFurtado/7134b3f76a6b03b9a166 to your computer and use it in GitHub Desktop.
Save GerardoFurtado/7134b3f76a6b03b9a166 to your computer and use it in GitHub Desktop.
Australian energy: scatter plot
year Coal Oil and LPG Gas Renewables Uranium
1977 2146 977 256 200 231
1978 2200 1016 283 202 234
1979 2229 1005 315 200 323
1980 2286 960 363 194 386
1981 2637 934 416 207 1066
1982 2798 909 462 212 2363
1983 2988 894 466 205 2177
1984 3143 1076 490 203 2082
1985 3573 1248 523 215 2055
1986 3947 1281 571 217 2092
1987 4360 1270 588 217 2117
1988 4035 1261 611 221 1971
1989 4426 1145 628 231 2140
1990 4685 1284 797 235 1922
1991 4880 1276 840 239 2063
1992 5177 1254 932 225 2044
1993 5245 1236 978 247 1271
1994 5261 1171 1065 255 1293
1995 5665 1250 1175 262 1237
1996 5746 1216 1204 272 2399
1997 6139 1249 1226 285 2818
1998 6617 1374 1276 283 2725
1999 6663 1136 1333 283 3002
2000 7046 1502 1317 267 3902
2001 7549 1540 1375 266 4535
2002 7952 1458 1389 257 3782
2003 8019 1422 1462 277 4311
2004 8262 1262 1463 279 4497
2005 8792 1135 1638 280 5153
2006 8887 1027 1701 284 4688
2007 9360 1146 1801 288 4507
2008 9384 1055 1875 286 4758
2009 9761 1083 1961 261 4846
2010 10519 1057 2084 297 3341
2011 9970 1059 2225 299 3322
2012 10632 993 2134 295 3599
2013 11438 882 2439 329 4229
<!DOCTYPE html>
<html lang="en">
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=PT+Serif' rel='stylesheet' type='text/css'>
<meta charset="utf-8">
<title>Australian energy: scatter plot</title>
<style type="text/css">
body {
background-color: white;
font-family: 'PT Serif', serif;
}
#container {
width: 1000px;
margin-left: auto;
margin-right: auto;
margin-top: 5px;
margin-bottom: 0px;
padding-bottom: 0px;
padding: 1px 10px 10px 10px;
background-color: white;
box-shadow: 1px 1px 1px 1px #fff;
}
h1 {
font-weight: 300;
color: #3e4a54;
font-size: 48px;
font-family: "Roboto";
margin-bottom: 20px;
margin-top: 10px;
}
h2 {
font-weight: 300;
color: #3e4a54;
font-size: 32px;
margin-bottom: 0px;
padding-bottom: 0px;
margin-top: 15px;
font-family: "Roboto";
}
p {
font-size: 16px;
width: 900px;
}
a {
color: steelblue;
}
a:hover {
color: darkslategray;
}
.footer {
font-size: 14px;
margin-top: 0px;
}
circle:hover {
fill: maroon;
}
select {
-webkit-appearance: button;
-moz-appearance: button;
-webkit-user-select: none;
-moz-user-select: none;
-webkit-padding-end: 10px;
-moz-padding-end: 10px;
-webkit-padding-start: 2px;
-moz-padding-start: 2px;
background-color: whitesmoke;
border: 1px solid #AAA;
border-radius: 4px;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
color: #555;
font-family: "Roboto";
font-size: 16px;
margin: 0;
overflow: hidden;
padding-top: 2px;
padding-bottom: 2px;
text-overflow: ellipsis;
white-space: nowrap;
}
#menu2 {
margin-left: 10px;
}
div.tooltip {
position: absolute;
text-align: center;
white-space: normal;
padding: 2px;
font-size: 14px;
background: whitesmoke;
border: 1px solid gray;
border-radius: 4px;
pointer-events: none;
cursor: none;
}
svg {
background-color: white;
}
.axis path, .axis line {
opacity: 1;
fill: none;
stroke: #4e5a64;
shape-rendering: crispEdges;
}
.axis text {
fill: #4e5a64;
font-size: 10px;
}
</style>
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
</head>
<body>
<div id="container">
<h1>Australian energy by fuel type</h1>
<img src="http://proecogroup.eu/sites/default/files/images/proecogroupPropjekty.jpg">
<h2>A scatter plot</h2>
<p>The following scatter plot was created using d3.js. I colected data regarding the amount of energy produced from five sources - coal, oil, uranium, gas and renewable sources - in Australia, from 1977 to 2013, in Petajoules (10<sup>15</sup> Joules). You can choose any two of these sources to create the scatter plot, each axis showing the corresponding amount of energy. The circles are connected by their chronological sequence. So, this is a <em>connected scatter plot</em>.</p>
<p>Choose the energy sources on the menu below. The first source uses the x-axis, the second source uses the y-axis (initial values are Coal and Oil). Please realize that the scales are different. Hover over the circles to see more details.</p>
<div class="dropdowns">
<select name="menu1" id="menu1">
<option value="Coal">Choose the 1st source</option>
<option value="Coal">Coal</option>
<option value="Oil and LPG">Oil and LPG</option>
<option value="Gas">Gas</option>
<option value="Renewables">Renewables</option>
<option value="Uranium">Uranium</option>
</select>
<select name="menu2" id="menu2">
<option value="Oil and LPG">Choose the 2nd source</option>
<option value="Coal">Coal</option>
<option value="Oil and LPG">Oil and LPG</option>
<option value="Gas">Gas</option>
<option value="Renewables">Renewables</option>
<option value="Uranium">Uranium</option>
</select>
</div>
<br>
<div id="svganchor"></div>
<p>Scatter plots give a good visual image of the relationship between two sets of data. As this is a paired time series, you'll have to follow the path to see how each source behaves. An excellent explanation can be found <a href="https://eagereyes.org/papers/the-connected-scatterplot-for-presenting-paired-time-series">here</a></p>
<p>Source of the data: <a href="http://www.industry.gov.au/Office-of-the-Chief-Economist/Publications/Pages/Australian-energy-statistics.aspx#">Department of Industry and Science</a></p>
<p class="footer">Created by Gerardo Furtado.</p>
<br>
</div>
<script type="text/javascript">
var w = 520
var h = 500
var padding = [ 5, 5, 20, 40 ]; //Top, right, bottom, left
var xScale = d3.scale.linear()
.range([ padding [3], w - padding[1] ]);
var yScale = d3.scale.linear()
.range([ padding[0], h - padding[2] ]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.outerTickSize(0)
.ticks(10);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.outerTickSize(0)
.ticks(10);
var svg = d3.select("#svganchor")
.append("svg")
.attr("width", w)
.attr("height", h);
var label1 = svg.append("text").attr("fill", "gray"), label2 = svg.append("text").attr("fill", "gray");
var colors = d3.scale.ordinal()
.domain(["Coal", "Oil and LPG", "Gas", "Uranium", "Renewables"])
.range(['#1b9e77','#d95f02','#7570b3','#e7298a','#66a61e']);
var source1 = "Coal";
var source2 = "Oil and LPG";
var tt = d3.select("#svganchor").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var yline = svg.append("line")
.attr("stroke", "gray")
.attr("stroke-dasharray", "1,2");
var xline = svg.append("line")
.attr("stroke", "gray")
.attr("stroke-dasharray", "1,2");
d3.csv("australianenergyb.csv", function(data) {
d3.select("#menu1").on("change", function(){
source1 = menu1.value;
source2 = menu2.value;
d3.selectAll("circle").remove();
d3.selectAll(".cline").remove();
redraw();
});
d3.select("#menu2").on("change", function(){
source1 = menu1.value;
source2 = menu2.value;
d3.selectAll("circle").remove();
d3.selectAll(".cline").remove();
redraw();
});
redraw();
function redraw(){
var circs = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
var lines = svg.selectAll(".cline")
.data(data)
.enter()
.append("line")
.attr("class", "cline");
xScale.domain([ 0, d3.max(data, function(d) {
return +d[source1];
}) * 1.1]);
yScale.domain([ d3.max(data, function(d) {
return +d[source2];
}) * 1.1, 0]);
circs.attr("cx", function(d) {
return xScale(d[source1])
})
.attr("cy", function(d) {
return yScale(d[source2]);
})
.attr("r", 0.1)
.attr("fill", "white")
.attr("stroke-width", 0.1)
.attr("stroke", colors(source1));
circs.sort(function(a, b) {
return d3.ascending(+a.year, +b.year);
})
.transition()
.delay(function(d, i) {
return i * 150;
})
.duration(500)
.attr("r", 4)
.attr("stroke-width", 2);
circs.on("mousemove", function(d){
tt.html("&nbspIn " + d.year + ", Australia produced <strong>" + d[source1] + "</strong> Petajoules from " + source1 + "&nbsp<br>&nbspand <strong>" + d[source2] + "</strong> Petajoules from " + source2 + "&nbsp")
.style('top', d3.event.pageY - 12 + 'px')
.style('left', d3.event.pageX + 25 + 'px')
.style("opacity", 0.95);
xline.attr("x1", d3.select(this).attr("cx"))
.attr("y1", d3.select(this).attr("cy"))
.attr("y2", (h - padding[2]))
.attr("x2", d3.select(this).attr("cx"))
.attr("opacity", 1);
yline.attr("x1", d3.select(this).attr("cx"))
.attr("y1", d3.select(this).attr("cy"))
.attr("y2", d3.select(this).attr("cy"))
.attr("x2", padding[3])
.attr("opacity", 1);
});
circs.on("mouseout", function(){
tt.style("opacity", 0);
xline.attr("opacity", 0);
yline.attr("opacity", 0);
});
lines.attr("x1", function(d) {
return xScale(d[source1])
})
.attr("y1", function(d) {
return yScale(d[source2])
})
.attr("x2", function(d) {
//If a next sibling exists…
if (d3.select(this).node().nextSibling) {
//Get the __data__ object for the next (sibling) element
var nextData = d3.select(this).node().nextSibling.__data__;
return xScale(nextData[source1]);
} else {
//Otherwise, just reuse the x1 value
return xScale(d[source1]);
}
})
.attr("y2", function(d) {
//If a next sibling exists…
if (d3.select(this).node().nextSibling) {
//Get the __data__ object for the next (sibling) element
var nextData = d3.select(this).node().nextSibling.__data__;
return yScale(nextData[source2]);
} else {
//Otherwise, just reuse the y1 value
return yScale(d[source2]);
}
})
.style("stroke-width", 0)
.style("stroke", "gray");
lines.sort(function(a, b) {
return d3.ascending(+a.year, +b.year);
})
.transition()
.delay(function(d, i) {
return i * 150;
})
.duration(500)
.style("stroke-width", 0.5);
label1.attr("x", w - 5)
.attr("text-anchor", "end")
.attr("y", h - 30)
.text(source1);
label2.attr("x", -5)
.attr("y", 60)
.attr("text-anchor", "end")
.attr("transform", "rotate(-90)")
.text(source2);
d3.transition(svg).select(".x.axis")
.transition()
.duration(1000)
.call(xAxis);
d3.transition(svg).select(".y.axis")
.transition()
.duration(1000)
.call(yAxis);
}
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (h - padding[2]) +")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (padding[3]) + ",0)")
.call(yAxis);
d3.selectAll(".tick")
.filter(function (d) { return d === 0; })
.remove();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment