Created
November 3, 2019 18:12
-
-
Save johnburnmurdoch/0916d9cc78742eb53a37d9fcce563210 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
needs(tidyverse, magrittr, png) | |
# Create a folder for storing the charts | |
dir.create("BFB_images") | |
# Loop though constituency codes in England and Wales, downloading the chart for each on from BfB | |
for(pcon in c(B4B_MRP$westminster_constituency[B4B_MRP$region != "Scotland"])){ | |
tryCatch(download.file(paste0("https://www.getvoting.org/charts/",pcon,"_1.png"), destfile = paste0("BFB_images/", pcon, ".png")), error = function(e){message("No chart")}) | |
} | |
# Function for inferring each party’s projected vote share from the chart | |
process_chart <- function(constituency_code){ | |
# Read in the chart as a matrix of red, green and blue colour values | |
img <- readPNG(paste0("BFB_images/",constituency_code,".png")) | |
# Multiply each colour band by 255 to turn the 0-1 values into standard RGB integer values | |
r <- img[,,1] * 255 | |
g <- img[,,2] * 255 | |
b <- img[,,3] * 255 | |
# Find the pixel coordinate associated with a vote share of zero by identifying the left-most pixel of the Labour vote share bar | |
zero <- c(1:330) %>% | |
map_dbl(~{ | |
min(which( | |
# The line below finds pixels that are rgb(213,0,0), the colour of the Labour bars | |
r[.x,1:615]==213 & g[.x,1:615]==0 & b[.x,1:615]==0 | |
)) %>% replace(!is.finite(.), 999) | |
}) %>% | |
reduce(min) | |
# Find the pixel value associated with Labour’s projected vote share by identifying the right-most pixel of the Labour vote share bar | |
lab <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==213 & g[.x,1:615]==0 & b[.x,1:615]==0 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
# Then subtract the pixel number associated with zero, to find the number of horizontal pixels used for Labour’s projected vote share | |
subtract(zero) | |
# Repeat the above step for all other parties | |
con <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==0 & g[.x,1:615]==155 & b[.x,1:615]==227 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
lib <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==253 & g[.x,1:615]==187 & b[.x,1:615]==48 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
bxp <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==18 & g[.x,1:615]==182 & b[.x,1:615]==207 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
grn <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==0 & g[.x,1:615]==128 & b[.x,1:615]==102 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
pc <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==64 & g[.x,1:615]==132 & b[.x,1:615]==40 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
oth <- c(1:330) %>% | |
map_dbl(~{ | |
max(which( | |
r[.x,1:615]==191 & g[.x,1:615]==191 & b[.x,1:615]==191 | |
)) %>% replace(!is.finite(.), 0) | |
}) %>% | |
reduce(max) %>% | |
subtract(zero) | |
# If there was no value for Plaid Cymru, the method I’ve used will have returned a negative number (zero minus the pixel associated with zero), so change this to zero | |
if(pc < 0){ | |
pc <- 0 | |
} | |
# Now return a little table of party names, vote shares and the constituency code | |
tibble( | |
party = c("con", "lab", "lib", "bxp", "pc", "grn", "oth"), | |
share = c(con, lab, lib, bxp, pc, grn, oth) | |
) %>% | |
transmute(constituency_code, party, share = share/sum(share)*100) | |
} | |
# Loop through all downloaded images, and process each chart, finally returning a big table of all projected vote shares for all parties in all seats | |
inferred_shares <- list.files(path="BFB_images/") %>% | |
str_replace("(\\.png)", "") %>% | |
imap_dfr(~{ | |
message(.y) | |
return(process_chart(.x)) | |
}) %>% | |
spread(party, share, 2:3) %>% | |
left_join(B4B_MRP %>% dplyr::select(constituency, constituency_code=westminster_constituency)) %>% | |
dplyr::select(1,9, everything()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment