Skip to content

Instantly share code, notes, and snippets.

@maartenzam
Last active April 20, 2019 01:42
Show Gist options
  • Save maartenzam/6235b42b9f9ec3851c492082957180d8 to your computer and use it in GitHub Desktop.
Save maartenzam/6235b42b9f9ec3851c492082957180d8 to your computer and use it in GitHub Desktop.
Directional dot plot
license: mit

A technique I sometimes use to indicate direction on a dot plot is connecting the dots with a triangle as an svg path and add a gradient to it. I think it stresses the direction more than a simple arrow because the direction is present on the whole shape (and in the colors), while arrows have only arrowheads to show the direction.

This is a remake of a remake by Jon Schwabish, with data from PEW. As Jon and others suggested: this type of dot plot might be more suited for data that really shows an evolution (fe values for 2015 with values for 2016) then for data that shows a comparison (Trump vs Obama).

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Directional dots</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<h2 style='font-family: sans-serif;'>The World is Questioning Trump's Leadership</h2>
<p style='font-family: sans-serif; font-size: 20px; margin-top: -20px;'>Share confident the President's doing the right thing globally (%)</p>
<div id="viz"></div>
<script>
var margin= {top: 50, right: 30, bottom: 30, left: 50};
var width = 600;
var height = 400;
var svg = d3.select('#viz').append('svg')
.attr('height', height)
.attr('width', width);
var chart = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.attr('id', 'chart');
var obamacolor = '#4286F4';
var trumpcolor = '#E91D0E';
//Gradients to use on the triangles
var defs = svg.append('defs')
var linearGradient = defs
.append('linearGradient')
.attr('id', 'gradient');
linearGradient.append('stop')
.attr('offset', '10%')
.attr('stop-color', trumpcolor);
linearGradient.append('stop')
.attr('offset', '90%')
.attr('stop-color', obamacolor);
var negativeGradient = defs
.append('linearGradient')
.attr('id', 'negative-gradient');
negativeGradient.append('stop')
.attr('offset', '10%')
.attr('stop-color', obamacolor);
negativeGradient.append('stop')
.attr('offset', '90%')
.attr('stop-color', trumpcolor);
d3.csv('trumpobama.csv', function(data){
data.forEach(function(d) {
d.Obama = +d.Obama;
d.Trump = +d.Trump;
d.diff = d.Obama - d.Trump;
});
var y = d3.scaleBand()
.domain(data.map(function(d) { return d.Country; }))
.range([0, (height - margin.bottom)])
.round(false);
var x = d3.scaleLinear()
.domain([0,100])
.range([0, width - margin.left]);
chart.selectAll('path.triangle')
.data(data)
.enter().append('path')
.attr('class', 'triangle')
.attr('d', function(d){
return 'M ' + x(d.Obama) +' '+ y(d.Country) + ' l ' + x(-d.diff) + ' -10 l 0 20 z';
})
.style('fill', function(d){
if (d.diff >= 0) {return 'url(#gradient)'; }
else {return 'url(#negative-gradient)'; }
});
chart.selectAll('circle.obama')
.data(data)
.enter().append('circle')
.attr('cx', function(d){return x(d.Obama); })
.attr('cy', function(d){return y(d.Country); })
.attr('r', 10)
.style('fill', obamacolor)
.style('stroke', 'white')
.style('stroke-width', 2);
chart.selectAll('text.obama')
.data(data)
.enter().append('text')
.text(function(d){ return d.Obama; })
.attr('x', function(d){
if(d.diff >= 0) {
return x(d.Obama) + 12
}
else { return x(d.Obama) - 30}
})
.attr('dy', '0.35em')
.attr('y', function(d){return y(d.Country); })
.style('fill', obamacolor)
.style('font-family', 'sans-serif');
chart.selectAll('circle.trump')
.data(data)
.enter().append('circle')
.attr('cx', function(d){return x(d.Trump); })
.attr('cy', function(d){return y(d.Country); })
.attr('r', 10)
.style('fill', trumpcolor)
.style('stroke', 'white')
.style('stroke-width', 2);
chart.selectAll('text.trump')
.data(data)
.enter().append('text')
.text(function(d){ return d.Trump; })
.attr('x', function(d){
if(d.diff >= 0) {
return x(d.Trump) - 30
}
else { return x(d.Trump) + 12}
})
.attr('dy', '0.35em')
.attr('y', function(d){return y(d.Country); })
.style('fill', trumpcolor)
.style('font-family', 'sans-serif');
chart.selectAll('text.country')
.data(data)
.enter().append('text')
.text(function(d){ return d.Country})
.attr('x', -50)
.attr('y', function(d){return y(d.Country); })
.attr('dy', '0.35em')
.style('text-anchor', 'start')
.style('font-family', 'sans-serif')
.style('font-weight', 700);
chart.append('text')
.text('Trump')
.attr('x', x(56))
.attr('y', -30)
.attr('text-anchor', 'start')
.style('font-family', 'sans-serif')
.style('font-weight', 700)
.style('fill', trumpcolor);
chart.append('text')
.text('Obama')
.attr('x', x(49))
.attr('y', -30)
.attr('text-anchor', 'end')
.style('font-family', 'sans-serif')
.style('font-weight', 700)
.style('fill', obamacolor);
});
</script>
</body>
</html>
Country Obama Trump
Israel 49 56
Russia 11 53
Australia 84 29
Canada 84 29
Japan 79 24
India 78 24
United Kingdom 79 22
South Korea 88 17
France 84 14
Germany 86 11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment