Importamos librerías

if (!"tidyverse" %in% installed.packages()) {install.packages("tidyverse")}
if (!"jsonlite" %in% installed.packages()) {install.packages("jsonlite")}
if (!"ggalluvial" %in% installed.packages()) {install.packages("ggalluvial")}
if (!"ggwordcloud" %in% installed.packages()) {install.packages("ggwordcloud")}
if (!"ggrepel" %in% installed.packages()) {install.packages("ggrepel")}
library(tidyverse)
library(jsonlite)
library(ggalluvial)
library(ggwordcloud)    
library(ggrepel)

Leemos El fichero de la votación y el de diputados

# Cuidado porque esta url puede cambiar
diputados <- fromJSON("https://www.congreso.es/webpublica/opendata/diputados/DiputadosActivos__20221229063010.json")

# Votación malversación
data <- fromJSON("https://www.congreso.es/webpublica/opendata/votaciones/Leg14/Sesion226/20221215/Votacion020/VOT_20221215191151.json")
nombre_votación <-"Reducción de penas por malversación"

# Votación de Ley Solo Si es Si
#data <- fromJSON("https://www.congreso.es/webpublica/opendata/votaciones/Leg14/Sesion196/20220825/Votacion008/VOT_20220825173242.json")
#nombre_votación <- "Ley del solo Sí es Sí" 

# Votación de Ley Trans
#data <- fromJSON("https://www.congreso.es/webpublica/opendata/votaciones/Leg14/Sesion229/20221222/Votacion371/VOT_20221222175412.json")
#nombre_votación <- "Ley Trans"

Preparamos los datos

# Agrupamos las formaciones electorales por partido para simplificar etiquetas
PSOE <- c("PSOE","PSC-PSOE","PsdeG-PSOE","PSE-EE-PSOE")
PP<- c ("PP","PP-FORO")
UP <- c("UP","ECP-GUAYEM EL CANVI", "EC-UP")
partidos_grandes <- c ("PSOE","PP","UP","Vox", "ERC-S","Cs")

progresistas <- c("PSOE","UP", "ERC-S" ,"MÁS PAÍS-EQUO","EH Bildu","CUP-PR","MÁS PAÍS-EQUO",
                   "¡Teruel Existe!","BNG","CCa-PNC-NC","MÉS COMPROMÍS" ,"NC-CCa-PNC")
conservadores <- c("PP", "Vox","Cs","EAJ-PNV","JxCat-JUNTS (Junts)","JxCat-JUNTS (PDeCAT)","NA+","PRC")
nacionalistas <- c ( "ERC-S","EAJ-PNV","EH Bildu","JxCat-JUNTS (Junts)","JxCat-JUNTS (PDeCAT)","CUP-PR",
                     "NA+","¡Teruel Existe!","PRC","BNG","CCa-PNC-NC","MÉS COMPROMÍS","NC-CCa-PNC")
informacion <- data$informacion
totales <- data$totales
votaciones <- data$votaciones
# Creamos una columna con el partido de cada formación electoral
diputados <- diputados %>%
             mutate (partido = ifelse (FORMACIONELECTORAL %in% PSOE,"PSOE",
                                  ifelse (FORMACIONELECTORAL %in% PP,"PP",
                                    ifelse (FORMACIONELECTORAL %in% UP,"UP",FORMACIONELECTORAL)))) %>%
             mutate (ideologia = ifelse (partido %in% progresistas, "Progresista","Conservador" )) %>%
             mutate (ambito = ifelse (partido %in% nacionalistas, "Nacionalista-Regionalista","Nacional" ))

# Ordenamos los partidos por votos
orden_partidos <- diputados %>%
                  group_by (partido) %>%
                      summarise(escanios = n()) %>%
                  ungroup() %>%
                  arrange (-escanios) 
print (unique (orden_partidos$partido))
##  [1] "PSOE"                 "PP"                   "Vox"                 
##  [4] "UP"                   "ERC-S"                "Cs"                  
##  [7] "EAJ-PNV"              "EH Bildu"             "JxCat-JUNTS (Junts)" 
## [10] "JxCat-JUNTS (PDeCAT)" "CUP-PR"               "MÁS PAÍS-EQUO"       
## [13] "NA+"                  "¡Teruel Existe!"      "BNG"                 
## [16] "CCa-PNC-NC"           "MÉS COMPROMÍS"        "NC-CCa-PNC"          
## [19] "PRC"
diputados$partido <- factor (diputados$partido, levels = unique (orden_partidos$partido))
# Damos color a los partidos
color_partidos <- rev(c("PSOE" = "#FF0000","PP" = "#09DBDE","Vox"= "#11CA08", "UP" = "#6329CF",  "ERC-S" = "#F2C005", 
                  "Cs"= "#FF7800", "EAJ-PNV" = "#298B13",
                  "EH Bildu" = "#ACE155", "JxCat-JUNTS (Junts)" = "#36E0C4", "JxCat-JUNTS (PDeCAT)" = "#585754",
                   "CUP-PR" =  "#585754",  "MÁS PAÍS-EQUO" =  "#26CF96",
                  "NA+"  = "#585754", "¡Teruel Existe!" = "#585754" , "BNG" = "#585754", "CCa-PNC-NC" = "#585754",
                  "MÉS COMPROMÍS" = "#585754", "NC-CCa-PNC" = "#585754", "PRC" = "#585754"))
# Ordenamos los votos
orden_voto <- c("Sí","No","Abstención","No vota")
votaciones$voto <- factor (votaciones$voto, levels = orden_voto)
# damos color a los votos
color_voto <- c("Sí" = "#028504","No" = "#DC1403","Abstención" = "#585754","No vota" = "black")
# Unimos votación y partidos
votaciones <- merge(votaciones,diputados, by.x="diputado", by.y ="NOMBRE") 

Vista en diagrama de barras

ggplot(data = votaciones,
       aes(x = voto, fill=partido)) +
  geom_bar( aes( y = ..count..),
            stat="count",
            position ="stack",
            width=.17,
            alpha =1) +
  geom_text_repel( aes(label = partido,  y = ..count.., color = partido),
            stat="count",
            position =position_stack(),
            max.overlaps=20,
            #nudge_x = 0.2, # Ajuste eje x
            #nudge_y = 0, # Ajuste eje y
            force = 1.5,
            #force_pull =2,
            direction="y",
            vjust = 1.6,
            hjust = 1,
            segment.size = 0.2,
            segment.linetype = 2,
            size =3,
            fontface="bold") +
  scale_fill_manual(values = color_partidos) +
  scale_color_manual(values = color_partidos) +
  labs(title = paste("Votación en el Congreso de los Diputados, sesión", informacion$sesion, informacion$fecha),
       subtitle = nombre_votación,
       x="",y="",
       caption = "@congosto")+
  theme_minimal() +
  theme (legend.position = "none",
        panel.border = element_blank(),
        axis.text.x=element_text(size=14))

Vista en aluvial del voto de las minorías

votaciones_minorias <- votaciones %>%
                      filter (!partido %in% partidos_grandes)  %>%
                      group_by (partido,voto)  %>%
                        summarise(mum_votos = n(),
                        .groups = "drop")  %>%
                      ungroup()

ggplot(data = votaciones_minorias,
       aes(y = mum_votos,
            axis1 = partido, axis2 = voto)) +
  geom_alluvium(aes(fill = voto), width = 1/12) +
  geom_stratum(width = 1/12, fill = "#585754", color = "grey") +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_x_discrete(limits = c("Partido", "Voto"), expand = c(.05, .05)) +
  scale_fill_manual (values = color_voto) +
  guides(fill = "none") +
  guides(color = "none") +
  labs(title = paste("Votación en el Congreso de los Diputados (minorías), sesión", informacion$sesion, informacion$fecha),
       subtitle = nombre_votación,
       x="",y="",
       caption = "@congosto")+
  theme_minimal() +
  theme ( axis.text.x=element_text(size=14))

Votos de los diputados por tipo de voto

votaciones_diputados <- votaciones %>%
                    group_by (partido,diputado,voto) %>%
                      summarise(freq = n(),
                      .groups = "drop") %>% # Calculamos la frecuencia de cada palabra
                    ungroup () %>%
                    arrange (voto) # Ordenamos por voto
ggplot() +
  # Dibujamos la nube de palabras
  geom_text_wordcloud_area(data = votaciones_diputados ,
                           aes(label = diputado, color = partido),
                           size =3,
                           angle = 0.35) +
  # Definimos la proporción del tamaño de las letras según frecuencia
   # Aplicamos una paleta de color
  scale_color_manual(values = color_partidos) +
  # Definimos el título principal y el de los ejes
  labs(title = paste("Votación de los diputados del Congreso, sesión", informacion$sesion, informacion$fecha),
       subtitle = nombre_votación,
       x="",y="",
       caption = "@congosto")+
  facet_wrap(~voto ) +
  # Aplicamos un template minimalista
  theme_minimal() +
  theme (title = element_text(size=22),
    strip.text = element_text(size=20))

## Votaciones por bloques ideologicos/ Ámbito

ggplot(data = votaciones,
       aes(x = voto, fill=partido)) +
  geom_bar( aes( y = ..count..),
            stat="count",
            show.legend = FALSE,
            position ="stack",
            width=.17,
            alpha =1) +
  geom_text_repel( aes(label = partido,  y = ..count.., color = partido),
            stat="count",
            show.legend = FALSE,
            position =position_stack(),
            max.overlaps=20,
            #nudge_x = 0.2, # Ajuste eje x
            #nudge_y = 0, # Ajuste eje y
            force = 1,
            #force_pull =2,
            direction="y",
            vjust = 1.3,
            hjust = 1,
            segment.size = 0.2,
            segment.linetype = 2,
            size =3,
            fontface="bold") +
  scale_fill_manual(values = color_partidos) +
  scale_color_manual(values = color_partidos) +
  # Definimos el título principal y el de los ejes
  labs(title = paste("Votación por partidos, sesión", informacion$sesion, informacion$fecha),
       subtitle = nombre_votación,
       x="",y="",
       caption = "@congosto")+
  facet_grid(ambito ~ ideologia ) +
  # Aplicamos un template minimalista
  theme_minimal() +
  theme (legend.position = "top",
         strip.text = element_text(size=16),
         panel.background = element_rect())