¿Cómo hacer un gráfico de parlamento en R?

Author

Samuel Calderon

Published

January 29, 2020

Para esta tarea vamos a hacer de uso dos paquetes principalmente: el viejo conocido tidyverse y también de ggpol, una extensión de ggplot2 desarrollada especialmente para este tipo de gráficos. ggforce nos servirá al final sólo para una mejora estética.

library(tidyverse)
library(ggpol)
library(ggforce)

Como en todo gráfico que se realiza con ggplot2, necesitamos primero contar con un data.frame o tibble que contenga la información necesaria para construirlo. La fuente primaria de estos datos es la web de la ONPE, de donde se puede obtener el detalle de la votación por varios niveles de desagregación. Debido a que no es propósito de este post mostrar cómo hacer el scrapping de la información, ni el cálculo de las curules, voy a preferir un resumen que ya ha trabajado otra persona para graficar en base a ello.

En la web de José Incio podemos encontrar un cuadro de la distribución de escaños del nuevo congreso peruano. Debido a que esa información aún está actualizándose según el conteo de los votos que ONPE sigue realizando, quiero hacer uso de Sys.time() para mostrar la hora en que estoy escribiendo este post.

Sys.time()
[1] "2023-05-19 11:41:38 -05"

Haciendo uso del add-in Paste as tribble que el paquete datapasta incluye en RStudio, puedo obtenr el tibble congreso, que no es más que un copy/paste de la tabla elaborada por José Incio disponible a esta hora.

votos <- tibble::tribble(
                                          ~Partido, ~Escaños,
                                  "ACCION POPULAR",      25L,
                        "ALIANZA PARA EL PROGRESO",      22L,
   "FRENTE POPULAR AGRICOLA FIA DEL PERU - FREPAP",      15L,
                                  "FUERZA POPULAR",      15L,
                               "UNION POR EL PERU",      13L,
                  "PARTIDO DEMOCRATICO SOMOS PERU",      11L,
                                    "PODEMOS PERU",      11L,
  "EL FRENTE AMPLIO POR JUSTICIA, VIDA Y LIBERTAD",       9L,
                                  "PARTIDO MORADO",       9L
  )

El siguiente paso es mejorar el tibble de tal modo que nos permita realizar el gráfico deseado. Empezamos por agregarle un color a cada uno de los partidos presentes en el gráfico. Podemos guiarnos de una hoja de referencia para escoger los colores, tomando en cuenta los colores partidarios. Podemos unir los colores a los partidos haciendo uso de bind_cols()

congreso <- tibble(
  colores = c(
  "darkred",
  "dodgerblue4",
  "deepskyblue3",
  "darkorange2",
  "gold2",
  "brown3",
  "royalblue3",
  "forestgreen",
  "mediumpurple4"
)) %>% 
  bind_cols(votos)

Ahora que contamos con los datos, simplemente realizamos el gráfico. Hacemos uso de geom_parliament() del paquete ggpol. Tan sólo necesitamos mapear dos argumentos:

  1. seats: la cantidad de escaños o asientos obtenidos
  2. fill: el nombre de los partidos

Además de eso, usaremos scale_fill_manual() para utilizar nuestros colores personalizados y el nombre de los partidos en la leyenda del gráfico. Luego, coord_fixed() nos ayuda a preservar el ratio de aspecto del gráfico.

grafico <- ggplot(congreso)+
  geom_parliament(
    aes(
      seats = Escaños, 
      fill = Partido), 
    color = "white") +
  scale_fill_manual(
    values = congreso$colores, 
    labels = congreso$Partido) +
  coord_fixed()

print(grafico)
Warning: Using the `size` aesthetic in this geom was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` in the `default_aes` field and elsewhere instead.

Vemos que hemos obtenido el gráfico y los partidos aparecen pintados con los colores que hemos asignado. Sin embargo, aún es posible hacerle unas mejoras estéticas. Usamos theme_no_axes() del paquete ggforce para eliminar las líneas guía de nuestro plano cartesiano y quedarnos sólo con un marco negro. También usamos labs() para agregarle un título a nuestro gráfico y theme() para cambiar el tamaño de los elementos de nuestra leyenda.

grafico +
  theme_no_axes() +
  labs(
    title = "DISTRIBUCIÓN DE ESCAÑOS") +
  theme(
    legend.text = element_text(
      size=5),
    legend.key.size = unit(
      x = 3, 
      units = "mm"))

Ya tenemos un gráfico más presentable y sencillo de replicar.