Skip to content

Election Results

Thomas Lin Pedersen edited this page Aug 16, 2018 · 2 revisions

Election Results of the German Bundestagwahl by Gender

submitted by holnburger

With ggplot2 and gganimate we're able to animate the outcome of the German federal elections since 1957 by gender. We also want to illustrate our plot as close as possible to design of the German Tagesschau. Our goal is to have an appealing visualization of the differences between the electoral choices of men and women.

The Data

Unfortunately the data provided by the Bundeswahlleiter (electoral management body) is a bit messy, therefore we have to clean it first and translate it into a tidy data set. We use the package dplyr and tidyr for that. Of course I'd love to include the electoral choices of voters with a non-binary gender – unfortunately the Bundeswahlleiter doesn't include such data.

library(dplyr)
library(tidyr)

btw_data <- read.csv2(
  "https://www.bundeswahlleiter.de/dam/jcr/f0610db5-f84c-430e-96e1-19be7f599e60/btw17_rws_zwst-1953.csv", 
  skip = 10
) %>%
  select(-Altersgruppe.etwa.von.....bis.....Jahren) %>%
  filter(Geschlecht != "Summe") %>%
  gather(CDU, SPD, PDS.DIE.LINKE, GRÜNE, CSU, FDP, AfD, Sonstige, key = Partei, value = Wahlergebnis) %>%
  mutate(Partei = ifelse(Partei == "PDS.DIE.LINKE", "Die Linke", Partei)) %>%
  mutate(Partei = ifelse(Partei == "GRÜNE", "Die Grünen", Partei)) %>%
  mutate(Partei = factor(Partei, levels = c("CDU", "SPD", "FDP", "CSU", "Die Grünen", "Die Linke", "AfD", "Sonstige"))) %>%
  mutate(Geschlecht = ifelse(Geschlecht == "m", "männlich", "weiblich")) %>%
  mutate(Wahlergebnis = Wahlergebnis / 100) %>%
  replace_na(replace = list(Wahlergebnis = 0))

Because we also want fitting colors for the parties we'll define them in a vector which we use later for the visualization.

party_color <- c(
  "AfD" = "#1a9fde",
  "SPD" = "#e10b1f", 
  "CDU" = "#565656", 
  "CSU" = "#727272", 
  "Die Grünen" = "#499533", 
  "Die Linke" = "#bc3475", 
  "FDP" = "#e5d82d",
  "Sonstige" = "#D3D3D3"
)

The Code

library(ggplot2)
library(gganimate)

btw_animated <- ggplot(btw_data, aes(x = Partei, y = Wahlergebnis, fill = Partei)) +
  geom_hline(yintercept = 0.05, colour = "#D3D3D3", linetype = "dashed") +
  geom_bar(position = "dodge", stat = "identity") +
  geom_text(aes(label = scales::percent(Wahlergebnis), 
                y = Wahlergebnis + 0.01),
            position = position_dodge(width = 0.9), 
            vjust = -0.5, size = 6, color = "black") +
  labs(title = "Wahlergebnisse der Bundestagswahl {closest_state}",
       subtitle = "Ergebnisse nach Geschlecht der WählerInnen*",
       caption = "* 1994 und 1998 wurde die repräsentative Wahlstatistik durch den Gesetzgeber ausgesetzt",
       x = "", y = "") +
  theme_light(base_size = 16) +
  guides(fill = FALSE) +
  facet_grid(Geschlecht ~ .) +
  scale_y_continuous(labels = scales::percent, limits = c(0, 0.59)) +
  scale_fill_manual(values = party_color) +
  transition_states(Bundestagswahl, 1, 3, wrap = FALSE) +
  ease_aes('quadratic-in-out')

btw_animated

Discussion

In this example we use transition_states() with the arguments transition_length = 1 and state_length = 3 to give us enough time to read the outcomes between the transition through the years. We use the argument wrap = FALSE because we don't want to have a smooth transition between the outcome of the last election and the first. With the easing set to ease_aes('quadratic-in-out') we generate a dynamic and smooth transition between the different states.