../docs/vignettes/using-cartograms.Rmd
using-cartograms.Rmd
cartogram
You can use the cartogram
package with parlitools
to produce maps with scaled areas,
as seen in Xinye
Li’s post on Brexit votes.
As the cartogram package requires
SpatialPolygonsDataFrame
objects, instead of simple
features objects, the west_hex_map
object is converted
first to a Spatial object, and then to a
SpatialPolygonsDataFrame
object, as there is no function to
convert directly from sf
to
SpatialPolygonsDataFrame
.
This map scales constituencies based on how marginal they are, by subtracting the majority (the difference in votes between the winning and second place candidate) from 100 and cubing that value. Larger constituencies are those deemed to be more marginal.
It uses datasets included in this package, namely the British
Election Study data of the 2017 General Election supplemented with the
Northern Ireland results (bes_2017
),
party_colours
and west_hex_map
.
library(leaflet)
library(sf)
library(htmlwidgets)
library(dplyr)
library(parlitools)
library(cartogram)
west_hex_map <- parlitools::west_hex_map
party_colour <- parlitools::party_colour
elect2017 <- parlitools::bes_2017
#Join to current MP data
elect2017_win_colours <- left_join(elect2017, party_colour, by = c("winner_17" ="party_name"))
#Join colours to hexagon map
gb_hex_map <- right_join(west_hex_map, elect2017_win_colours,
by = c("gss_code"="ons_const_id"))
# gb_hex_map <- as(gb_hex_map, "Spatial")
#
# gb_hex_map <- as(gb_hex_map, "SpatialPolygonsDataFrame")
gb_hex_map$majority_17 <- round(gb_hex_map$majority_17, 2)
gb_hex_map$turnout_17 <- round(gb_hex_map$turnout_17, 2)
gb_hex_map$marginality <- (100-gb_hex_map$majority_17)^3
gb_hex_map <- st_transform(gb_hex_map, "+init=epsg:3395")
gp_hex_scaled <- cartogram_cont(gb_hex_map, 'marginality', itermax = 5)
gp_hex_scaled <- st_transform(gp_hex_scaled, "+init=epsg:4326")
# Creating map labels
labels <- paste0(
"Constituency: ", gp_hex_scaled$constituency_name.y, "</br>",
"Most Recent Winner: ", gp_hex_scaled$winner_17, "</br>",
"Most Recent Majority: ", gp_hex_scaled$majority_17, "%","</br>",
"Turnout: ", gp_hex_scaled$turnout_17, "%"
) %>% lapply(htmltools::HTML)
# Creating the map itself
leaflet(options=leafletOptions(
dragging = FALSE, zoomControl = FALSE, tap = FALSE,
minZoom = 6, maxZoom = 6, maxBounds = list(list(2.5,-7.75),list(58.25,50.0)),
attributionControl = FALSE),
gp_hex_scaled) %>%
addPolygons(
color = "grey",
weight=0.75,
opacity = 0.5,
fillOpacity = 1,
fillColor = ~party_colour,
label=labels) %>%
htmlwidgets::onRender(
"function(x, y) {
var myMap = this;
myMap._container.style['background'] = '#fff';
}")%>%
mapOptions(zoomToLimits = "first")