---
title: "Using cartograms with parlitools"
author: "Evan Odell"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using cartograms with parlitools}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

# Scaling with `cartogram`

You can use the [`cartogram`](https://CRAN.R-project.org/package=cartogram) package with `parlitools` to produce maps with scaled areas, as seen in [Xinye Li's post on Brexit votes](https://xinye1.github.io/projects/brexit-cartogram-leaflet/).

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`.

## Scaling by marginality

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 (`bes_2017`), `party_colours` and `west_hex_map`. As the BES only covers Wales, Scotland and England, Northern Ireland is not included in the map.

```{r fig.width=6, echo=TRUE, fig.height=7, message=FALSE, warning=FALSE}
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

elect2017_win_colours <- left_join(elect2017, party_colour, by = c("winner_17" ="party_name")) #Join to current MP data

gb_hex_map <- right_join(west_hex_map, elect2017_win_colours, by = c("gss_code"="ons_const_id")) #Join colours to hexagon map

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

gp_hex_scaled <- cartogram(gb_hex_map, 'marginality')

# 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")

```

