Skip to content

Instantly share code, notes, and snippets.

@chrishanretty
Created March 21, 2019 12:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrishanretty/96d35db95cb7da54f51bed9dcd16e340 to your computer and use it in GitHub Desktop.
Save chrishanretty/96d35db95cb7da54f51bed9dcd16e340 to your computer and use it in GitHub Desktop.
Plot signatures to a petition calling for revocation of Article 50
library(rjson)
library(rio)
library(tidyverse)
library(hrbrthemes)
library(ggrepel)
json_to_df <- function(f) {
json_obj <- tryCatch(fromJSON(file = f),
error = function(e) warning(paste0("No data in ",f)))
if (class(json_obj) == "character") {
## pass
sigs <- NULL
} else {
sigs <- do.call("rbind",
lapply(json_obj$data$attributes$signatures_by_constituency,function(x) {
data.frame(name = x$name, ons_code = x$ons_code, signature_count = x$signature_count)
}))
### Get all the things that can be coerced to a one-row data frame
### Except signatures by constituency
attrs <- names(which(lapply(json_obj$data$attributes, length) == 1))
attrs <- setdiff(attrs, "signatures_by_constituency")
attrs <- as.data.frame(json_obj$data$attributes[attrs])
sigs <- merge(sigs, attrs, by = NULL,
suffixes = c(".constituency",".total"),
all = T)
if (nrow(sigs)>0) {
sigs$id <- gsub(".json","", f)
}
}
return(sigs)
}
if (file.exists("241584.json")) {
## pass
} else {
download.file("https://petition.parliament.uk/petitions/241584.json",
destfile = "241584.json")
}
dat <- json_to_df("241584.json")
if (file.exists("BES-2017-General-Election-results-file-v1.0.xlsx")) {
## pass
} else {
download.file("https://www.britishelectionstudy.com/wp-content/uploads/2017/07/BES-2017-General-Election-results-file-v1.0.xlsx",
destfile = "BES-2017-General-Election-results-file-v1.0.xlsx")
}
aux <- import("BES-2017-General-Election-results-file-v1.0.xlsx")
dat <- merge(dat, aux,
by.x = c("ons_code"),
by.y = c("ONSConstID"),
all.x = FALSE,
all.y = TRUE)
dat <- dat %>%
mutate(signature_rate = signature_count.constituency / Electorate17,
Nation = substr(ons_code, 0, 1),
Nation = case_when(Nation == "E" ~ "England",
Nation == "S" ~ "Scotland",
Nation == "W" ~ "Wales"),
party_col = case_when(Winner17 == "Conservative" ~ "#0087dc",
Winner17 == "Labour" ~ "#d50000",
Winner17 == "Liberal Democrat" ~ "#FDBB30",
Winner17 == "Scottish National Party" ~ "#FFF95D",
Winner17 == "Green" ~ "#008066",
Winner17 == "Speaker" ~ "darkgrey",
Winner17 == "Plaid Cymru" ~ "#3F8428"))
mod <- lm(I(signature_rate / 100) ~ remainHanretty, data = dat)
p <- ggplot(dat, aes(x = remainHanretty, y = signature_rate)) +
geom_point(aes(shape = Nation, fill = party_col),
alpha = 0.9, size = 4, colour = "black") +
scale_x_continuous("Remain % in 2016") +
scale_y_continuous("Signatures as % of 2017 electorate",
labels = scales::percent,
limits = c(0, NA)) +
scale_fill_identity("Party") +
scale_shape_manual(values = c(21, 22, 23)) +
geom_smooth(method = "lm", se = FALSE, colour = "black", lty = 2) +
geom_text_repel(data = subset(dat, signature_rate > 0.05),
aes(label = name)) +
theme_minimal() +
theme_ipsum_rc() +
labs(title = "Constituencies which voted to Remain sign the Article 50 revocation petition at higher rates",
caption = "Source: petition.parliament.uk; Hanretty (2017), 'Areal interpolation and the UK's referendum on EU membership'")
ggsave(p, file = "revocation_petition.png", width = 1024/300, height = 512/300, units = "in", dpi = 300, scale = 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment