Sweden election 2014

Plotting the Swedish Election 2014

This post plots the results from the 2014 Swedish general election for each political party per county. The values plotted are votes as z-value for each county compared to the whole country.

Loading libraries

library(httr)
library(lubridate)
library(jsonlite)
library(ggplot2)
library(swemaps)
library(rkolada)
library(maps)
library(dplyr)
library(RColorBrewer)
library(htmlwidgets)
library(rvg)
library(ggiraph)
library(gganimate)
library(gridExtra)
library(grid)
library(gtable)

Getting data

Get all the election data per county and per election. This involves trying to figure out where on the Swedish Statistical Bureau you can find information (http://api.scb.se/OV0104/v1/doris/sv/ssd/) . For english go to http://api.scb.se/OV0104/v1/doris/en/ssd

url <- "http://api.scb.se/OV0104/v1/doris/sv/ssd/ME/ME0104/ME0104C/ME0104T3"

SCB <- jsonlite::fromJSON(url)

SCB$variables$code
## [1] "Region"       "Partimm"      "ContentsCode" "Tid"
query = paste0(' { "query": [  {"code": "ContentsCode","selection": {"filter": "item", "values": [ "ME0104B7"] } }, {"code": "Tid",
 "selection": {"filter": "item",
 "values": ["', paste(SCB$variables$values[[4]],collapse='" "'),'"]}},   
 {"code": "Region","selection": {"filter": "item", "values": ["', paste(SCB$variables$values[[1]],collapse='" "'), 
 '"] } } ],"response": {"format": "csv"}  }')

results <- POST(url, body=query)
SCBdata <- content(results)

SCBdata
## # A tibble: 3,553 x 15
##    region  `parti mm`  `Andel röster (a… `Andel röster (… `Andel röster (…
##    <chr>   <chr>       <chr>             <chr>            <chr>           
##  1 0114 U… Moderaterna 15.5              17.1             23.5            
##  2 0114 U… Centerpart… 23.6              20.1             12.8            
##  3 0114 U… Folkpartiet 9.7               13.8             12.1            
##  4 0114 U… Kristdemok… 1.0               0.6              0.8             
##  5 0114 U… Miljöparti… ..                ..               ..              
##  6 0114 U… Socialdemo… 42.9              41.4             41.9            
##  7 0114 U… Vänsterpar… 6.5               6.5              7.8             
##  8 0114 U… Sverigedem… ..                ..               ..              
##  9 0114 U… övriga par… 0.6               0.5              1.0             
## 10 0114 U… ogiltiga v… ..                ..               ..              
## # ... with 3,543 more rows, and 10 more variables: `Andel röster (av
## #   giltiga röster) 1982` <chr>, `Andel röster (av giltiga röster)
## #   1985` <chr>, `Andel röster (av giltiga röster) 1988` <chr>, `Andel
## #   röster (av giltiga röster) 1991` <chr>, `Andel röster (av giltiga
## #   röster) 1994` <chr>, `Andel röster (av giltiga röster) 1998` <chr>,
## #   `Andel röster (av giltiga röster) 2002` <chr>, `Andel röster (av
## #   giltiga röster) 2006` <chr>, `Andel röster (av giltiga röster)
## #   2010` <chr>, `Andel röster (av giltiga röster) 2014` <chr>

Extract county code and remove lan

As we only want to plot the county data, we remove the larger Lan

SCBdata$kod <- unlist(lapply(strsplit(SCBdata$region,split=' '), function(x) {x[1]}))
SCBdata <- SCBdata[grep('VR', SCBdata$kod, invert=T),]

Clean data and make interactive

sweden_map <- map_kn %>%
	select(leaflet_long, leaflet_lat, knkod, knnamn, lnnamn) %>%
	rename(long = leaflet_long, lat= leaflet_lat, region=knkod, subregion=knnamn) %>%
	fortify() %>%
        unique()

SCBdata <- SCBdata[SCBdata$kod%in%sweden_map$region,]

SCBmelt <- melt(SCBdata, id=c('region', 'parti mm', 'kod'))
SCBmelt[SCBmelt$value=='..',]$value <- 0
SCBmelt$value <- as.numeric(SCBmelt$value)


SCBmelt$tip <- paste0(
"<b>", sub(".*? (.+)", "\\1", SCBmelt$region), "</b> ",
"<br>", paste0(round(SCBmelt$value),'%'))
SCBmelt$variable= gsub('Andel röster \\(av giltiga röster\\) ','',SCBmelt$variable )

colnames(SCBmelt) <- c('region', 'parti', 'kod', 'year','percent', 'tip')

SCBmelt <- SCBmelt[grep('ogiltiga valsedlar|ej röstande', SCBmelt$parti, invert=T),]

Create colour for each party

unique(SCBmelt$parti)
## [1] "Moderaterna"         "Centerpartiet"       "Folkpartiet"        
## [4] "Kristdemokraterna"   "Miljöpartiet"        "Socialdemokraterna" 
## [7] "Vänsterpartiet"      "Sverigedemokraterna" "övriga partier"
SCBmelt$cols <- "#129B93"
SCBmelt$cols[SCBmelt$parti %in% "Socialdemokraterna"] <- "firebrick2"
SCBmelt$cols[SCBmelt$parti %in% "Moderaterna"] <- "deepskyblue4"
SCBmelt$cols[SCBmelt$parti %in% "Centerpartiet"] <- "darkgreen"
SCBmelt$cols[SCBmelt$parti %in% "Folkpartiet"] <- "dodgerblue3"
SCBmelt$cols[SCBmelt$parti %in% "Kristdemokraterna"] <- "navy"
SCBmelt$cols[SCBmelt$parti %in% "Miljöpartiet"] <- "green3"
SCBmelt$cols[SCBmelt$parti %in% "Vänsterpartiet"] <- "red3"
SCBmelt$cols[SCBmelt$parti %in% "Sverigedemokraterna"] <- "goldenrod3"
SCBmelt$cols[SCBmelt$parti %in% "övriga partier"] <- "gray52"

Plot data

partiPlot <- SCBmelt[SCBmelt$year=='2014',]
plotlist <- list() # create empty list to fill with plots
for(i in 1:length(unique(partiPlot$parti)))
  local({
    i <- i
    # filter data to only contain current party
    plotdata <- partiPlot %>% filter(parti %in% unique(partiPlot$parti)[i])
    plotdata$Long <- 'all'
    plotdata$Long[as.numeric(plotdata$kod)<0563] <- 'south'
    # save plot as list element  
    plotlist[[i]] <<-    plotdata %>%
                                ggplot( aes(map_id=kod, fill=percent, frame = year))+ 
                                geom_map_interactive(data=plotdata, map=sweden_map, aes(fill=percent, 
                                tooltip=tip, map_id=kod, data_id=kod), 
                                colour="white", size=0.05)+
                                expand_limits(x = sweden_map$long, y = sweden_map$lat)+
                                theme_void() +
                                scale_fill_gradient2(low="#F4F4F4", high=unique(plotdata$cols)) +
                                theme(legend.position='none')+
                                ggtitle(unique(partiPlot$parti)[i])+
                                theme(plot.background = element_rect(fill = '#999999'))+
                                theme(line = element_blank(),plot.title = element_text(hjust = 0.5))#+
                                #facet_zoom(xlim = c(10, 18), ylim = c(55, 60), zoom.size = 2)
})
do.call("grid.arrange", c(plotlist, ncol=3))

plot of chunk unnamed-chunk-6