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