What are “overhang seats” and why do they matter?

Various democratic countries use different processes to elect politicians. A few places use Mixed-member proportional (MMP) representation (Germany, New Zealand, Lesotho and Bolivia). In a MMP electoral system, voters have two votes: one for a representative for their electoral constituency and the other for a nation-wide political party. Seats are filled first by the constituency votes and then by political party. A party wins a certain number of seats based on the total vote percentage (a combination of both constituency votes and party votes). Sometimes a party does not win the number of constituencies needed to fill the total number of seats (i.e., they win 6 seats in total but are only elected to 4 constituencies). The remaining seats are known as overhang seats.

Germany 2013 election

In 2017, the Bloomberg visual graphics team created an excellent data visualization of the German Bundestag prior to the 2017 German election. They represented the overhang seats by adding hollow seats to each party. We have decided to recreate the idea of hollow seats in ggparliament with geom_overhang_seats().

data <- election_data %>%
  filter(country == "Germany" & year == "2013") 
# binary variable for overhang seat
overhangseats <- c(1, 0, 1, 0, 1, 0, 1, 0)
# number of overhang seats and remainder for each party
number_overhangseats <- c(3, 61, 3, 60,16, 295, 11, 182)
# expand data
german_data <- parliament_data(
  election_data = data,
  parl_rows = 11,
  party_seats = data$seats,
  type = "semicircle"
)
german_data <- german_data %>% mutate(overhang_seats = rep(overhangseats, number_overhangseats))
german_parliament <- ggplot(german_data, aes(x,
  y,
  colour = party_short
)) +
  geom_parliament_seats() +
  # Hollow the overhang seats as follows:
  geom_overhang_seats(overhang_seats == 1) +
  labs(
    colour = "Party",
    title = "German Bundestag - 2013 election",
    subtitle = "Overhang seats are hollow."
  ) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5),
    legend.position = "none"
  ) +
  draw_partylabels(type = "semicircle",
                   party_colours = colour,
                   party_names = party_short,
                   party_seats = seats) +
  scale_colour_manual(
    values = german_data$colour,
    limits = german_data$party_short
  )
german_parliament