D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
natemiller
Full window
Github gist
California Annual Maximum and Minimum Temperatures 1895-2014
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>CA Historical Temperature (1895-2014)</title> <script type="text/javascript" src="https://d3js.org/d3.v3.js"></script> <style type="text/css"> body { font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; background-color: white; padding: 50px; } h1 { margin-left: 50px; } p { max-width: 1000px; margin-left: 50px; } figure { display: block; margin-top: 1em; margin-bottom: 1em; margin-left: 40px; margin-right: 40px; } figcaption { padding: 5px; font-family: ; font-size: 0.8em; font-weight: 700; border: none; background: transparent; word-wrap:normal; text-align: center; } em { color: black; font-weight: bold; font-style: italic; } em1 { color: steelblue; font-weight: bold; font-style: italic; } em2 { color: tomato; font-weight: bold; font-style: italic; } svg { background-color: white; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { fill: none; stroke: #000; shape-rendering: crispEdges; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } .highlight { stroke: #fc0; } </style> </head> <body> <h1>Historical Temperature Patterns for California</h1> <p>Temperature anomalies are calculated by comparing measured values to a baseline to detect changes relative to that baseline. Using data from the Western Regional Climate Center <a href="https://www.wrcc.dri.edu/monitor/cal-mon/frames_version.html">www.wrcc.dri.edu</a>, I explored the temperature anomaly for both the maximum yearly temperature and the minimum yearly temperature in California, USA. The anomaly for both is calculated as the difference between the yearly maximum (or minimum) and a baseline <em>(in this case set as the average maximum (or minimum) for the period between 1949 and 2005)</em>. Thus generally, positive anomalies represent years that are warmer than the baseline period and negative anomalies represent years that are cooler. </p> <script type="text/javascript"> //Temperature anomaly plot var margin = {top: 20, right: 250, bottom: 50, left: 70}, width = 1200 - margin.left - margin.right, height = 700 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height-5, 0]); var curve = d3.scale.ordinal(); var color = d3.scale.ordinal() .range([ "tomato","steelblue"]) .domain(d3.range(0,1)); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .defined(function(d) { return !isNaN(d.Temperature); }) .interpolate("cubic") .x(function(d) { return x(d.Year); }) .y(function(d) { return y(d.Temperature); }); var svg = d3.select("body").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 + ")"); d3.csv("CA_temps_C_anomaly.csv", function(error, data) { curve.domain(d3.keys(data[0]).filter(function(key) { return key !== "Year"; })); data.forEach(function(d) { d.Year = parseDate(d.Year); }); var sources = curve.domain().map(function(name) { return { name: name, values: data.map(function(d) { return {Year: d.Year, Temperature: +d[name]}; }) }; }); x.domain(d3.extent(data, function(d) { return d.Year;})); y.domain([ d3.min(sources, function(c) { return d3.min(c.values, function(v) { return v.Temperature; }); }), d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.Temperature; }); }) ]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .append("text") .attr("y", margin.bottom/1) //smaller divider moves down .attr("x",width/2) .text("Year") .attr("font-family","serif") .attr("font-size","16px"); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y",-margin.top*3.3) //bigger mulitplier moves to the left .attr("x",-height/2) //smaller divider moves up .attr("dy", ".71em") .style("text-anchor", "middle") .text("Maximum Temperature Anomaly - Minimum Temperature Anomaly (C)") .attr("font-family","serif") .attr("font-size","16px"); var source = svg.selectAll(".source") .data(sources) .enter().append("g") .attr("class", "sourceDelta"); source.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke",function(d) {return color(d.name);}) .style("stroke-width", "3px") source.append("text") .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) //.attr("transform", function(d) { return "translate(" + x(d.value.Year) + "," + y(d.value.Temperature) + ")"; }) .attr("x", 50) .attr("y", function(d, i) {return 30 * i;}) .style("stroke",function(d) {return color(d.name);}) .style("fill", function(d) {return color(d.name);}) .text(function(d) { return d.name; }) .style("font-size", 18) source.append('svg:line') .attr("x1", 0) .attr("y1", 347) .attr("x2", 900) .attr("y2", 347) .style("stroke", "rgb(6,120,155)") .style("stroke-width", "2px"); }); </script> <!-- Delta Temperature Anomaly--> <h2>Minimum temperatures increasing more than Maximum temperatures?</h2> <p>Here I have gone a step further and calculated the difference between the maximum anomaly and the minimum anomaly (the difference between the <em2>red</em2> and <em1>blue</em1> lines in the figure above). This value tells us something about what might be accounting for shifts in temperature. In this case, negative values represent periods where the difference between maximum yearly temperature its baseline was less than the difference between the minimum yearly value and its baseline. This means that during periods when this value is negative, even though we may be seeing increases in maximum temperatures, we are seeing even greater increases in minimum temperatures. </p> <p><em>(Take home: While it may be getting hotter, its also getting less cold)</em> </p> <body> <script type="text/javascript"> var margin = {top: 20, right: 250, bottom: 50, left: 70}, width = 1200 - margin.left - margin.right, height = 700 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height-5, 0]); var curve = d3.scale.ordinal(); var colorDelta = d3.scale.ordinal() .range(["lightgreen"]) .domain(d3.range(0,1)); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var lineDelta = d3.svg.line() .defined(function(d) { return !isNaN(d.Temperature); }) .interpolate("cubic") .x(function(d) { return x(d.Year); }) .y(function(d) { return y(d.Temperature); }); var svgDelta = d3.select("body").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 + ")"); d3.csv("CA_temps_C_anomaly_diff.csv", function(error, data) { curve.domain(d3.keys(data[0]).filter(function(key) { return key !== "Year"; })); data.forEach(function(d) { d.Year = parseDate(d.Year); }); var sourcesDelta = curve.domain().map(function(name) { return { name: name, values: data.map(function(d) { return {Year: d.Year, Temperature: +d[name]}; }) }; }); x.domain(d3.extent(data, function(d) { return d.Year;})); y.domain([ d3.min(sourcesDelta, function(c) { return d3.min(c.values, function(v) { return v.Temperature; }); }), d3.max(sourcesDelta, function(c) { return d3.max(c.values, function(v) { return v.Temperature; }); }) ]); svgDelta.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .append("text") .attr("y", margin.bottom/1) //smaller divider moves down .attr("x",width/2) .text("Year") .attr("font-family","serif") .attr("font-size","16px"); svgDelta.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y",-margin.top*3.3) //bigger mulitplier moves to the left .attr("x",-height/2) //smaller divider moves up .attr("dy", ".71em") .style("text-anchor", "middle") .text("Maximum Temperature Anomaly - Minimum Temperature Anomaly (C)") .attr("font-family","serif") .attr("font-size","16px"); var sourceDelta = svgDelta.selectAll(".sourceDelta") .data(sourcesDelta) .enter().append("g") .attr("class", "sourceDelta"); sourceDelta.append("path") .attr("class", "line") .attr("d", function(d) { return lineDelta(d.values); }) .style("stroke",function(d) {return colorDelta(d.name);}) .style("stroke-width", "3px") sourceDelta.append("text") .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) .attr("transform", function(d) { return "translate(" + x(d.value.Year) + "," + y(d.value.Temperature) + ")"; }) .attr("x", 5) .attr("dy", "3em") .style("stroke",function(d) {return colorDelta(d.name);}) .style("fill", function(d) {return colorDelta(d.name);}) .style("font-size", 18) sourceDelta.append('svg:line') .attr("x1", 0) .attr("y1", 307) .attr("x2", 900) .attr("y2", 307) .style("stroke", "rgb(6,120,155)") .style("stroke-width", "2px"); }); </script>
Modified
http://d3js.org/d3.v3.js
to a secure url
https://d3js.org/d3.v3.js