1 Setup

knitr::opts_chunk$set(echo = TRUE)
knitr::opts_chunk$set(out.width = "100%")
library(curl)
library(sf)
## Linking to GEOS 3.8.1, GDAL 3.1.1, PROJ 6.3.1
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.2     ✓ purrr   0.3.4
## ✓ tibble  3.0.4     ✓ dplyr   1.0.2
## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
## ✓ readr   1.4.0     ✓ forcats 0.5.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter()     masks stats::filter()
## x dplyr::lag()        masks stats::lag()
## x readr::parse_date() masks curl::parse_date()
library(ggplot2)

2 Introduction

One of the problems associated with mapping area-based data is the often highly variable size of geographical areas. With data such as that provided by Census (OA, LSOA, MSOA etc) representing similar populations, the dominance of the largest areas can lead to mis-interpretation (and potential overlooking of smaller areas). Cartograms have been used to resize areas in accordance with other attributes such as population. For more background and creating hexograms in R see Hexograms: better maps of area based data.

3 Examples

This example follows an example of creating a non-contiguous hexogram (and re-uses code) by [@VictimOfMaths](https://github.com/VictimOfMaths/Maps/blob/master/WFHCartogram.R) using hex-map geometry from House of Commons Library.

The first example we will look at is plotting a non-contiguous hexogram of Local Authority areas.

3.1 Local Authority areas

ltla <- tempfile()
source <- ("https://github.com/houseofcommonslibrary/uk-hex-cartograms-noncontiguous/raw/main/geopackages/LocalAuthorities-lowertier.gpkg")
ltla <- curl_download(url=source, destfile=ltla, quiet=FALSE, mode="wb")

The file downloaded is a GeoPackage (.gpkg) file, an SQLite Database container (see http://www.geopackage.org/guidance/getting-started.html for more info.). We can examine the layers contained using the st_layers() command from the sf package.

st_layers(ltla)
## Driver: GPKG 
## Available layers:
##       layer_name geometry_type features fields
## 1 1 Group labels         Point       60      4
## 2       2 Groups Multi Polygon       61      5
## 3    3 LTLA-2018 Multi Polygon      391      8
## 4    4 LTLA-2019 Multi Polygon      382      8
## 5    5 LTLA-2020 Multi Polygon      379      8
## 6    6 LTLA-2021 Multi Polygon      374      8
## 7   7 Background Multi Polygon        3      2
## 8   layer_styles            NA        7     12

Next we extract the layers we want using the st_read command. Alternative methods are available.

Background <- st_read(ltla, layer="7 Background")
## Reading layer `7 Background' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f7eba46bc' using driver `GPKG'
## Simple feature collection with 3 features and 2 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 5.987083 ymin: 1.761197 xmax: 56.83708 ymax: 70.35025
## projected CRS:  OSGB 1936 / British National Grid
Areas <- st_read(ltla, layer="4 LTLA-2019")
## Reading layer `4 LTLA-2019' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f7eba46bc' using driver `GPKG'
## Simple feature collection with 382 features and 8 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 7.337122 ymin: 2.106729 xmax: 55.78812 ymax: 69.48159
## projected CRS:  OSGB 1936 / British National Grid
Groups <- st_read(ltla, layer="2 Groups")
## Reading layer `2 Groups' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f7eba46bc' using driver `GPKG'
## Simple feature collection with 61 features and 5 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 7.337122 ymin: 2.106729 xmax: 55.78812 ymax: 69.48159
## projected CRS:  OSGB 1936 / British National Grid
Group_labels <- st_read(ltla, layer="1 Group labels") %>% 
  mutate(just=if_else(LabelPosit=="Left", 0, 1))
## Reading layer `1 Group labels' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f7eba46bc' using driver `GPKG'
## Simple feature collection with 60 features and 4 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 13.33708 ymin: 2.211136 xmax: 55.03708 ymax: 69.31102
## projected CRS:  OSGB 1936 / British National Grid

And finally we can make a plot, for example Figure 3.1 note the Groups geometry provides County-level grouping of local authorities and an outline (appears bold in the plot below). Areas provides the local authority outlines.

Non-contiguous hexogram of local authorities in Great Britain

Figure 3.1: Non-contiguous hexogram of local authorities in Great Britain

4 Middle-layer Super Output Areas

Load GeoPackage file … this time Middle-layer Super Output Areas (MSOAs) in England and Wales only.

msoa <- tempfile()
source <- ("https://github.com/houseofcommonslibrary/uk-hex-cartograms-noncontiguous/raw/main/geopackages/MSOA.gpkg")
msoa <- curl_download(url = source, destfile = msoa, quiet = FALSE, mode = "wb")

List layers …

st_layers(msoa)
## Warning in CPL_get_layers(dsn, options, do_count): GDAL Message 1: File /
## private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/
## file1e6f40a87e0a has GPKG application_id, but non conformant file extension
## Driver: GPKG 
## Available layers:
##                          layer_name geometry_type features fields
## 1                    1 Group labels         Point       50      4
## 2                          2 Groups Multi Polygon       51      3
## 3 3 Local authority outlines (2019) Multi Polygon      339      8
## 4                        4 MSOA hex Multi Polygon     7201     13
## 5                      5 Background Multi Polygon        1      2
## 6                      layer_styles            NA        5     12

Extract layers …

background_msoa <- st_read(msoa, layer="5 Background")
## Reading layer `5 Background' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f40a87e0a' using driver `GPKG'
## Simple feature collection with 1 feature and 2 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 11.98708 ymin: 1.761197 xmax: 56.83708 ymax: 56.06086
## projected CRS:  OSGB 1936 / British National Grid
msoa_la_outlines <- st_read(msoa, layer="3 Local authority outlines (2019)")
## Reading layer `3 Local authority outlines (2019)' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f40a87e0a' using driver `GPKG'
## Simple feature collection with 339 features and 8 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 12.43712 ymin: 2.10724 xmax: 55.78812 ymax: 55.4529
## projected CRS:  OSGB 1936 / British National Grid
msoa_data <- st_read(msoa, layer="4 MSOA hex")
## Reading layer `4 MSOA hex' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f40a87e0a' using driver `GPKG'
## Simple feature collection with 7201 features and 13 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 12.43766 ymin: 2.106214 xmax: 55.78866 ymax: 55.45188
## projected CRS:  OSGB 1936 / British National Grid
msoa_groups <- st_read(msoa, layer="2 Groups")
## Reading layer `2 Groups' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f40a87e0a' using driver `GPKG'
## Simple feature collection with 51 features and 3 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 12.43712 ymin: 2.10724 xmax: 55.78812 ymax: 55.4529
## projected CRS:  OSGB 1936 / British National Grid
msoa_group_labels <- st_read(msoa, layer="1 Group labels") %>% 
  mutate(just=if_else(LabelPosit=="Left", 0, 1))
## Reading layer `1 Group labels' from data source `/private/var/folders/8g/mcy278p50hnd4s37tn7w94jj1yjlr8/T/Rtmpo3rt9t/file1e6f40a87e0a' using driver `GPKG'
## Simple feature collection with 50 features and 4 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 14.18924 ymin: 2.211136 xmax: 54.81992 ymax: 54.2137
## projected CRS:  OSGB 1936 / British National Grid

Figure 4.1 As with the local authority example, msoa_groups and msoa_la_outlines geometries provide County- and Local Authority-level grouping/outlines (black in the plot below). msoa_data provides the MSOA outlines (in blue).

Non-contiguous hexogram of local authorities in Great Britain

Figure 4.1: Non-contiguous hexogram of local authorities in Great Britain

5 Further reading and resources

I cannot find LSOA level hex maps but here’s some links with a more info on creating hex maps, something to try out!

Other resources …

ODI Leeds …