Created
September 13, 2018 18:13
-
-
Save peterdalle/570b667541c162f72787cef6b4cd6a36 to your computer and use it in GitHub Desktop.
News coverage of party leaders compared to Swedish 2018 election results
This file contains hidden or 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
library(gganimate) | |
library(ggrepel) | |
library(lubridate) | |
library(tidyverse) | |
# The order is FUBAR. | |
partycolors <- c("#006AB3", "#000077", "#52BDEC", "#E8112d", | |
"#83CF39", "#009933", "#DA291C", "#E8AC41") | |
# Mediearkivet keywords: | |
# | |
# "jimmie åkesson" | |
# "stefan löfven" | |
# "annie lööf" | |
# "ebba busch thor" | |
# "isabella lövin" | |
# "gustav fridolin" | |
# "jonas sjöstedt" | |
# "jan björklund" | |
# "ulf kristersson" | |
# Each MP party leader separate: | |
lovin <- c(1649,1148,1074,755,1983,1089,1361,2068,1284) # "isabella lövin" | |
fridolin <- c(642,943,1519,1181,1780,1148,1396,2725,1163) # "gustav fridolin" | |
mp <- lovin + fridolin | |
# "isabella lövin" OR "gustav fridolin" | |
mp_or <- c(2056,1853,2305,1774,2875,2067,2461,4252,1947) | |
# Data: | |
# total = total number of articles from Mediearkivet 2018 (up to 2018-09-13), used the keywords above. | |
# votes = vote share election night, from https://data.val.se/val/val2018/valnatt/R/rike/index.html | |
# jan:sep = number of articles each month from Mediearkivet | |
df <- read.table(text = "name,total,votes,january,february,march,april,may,june,july,august,september | |
Åkesson (SD),21448,17.6,929,994,1349,1252,2310,2237,2012,4493,5882 | |
Löfven (S),58469,28.4,4891,4950,7931,4887,7304,6590,6209,7945,7789 | |
Lööf (C),20584,8.6,1298,1446,1525,2066,1967,2014,2429,4112,3735 | |
Busch Thor (KD),13849,6.4,595,980,1313,826,1471,911,1122,3531,3113 | |
Lövin/Fridolin (MP),24908,4.3,2291,2091,2593,1936,3763,2237,2757,4793,2447 | |
Sjöstedt (V),13016,7.9,1313,1396,880,826,1508,1299,1096,2658,2051 | |
Björklund (L),16975,5.5,1078,779,1228,1809,1794,2038,1653,3840,2758 | |
Kristersson (M),26897,19.8,1708,1550,1687,1939,3932,2689,2411,5925,5067", sep=",", header=TRUE) | |
# Use MP "isabella lövin" OR "gustav fridolin". | |
df[5, 4:12] <- mp_or | |
# Make long, add date. | |
df_long <- df %>% | |
gather("month", "n", january:september) %>% | |
mutate(date = case_when(month == "january" ~ as.Date("2018-01-01"), | |
month == "february" ~ as.Date("2018-02-01"), | |
month == "march" ~ as.Date("2018-03-01"), | |
month == "april" ~ as.Date("2018-04-01"), | |
month == "may" ~ as.Date("2018-05-01"), | |
month == "june" ~ as.Date("2018-06-01"), | |
month == "july" ~ as.Date("2018-07-01"), | |
month == "august" ~ as.Date("2018-08-01"), | |
month == "september" ~ as.Date("2018-09-01"))) | |
# Calculate intercept and slope for diagonal. | |
#coef(lm(total ~ votes, df)) | |
# Create static plot. | |
gg <- df %>% | |
ggplot(aes(votes, total)) + | |
geom_point(size=3) + | |
geom_text_repel(aes(label=name), seed=42, force = .7) + | |
annotate("label", x=7, y=50000, label="Överrepresenterad") + | |
annotate("label", x=25, y=20000, label="Underrepresenterad") + | |
scale_x_continuous(breaks = seq(0, 100, 5)) + | |
scale_y_continuous(breaks = seq(0, 6e6, 1e4)) + | |
#geom_abline(intercept=0, slope=1) + | |
#scale_x_log10() + | |
#scale_y_log10() + | |
labs(title = "Mediebevakning av partiledare jämfört med valresultatet", | |
x = "Andel röster valnatten (procent)", | |
y = "Antal artiklar Mediearkivet 2018\n(t.o.m. 2018-09-13)") + | |
theme_bw() + | |
theme(legend.position = "none", | |
panel.grid = element_blank()) | |
gg | |
# Save static plot. | |
ggsave("valresultat-partiledare-mediebevakning.png", | |
width=7, height=5, device="png", dpi=300) | |
# Create static plot with facet for each month. | |
gg_facet <- df_long %>% | |
ggplot(aes(votes, n, color=name)) + | |
geom_point(size=3) + | |
geom_text_repel(aes(label=name), seed=42, force = .7) + | |
scale_color_manual(values = partycolors) + | |
scale_x_continuous(breaks = seq(0, 100, 5)) + | |
scale_y_continuous(breaks = seq(0, 6e6, 1e4)) + | |
labs(title = "Mediebevakning av partiledare jämfört med valresultatet", | |
x = "Andel röster valnatten (procent)", | |
y = "Antal artiklar Mediearkivet 2018\n(t.o.m. 2018-09-13)") + | |
theme_bw() + | |
theme(legend.position = "none", | |
panel.grid = element_blank()) + | |
facet_wrap(~month) | |
gg_facet | |
# Create animated plot. | |
gg_animated <- df_long %>% | |
ggplot(aes(votes, n, color=name)) + | |
geom_point(size=3) + | |
scale_color_manual(values = partycolors) + | |
geom_text_repel(aes(label=name), seed=42, force = .7) + | |
scale_x_continuous(breaks = seq(0, 100, 5)) + | |
scale_y_continuous(breaks = seq(0, 8000, 1000)) + | |
labs(title = "News coverage of party leaders compared to Swedish 2018 election results", | |
subtitle = "Month: {round_date(frame_time, 'month')}", | |
x = "Vote share election night (percent)", | |
y = "Number of articles\n(Mediearkivet up to 2018-09-13)") + | |
theme_bw() + | |
theme(legend.position = "none", | |
panel.grid = element_blank()) + | |
transition_time(date) + | |
enter_fade() + | |
exit_shrink() + | |
ease_aes("quadratic-in-out") | |
# Gif | |
ani <- animate(gg_animated, nframes = 200, fps = 10, width = 550, | |
height = 450, renderer = gifski_renderer(loop = F)) | |
anim_save("partyleaders-votes-media-animation.gif", ani) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See animation at https://twitter.com/peterdalle/status/1040281663517990912.