The original intent of this plot was to explore election victory margin and presidential rating, with the idea being that higher rated presidents should have been voted into office on a higher margin of victory. After some additional thinking, I realized that the original premise was flawed - every presidential election should be treated as a contest of its own, between the two contenders, and can't really be held in comparison to other elections. However, it was still a fun data scraping and visualization exercise. The results of the exercise are in the visualization/code seen.
Each presidential election has been shown, plotting margin of popular vote victory against a ranking of the Presidents' effectivness (data from the 2014 American Political Science Association’s Presidents & Executive Politics ranking of American presidents). There's a 0.15 Pearson's r correlation between margin of victory and presidential ranking. If I'm to draw a conclusion based on a flawed premise, it'd be that the American people are rather poor at picking presidents. I think a more interesting investigation would be one comparing data across different styles of ruling - democracy, communism, and dictatorships - and trying to find a metric to compare them. That will have to be for next time.
xxxxxxxxxx
<meta charset="utf-8">
<style>
.axis--y path {
display: none;
}
.focus text {
text-anchor: middle;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
#form {
position: absolute;
top: 20px;
right: 30px;
}
.dot {
stroke: #000;
stroke-opacity: 0.8;
opacity: 0.8;
}
.tooltip {
background-color: #f7f7f7;
padding: 3px 12px;
font-family: sans-serif;
border: 1px solid #bbbbbb;
box-shadow: 1px 1px 4px #bbbbbb;
}
.tooltip {
/* width: 200px;
height: 80px;*/
pointer-events: none;
word-wrap: normal;
}
.tooltip_title {
font-weight: bold;
font-size: 14px;
margin: 5px 0;
max-width: 300px;
word-wrap: normal;
}
.tooltip_body {
font-weight: normal;
margin: 5px 0;
}
</style>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 20, right: 30, bottom: 50, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleLinear()
.range([margin.left, width]);
var y = d3.scaleLinear()
.range([height, margin.top]);
var x_axis,
y_axis;
var xAxis = d3.axisBottom(x)
.ticks(10, "%")
var yAxis = d3.axisLeft(y)
.ticks(10, "%")
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 + ")");
// var xValue = function(d) { return d.rel_time;},
// xMap = function(d) { return x(xValue(d));};
// var yValue = function(d) { return d.pred;}, // data -> value
// yMap = function(d) { return y(yValue(d));}; // data -> display
var z = d3.scaleOrdinal(d3.schemeCategory10);
var cValue = function(d) { return d.Party;},
color = d3.scaleOrdinal(d3.schemeCategory10);
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("opacity", 0)
.style("z-index", "10");
var title = svg.append("text")
.attr("x", (width / 2))
.attr("y", 0)
.attr("text-anchor", "middle")
.style("font-size", "20px")
.style("font-family","sans-serif")
.text("Margin of Voting Victory vs. Presidential Rating");
d3.csv("vote.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year
d.PopVoteMarginPer = +d.PopVoteMarginPer/100;
d.ECMarginPer = +d.ECMarginPer/100
d.Rating = +d.Rating/100;
});
console.log(d3.extent(data, function(d) { return d.PopVoteMarginPer; }));
x.domain(d3.extent(data, function(d) { return d.PopVoteMarginPer; }));
y.domain(d3.extent(data, function(d) { return d.Rating; }));
// draw dots
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 4)
.attr("cx", function(d) {return x(d.PopVoteMarginPer); })
.attr("cy", function(d) {return y(d.Rating); })
.style("fill", function(d) {
console.log(d)
return color(cValue(d));})
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html("")
.style("left", (d3.event.pageX + 18) + "px")
.style("top", (d3.event.pageY - 52) + "px");
tooltip.append("h3").attr("class", "tooltip_title");
tooltip.append("pre").attr("class", "tooltip_body");
tooltip.select(".tooltip_title")
.text(d.Winner)
tooltip.select(".tooltip_body")
.text(
"Party: " + d.Party + "\n" +
"Year: " + d.Year + "\n" +
"Runner-Up: " + d.RunnerUp
)
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
// draw legend
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
// draw legend colored rectangles
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
// draw legend text
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.style("font-family","sans-serif")
.text(function(d) { return d;})
x_axis = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("transform", "translate(" + width/2 + ",35)")
.attr("class", "axis_title")
.text("Margin of Election Victory")
.style("fill", "#000")
.style("font-size", "14px")
y_axis = svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "translate(-" + margin.left + ",170) rotate(-90)")
.attr("class", "axis_title")
.text("Presidential Ranking")
.style("fill", "#000")
.style("font-size", "14px")
});
</script>
https://d3js.org/d3.v4.min.js