This graph plots the observed rate of tweets for Eric Fischer’s Twitter feed over the period from January 8, 2015 through November 30, 2015 with a LOESS curve fitted to the data using science.js.
Forked from mbostock's block: Time of Day
Draws from the example Loess with science.js for adding the LOESS curve.
Part of a discussion on d3-shape: Moving averages, line smoothing, etc. #43.
xxxxxxxxxx
<meta charset="utf-8">
<style>
.dots path {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis--y line {
stroke-opacity: 0.2;
}
.axis--y path {
stroke: none;
}
.axis text {
font: 10px sans-serif;
}
.loess {
stroke: #000;
stroke-width: 3px;
fill: none;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="science.v1.min.js"></script>
<script>
var parseTime = d3.time.format.utc("%H:%M").parse,
midnight = parseTime("00:00");
var margin = {top: 30, right: 30, bottom: 30, left: 30},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.time.scale.utc()
.domain([midnight, d3.time.day.utc.offset(midnight, 1)])
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var line = d3.svg.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.rateSmooth); });
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("tweets.csv", type, function(error, data) {
if (error) throw error;
y.domain([0, d3.max(data, function(d) { return d.rate; })]);
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format.utc("%I %p")));
svg.append("g")
.attr("class", "dots")
.selectAll("path")
.data(data)
.enter().append("path")
.attr("transform", function(d) { return "translate(" + x(d.time) + "," + y(d.rate) + ")"; })
.attr("d", d3.svg.symbol()
.size(40));
var tick = svg.append("g")
.attr("class", "axis axis--y")
.call(d3.svg.axis()
.scale(y)
.tickSize(-width)
.orient("left"))
.select(".tick:last-of-type");
var title = tick.append("text")
.attr("dy", ".32em")
.text("tweets per hour");
tick.select("line")
.attr("x1", title.node().getBBox().width + 6);
var loess = science.stats.loess().bandwidth(.1);
data.sort(function (a, b){ return a.time < b.time ? -1 : 1 });
var xValues = data.map(function (d){ return d.time; });
var yValues = data.map(function (d){ return d.rate; });
var pathData = loess(xValues, yValues).map(function (yValue, i){
return {
time: data[i].time,
rateSmooth: yValue
};
});
svg.selectAll(".loess")
.data([pathData])
.enter().append("path")
.attr("class", "loess")
.attr("d", line);
});
function type(d) {
d.rate = +d.count / 327 * 60; // January 8 to November 30
d.time = parseTime(d.time);
d.time.setUTCHours((d.time.getUTCHours() + 24 - 7) % 24);
return d;
}
</script>
https://d3js.org/d3.v3.min.js