All examples By author By category About

darrenjaworski

Tutorial III

Points on a map

In these series of tutorials, I'm going to be producing popular journalism web-friendly charts. There are a many visuzaliation tools to help you create charts, and maps. Google docs can also help you get started in data visualization. These tutorials are for journalists interested in more control over their visualizations than off the shelf tools, or a way to get started in D3. I will try to provide as much detail as possible, walking through each graphic step by step, from data preparation to final version. These are being written to help an average journalist with a chart or map accompaniment to their work. I will therefore ensure as much as possible a replicability and reusability, while making them as easy to understand as possible.

These tutorials use D3, which is a framework that relies on scaled vector graphics to render visualizations. These tutorials will not require extensive javascript or programming knowledge as they use minimal code, and every facet that is customizable will be explained in detail.

Tutorial I: Pie chart, bar chart, and line chart.

Tutorial II: Choropleth map.

Tutorial III: Points on a map.

Tutorial IV: Slightly more advanced pie, bar and line charts.

Tutorial V: Slightly more advanced choropleth map.

Tutorial VI: Network graph.


Data preparation

In tutorial II I went through TOPOJSON installation. For this tutorial, we're going to be using TOPOJSON to output a file with our latitudes and longitudes. I'm going to be using the county and state shapefile from tutorial II. For your own work you will need to change the references to match your file directory.

For this tutorial we're going to be mapping tornado touchdown locations in OK provided by the National Weather Service, Storm Prediction Center for the 2012 calendar year. Here is a link to the data. To download, go to file>download, and save as a .csv to your computer.

Notice that I have a column named longitude and latitude according to the command line reference of TOPOJSON. If you don't name the columns latitude and longitude, you will have to specify using -x and -y.

topojson tornadoes.csv --properties -o points.json

With that line we'll have our points.json file ready to go.

HTML

We have a simple html file for this tutorial, which looks like the following.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
	
.state {
	fill: #EEEFF1;
}

.county-border {
	fill: none;
	stroke: #919599;
}

.state-border {
	fill: none;
	stroke: #919599;
}

.points {
	stroke-width: 1px;
	stroke: #000;
}
	
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<script src="points.js"></script>

We style our county and state borders exactly how we did in the choropleth. The state fill is the background for the map. In this example I chose a nice grey to give us a good contrast and not be eye popping.

Points are stiled by a stroke-width and stroke color. For this I chose small points, with a black stroke. They should appear black on the map.

For this tutorial we need to reference " queue.v1.min.js ". This allows us to use two json files at once without interferance.

points.js

Standard fair from the tutorial II if you'll notice.

var width = 1000, 
	height = 550;

//http://www.ngs.noaa.gov/PUBS_LIB/ManualNOSNGS5.pdf
var projection = d3.geo.conicConformal()
	.parallels([35 + 34 / 60, 36 + 46 / 60])
	.rotate([98 + 00 / 60, -35 - 00 / 60])
	.scale(5300)
	.translate([width / 2, height / 2]);
	
var path = d3.geo.path()
	.projection(projection);

var svg = d3.select("body")
	.append("svg")
	.attr("width", width)
	.attr("height", height);

Next we use queue() to load our jsons. We then have them both queued up awaiting the function ready. I ignorantly would load both simultaneously. This would lead to my data being loaded over one another. You'll notice the difference if you try to use two d3.json references at once.

queue()
	.defer(d3.json, "finaloutput.json")
	.defer(d3.json, "points.json")
	.await(ready);

Next we create the actual function itself. Notice the parameters to the function. "ok" and "points". That was the order that we loaded them, and that is the order of our reference. We create a state, county and state borders from the finaloutput.json the same way we did for the choropleth map.

function ready(error, ok, points) {

	//state
	svg.append("path")
		.attr("class", "state")
		.datum(topojson.feature(ok, ok.objects.county))
		.attr("d", path);

	//county border
	svg.append("path")
		.attr("class", "county-border")
		.datum(topojson.mesh(ok, ok.objects.county, function(a, b) { return a !== b;}))
		.attr("d", path);

	//state border
	svg.append("path")
		.attr("class", "state-border")
		.datum(topojson.mesh(ok, ok.objects.county, function(a, b) { return a === b;}))
		.attr("d", path);

Next we load the tornado points data from points.json. I use a sort function keyed to the property id to read the data. Then I append points at the coordinates with a radius of 3.

	//points data
	var points = topojson.feature(points, points.objects.tornadoes);

	//prisons
	svg.selectAll(".points")
		.data(points.features.sort(function(a, b) { return b.properties.id - a.properties.id;}))
		.enter()
		.append("path")
		.attr("class", "points")
		.attr("d", path.pointRadius(3))
		
}

That is a simple points map for all tornadoes hitting oklahoma in 2012. This technique requires your data to have predefined latitudes and longitudes. It's conceivable to go through a small set of points and pick out their latitudes and longitudes, but not possible if you have a lot. Google Maps API has a geocoding function. There are also services such as Google Fusion and Batch Geo which can geocode for you. In the next couple of tutorials I'll add some bells and whistles to some previous tutorials.