Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Unemployment ranked with horizontal bars

Here is a simple, mildly interactive visualisation of unemployment in the world. More specifically, a ranked list of the 20 countries with the highest unemployment rates. The design draws heavily from Mike Bostock's bar chart used in his explanation of object constancy.

The data was downloaded in Excel format from the World Bank. As the notes explain, unemployment is narrowly defined as people who are available to work and who have actively been engaged in looking for work. I say "narrow" because in many cases it is not quite clear how long this window should be, or to what extent it is relevant to the problem.

Lastly, the data is from 2010 and the world has changed quite rapidly since then. Anyways, this at least shows some interestng data in addition to how to make a graph like this. Enjoy :)

[{"country":"Namibia","rate":37.6},{"country":"Macedonia, FYR","rate":32.0},{"country":"Armenia","rate":28.6},{"country":"Bosnia and Herzegovina","rate":27.2},{"country":"Lesotho","rate":25.3},{"country":"South Africa","rate":24.7},{"country":"Spain","rate":20.1},{"country":"Latvia","rate":18.7},{"country":"Lithuania","rate":17.8},{"country":"Estonia","rate":16.9},{"country":"Serbia","rate":16.6},{"country":"Georgia","rate":16.5},{"country":"Yemen, Rep.","rate":14.6},{"country":"Slovak Republic","rate":14.4},{"country":"Dominican Republic","rate":14.2},{"country":"Tunisia","rate":14.2},{"country":"Albania","rate":13.8},{"country":"Ireland","rate":13.6},{"country":"Jordan","rate":12.9},{"country":"Greece","rate":12.5}]
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
.x-axis path {
stroke:white;
fill:none;
}
.x-axis line {
fill: none;
stroke: none;
stroke-opacity:.8;
shape-rendering: crispEdges;
}
.bars rect {
fill:steelblue;
fill-opacity:.9;
}
.title {
font-weight: bold;
}
#precise-value {
fill:white;
font-size: 12px;
}
</style>
</head>
<body>
<script type="text/javascript">
(function(){
var margin = {top: 50, bottom: 50, left:250, right: 40};
var width = 900 - margin.left - margin.right;
var height = 450 - margin.top - margin.bottom;
var xScale = d3.scale.linear().range([0, width]);
var yScale = d3.scale.ordinal().rangeRoundBands([0, height], 1.8,0);
var numTicks = 5;
var xAxis = d3.svg.axis().scale(xScale)
.orient("top")
.tickSize((-height))
.ticks(numTicks);
var svg = d3.select("body").append("svg")
.attr("width", width+margin.left+margin.right)
.attr("height", height+margin.top+margin.bottom)
.attr("class", "base-svg");
var barSvg = svg.append("g")
.attr("transform", "translate("+margin.left+","+margin.top+")")
.attr("class", "bar-svg");
var x = barSvg.append("g")
.attr("class", "x-axis");
var url = "data.json";
d3.json(url, function(data) {
var xMax = d3.max(data, function(d) { return d.rate; } );
var xMin = 0;
xScale.domain([xMin, xMax]);
yScale.domain(data.map(function(d) { return d.country; }));
d3.select(".base-svg").append("text")
.attr("x", margin.left)
.attr("y", (margin.top)/2)
.attr("text-anchor", "start")
.text("Narrowly defined unemployment rates: top 20 countries (2010)")
.attr("class", "title");
var groups = barSvg.append("g").attr("class", "labels")
.selectAll("text")
.data(data)
.enter()
.append("g");
groups.append("text")
.attr("x", "0")
.attr("y", function(d) { return yScale(d.country); })
.text(function(d) { return d.country; })
.attr("text-anchor", "end")
.attr("dy", ".9em")
.attr("dx", "-.32em")
.attr("id", function(d,i) { return "label"+i; });
var bars = groups
.attr("class", "bars")
.append("rect")
.attr("width", function(d) { return xScale(d.rate); })
.attr("height", height/20)
.attr("x", xScale(xMin))
.attr("y", function(d) { return yScale(d.country); })
.attr("id", function(d,i) { return "bar"+i; });
groups.append("text")
.attr("x", function(d) { return xScale(d.rate); })
.attr("y", function(d) { return yScale(d.country); })
.text(function(d) { return d.rate; })
.attr("text-anchor", "end")
.attr("dy", "1.2em")
.attr("dx", "-.32em")
.attr("id", "precise-value");
bars
.on("mouseover", function() {
var currentGroup = d3.select(this.parentNode);
currentGroup.select("rect").style("fill", "brown");
currentGroup.select("text").style("font-weight", "bold");
})
.on("mouseout", function() {
var currentGroup = d3.select(this.parentNode);
currentGroup.select("rect").style("fill", "steelblue");
currentGroup.select("text").style("font-weight", "normal");
});
x.call(xAxis);
var grid = xScale.ticks(numTicks);
barSvg.append("g").attr("class", "grid")
.selectAll("line")
.data(grid, function(d) { return d; })
.enter().append("line")
.attr("y1", 0)
.attr("y2", height+margin.bottom)
.attr("x1", function(d) { return xScale(d); })
.attr("x2", function(d) { return xScale(d); })
.attr("stroke", "white");
});
})();
</script>
</body>
</html>
"""
Download xls data at: http://data.worldbank.org/data-catalog/wdr-2013-jobs
Explanatory notes: http://data.worldbank.org/sites/default/files/wdr-2013-statistical-annex-tables-notes.pdf
'Share of the labor force that is unemployed,
with the unemployed defined as persons who are available to work
and are actively looking for a job during a reference period'
And now?
Do some manual reshaping to get data into single column
Name countries column 'country'
Name unemployment rate column 'rate'
Now get data from csv into sorted JSON
"""
import pandas as pd
filepath = "~/Desktop/unempl.csv"
data = pd.read_csv(filepath)
cleandata = data.dropna(axis=0, how='any')
sorted_data = cleandata.sort('rate', ascending=0)
sorted_data.head(20).to_json(orient='records')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment