Creating a heat map from coordinates using R

Recently we wanted to visualise some coordinates which are tracked during a specific API call. The goal was helping us to find out if the functionality is used at all and especially where it is used. It might not be a good use of your time to improve a service in Antartica if no one there is trying to use it. Don’t worry, there is no connection between the user and the location.

Wouldn’t it be cool to view that data quickly via heat map?

Remembering R, an environment for statistical computing and graphics, from a past project, we quickly had enough keywords to google for.

A good starting point, although with a sad topic, can be found here. Let’s find a dataset for the following example.

Finding sample data to work with

Your actual data might be located in some database. Feel free to use is as the input. But for the sake of having some unrelated data for this post I’m taking all locations of McDonald’s in Germany. No affiliation whatsoever to the company 😉. These locations can be found using their german restaurant finder. Simply increase the radius of the search area.

curl -X POST http://www.mcdonalds.de/search\?longitude\=9.481544\&latitude\=51.312801\&radius\=1000 > response.json

The location is the coordinates of Kassel, which is close to the center of Germany. A radius of 1000km covers the whole country.

We transform the reponse.json into CSV via

< response.json | jq '.restaurantList[].restaurant | [.latitude,.longitude] | @csv' | tr -d '"' > locations.csv

We will work on the filelocations.csv. We provide some headers for the columns adding the first line Latitude,Longitude

The first four lines of the CSV thus look like

Latitude,Longitude
48.5600147488,12.1366223689
48.5390797532,12.0959665032
53.3636784825,9.8725737345

Now we need to put these coordinates on a map. Since Google maps started to require an API key recently why not try out another provider?

In the example we are using stamen, which offers map visualisations using OpenStreetMap data. No API required. Yet.

Setup instructions can be found on GitHub. We start with some dependencies of R.

library(ggplot2)
library(ggmap)
library(RColorBrewer)

ggplot2 for graphics. ggmap for plotting maps and RColorBrewer provides colour palettes for data visualisation.The red to yellow to blue for the heat map in our case.

First we read the contents of our locations.csv

coords.data <- read.csv(file="./locations.csv")

Then we define the bounds of the to be mapped country. Germany in our case.

map_bounds <- c(left = 5, bottom = 47, right = 16, top = 56)

We configure the map, bounds, zoom and style, via

coords.map <- get_stamenmap(map_bounds, zoom = 7, maptype = "toner-lite")

To next adding the logic for rendering the heat map

coords.map <- ggmap(coords.map, extent="device", legend="none")
coords.map <- coords.map + stat_density2d(data=coords.data,  aes(x=Longitude, y=Latitude, fill=..level.., alpha=..level..), geom="polygon")
coords.map <- coords.map +   scale_fill_gradientn(colours=rev(brewer.pal(7, "Spectral")))

And get the output as an image

coords.map <- coords.map + theme_bw()
ggsave(filename="./coords.png")

Now we invoke the script via Rscript script.R and are presented with the following

Nice. Let’s add the actual locations to the map to see how these heat spots were created. Add the next snipped before creating the output via ggsave

coords.map <- coords.map + geom_point(data=coords.data,  aes(x=Longitude, y=Latitude), fill="red", shape=23, alpha=0.8)

Running the script again yields

Of course, for a company like McDonald’s, this closely resembles the population centers in Germany. But if you are creating an App which is offering surf spots or hiking trails the map might look quite different.

The code with some setup instruction can be found on GitHub