Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
122 lines (86 sloc) 6.34 KB
title: "Tracking London's Pub & Bar Landscape with geofacet"
description: "Toying around with geofacet, a ggplot2 extension for geographic small multiples."
date: "2017-05-30"
tags: ["r", "ggplot2", "geofacet", "gis"]
draft: no
```{r setup, include=FALSE}
knitr::opts_chunk$set(cache=TRUE, echo = TRUE, warning = FALSE, message = FALSE, out.width = '100%', dpi = 180)
# devtools::install_github("hafen/geofacet")
## Introducing geofacet
The [`geofacet`]( package dropped recently (I want to say last week?), a `ggplot2` extension allowing for the user to facet plots in a way that can retain an underlying geographical dimension. It perhaps goes a little bit further towards abstraction than [tilegrams](, but the visualizations we produce can be a bit more complex as well. This post documents my first foray into this packages functionality.[^fullcode]
## Getting to grips with grids
If we think about faceting in `ggplot2` (`facet_wrap`, `facet_grid`), we are already familiar with the idea of placing a sequence of plots into a number of panels, arranged according to a variable(s) of interest.
`geofacet` is based on the assumption that we want to arrange our sequence of plots into a grid that preserves some known geographical orientation. These known geographical orientations are stored as **grids**, which provide us with row and column values corresponding to a panel's position in a faceted plot. Take this US states example, providing grid positions for US states:
```{r grid eg}
This grid also contains geographical data (state codes/names). We can simply join our data, that sits nicely within this geographical framework, to this grid and start 'geofaceting'.
There is a function in the package, `submit_grid`, which allows users to submit their own grids (as a dataframe, like in the above example) as a github issue and hopefully get them incorporated into the package proper. Having kicked off with just the US states, there's now grids for EU countries, South African provinces, Australian states and London boroughs. Nice - my business is with the latter...
## Geofaceting London
A couple of months ago, [a dataset was published]( containing the number of public houses (pubs) and bars by local authority (borough) in London from 2001 through 2016. We'll use this to demonstrate how this package can help us visualize trends in data without losing the geography along the way.
Below is a map of London's boroughs, in case you aren't familiar.
```{r echo = FALSE, out.width = "75%", fig.align = "center"}
With that cleared up, let's load up this data and get it into shape.
```{r setup n load}
#read/clean pubs data
pubs <- read.xls("",
sheet = "Number of workplaces by LA", skip=2, stringsAsFactors=FALSE) %>%
filter(!`X.1` %in% c("", "London")) %>%
gather(key=year, value=count, -X, -`X.1`) %>%
rename(code_ons=X, area_name=`X.1`) %>%
mutate(count=as.numeric(count), year=as.numeric(str_replace(year, "X", ""))) %>%
# add year-on-year pct change
arrange(area_name) %>%
group_by(area_name) %>%
mutate(prev=lag(count, order_by=year, default=first(count)),
So, we have a tidy dataframe with yearly counts and year-on-year change in pub numbers by borough. Let's peek at the existing `geofacet` grid for London boroughs.
```{r ldn grid}
We're ready to join these on the ONS code field. I'll also put in some line breaks to the borough names - I think some of these might be too long for a densely paneled plot, otherwise.
```{r join}
#clean boro strings in pubs df
pubs$area_name <- str_replace(pubs$area_name, " ", "\n")
#clean boro strings in geofacet grid df
london_boroughs_grid$name <- str_replace(london_boroughs_grid$name, " ", "\n")
# join pubs w/ grid
pubs <- inner_join(pubs, london_boroughs_grid, by ="code_ons") %>%
Ready to plot. All we need to do is call `facet_geo` in the same way we might have faceted by borough using `facet_wrap` previously. This has to be accompanied by a `grid` argument, specifying the grid we want to facet with. We can go on to tweak the plot using familiar `ggplot2` commands.
Here's my first effort:
```{r geofacet, fig.width = 10, fig.height = 10}
# geofaceted plot of year-on-year pubs % change
ggplot(data = pubs, aes(x=year, y=yoy_chg, fill=yoy_chg)) +
geom_col() +
geom_hline(yintercept = 0) +
facet_geo( ~ area_name, grid = "london_boroughs_grid") +
scale_x_continuous(breaks = c(2001, 2016),
labels = NULL) +
scale_y_percent(limits=c(-0.35,0.25), breaks=c(-0.3, 0, 0.25), labels = NULL) +
labs(title = "The Evolution of London's Pubs & Bars",
subtitle = "No. of Public Houses and Bars by London borough, 2001-2016",
caption = "Source:", x = "", y = "") +
theme_minimal(base_family = "Arial Narrow", base_size = 14) +
scale_fill_viridis(option="D",limits=c(-0.35,0.25), name="Year-on-year\n% change",
labels=percent) +
theme(legend.position=c(.9, .95))
## Close
As the package author, [Ryan Hafen accepts]( that some of these plot's readability does rely on some pre-existing knowledge of the underlying geography (Ryan also says to watch out for some ideas to deal with this). Bearing this in mind, there are opportunities to make eye-catching plots on the occasions when this assumption holds (see [this New York Times example]( I reckon I'm gonna have fun with it...
[^fullcode]: To keep the post concise I don't show all of the code, especially code that generates figures. But you can find the full code [here](