Skip to content

Instantly share code, notes, and snippets.

@mgold
Last active April 17, 2016 22:04
Show Gist options
  • Save mgold/0b8095061527f6e329479ed5cdf8acba to your computer and use it in GitHub Desktop.
Save mgold/0b8095061527f6e329479ed5cdf8acba to your computer and use it in GitHub Desktop.
Brady Campaign vs. the NRA on Senators

This scatterplot shows how the pro-gun NRA and the pro-gun-control Brady Campaign rank U.S. senators. The size of the dot is proportional to the number of senators; hover over to see them. Not surprisingly, there's a strong negative correlation.

Each scatter dot is actually a pie chart, but I am saved from the wrath of the datavis gods by political polarization: there are no Democrats and Republicans that share a stance.

The data were surpringly hard to come by but were sourced from VoteSmart (Brady) and The Washington Post (NRA).

Built with blockbuilder.org.

state senator party brady nra
AL Richard Shelby Republican 0 A+
AL Jeff Sessions Republican 8 A+
AZ John McCain Republican 11 B+
CA Dianne Feinstein Democratic 100 F
CA Barbara Boxer Democratic 100 F
GA Johnny Isakson Republican 0 A
IA Chuck Grassley Republican 11 A
ID Mike Crapo Republican 0 A+
IL Dick Durbin Democratic 100 F
KS Pat Roberts Republican 8 A
KS Jerry Moran Republican 60 A
KY Mitch McConnell Republican 5 A
LA David Vitter Republican 20 A
MA Ed Markey Democratic 100 F
MD Barbara Mikulski Democratic 100 F
MD Ben Cardin Democratic 100 F
ME Susan Collins Republican 17 C+
MO Roy Blunt Republican 0 A
MS Thad Cochran Republican 5 A
MS Roger Wicker Republican 0 A+
NC Richard Burr Republican 17 A
NJ Bob Menendez Democratic 91 F
NM Tom Udall Democratic 80 C
NV Harry Reid Democratic 74 B
NY Chuck Schumer Democratic 100 F
OH Sherrod Brown Democratic 100 F
OH Rob Portman Republican 18 A
OK Jim Inhofe Republican 0 A+
OR Ron Wyden Democratic 100 F
PA Pat Toomey Republican 0 A
RI Jack Reed Democratic 100 F
SC Lindsey Graham Republican 0 A
SD John Thune Republican 20 A+
UT Orrin Hatch Republican 5 A+
VT Patrick Leahy Democratic 47 C
VT Bernie Sanders Independent 71 D-
WA Patty Murray Democratic 89 F
WI Tammy Baldwin Democratic 100 F
WY Mike Enzi Republican 8 A
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0;font: 10px sans-serif; }
svg { width:100%; height: 100% }
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.arrow {
stroke: #000;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<script>
var margin = {top: 30, right: 40, bottom: 40, left: 30},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 100])
.range([0, width-5])
var y = d3.scale.ordinal()
.domain(["A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"])
.rangeRoundPoints([height, 0])
var r = d3.scale.sqrt()
.domain([1, 15])
.range([4, 20])
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("right");
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var plot = svg.append("g")
var axesG = svg.append("g")
var overlayG = svg.append("g").style("font-size", "16px")
axesG.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.text("Brady Campaign To End Gun Violence - Percentage Approval")
.attr({dx: width/2 + "px", dy: "30px"})
.style("text-anchor", "middle")
axesG.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ",0)")
.call(yAxis)
.append("text")
.text("National Rifle Association - Letter Grade")
.attr({dx: -height/2 + "px", dy: "30px", transform: "rotate(-90)"})
.style("text-anchor", "middle")
// The circles are actually pie charts, but the data contains no overlap
var pie = d3.layout.pie();
var arc = d3.svg.arc().innerRadius(function(){return 0});
d3.csv("gun_data.csv", function(err, data){
if (err) return console.error(err);
var map = d3.map();
data.forEach(function(d){
var key = [d.brady, d.nra]
var oldVal = map.get(key) || [];
oldVal.push(d)
map.set(key, oldVal)
})
plot.selectAll(".data")
.data(map.values())
.enter()
.append("g")
.attr("transform", function(a){
var dx = x(+a[0].brady);
var dy = y(a[0].nra);
return "translate("+dx+","+dy+")"
})
.each(function(a){
var reps = a.filter(function(d){return d.party == "Republican"}).length;
var dems = a.filter(function(d){return d.party == "Democratic"}).length;
var inds = a.filter(function(d){return d.party == "Independent"}).length;
pieSlices = pie([reps, dems, inds]);
var sel = d3.select(this);
arc.outerRadius(function(){return r(a.length)})
sel.selectAll("path")
.data(pieSlices)
.enter()
.append("path")
.attr("d", arc)
.attr("fill", function(d, i){return ["#FF4136", "#0074D9", "#AAAAAA"][i]})
})
.on("mouseleave", function(a){
overlayG.selectAll("*").remove();
})
.on("mouseenter", function(a){
overlayG.append("text")
.text("NRA: "+ a[0].nra + " Brady: " + a[0].brady+"%")
overlayG.selectAll("foo")
.data(a)
.enter()
.append("text")
.text(function(d){
return d.senator + " " + d.party.charAt(0) + "-" + d.state
})
.attr("dx", 10)
.attr("dy", function(d, i){ return (i+1) * 20})
})
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment