4 plotly

El paquete plotly es una poderosa herramienta para la creación de gráficos interactivos en R. Desarrollado inicialmente como una biblioteca para Python, plotly ha sido adaptado para R, permitiendo a los usuarios beneficiarse de sus capacidades de visualización dinámica y envolvente. La interactividad de los gráficos generados con plotly facilita que se puedan integrar en sitios web, y en combinación con otros paquetes como ineapir (véase (Crespo 2024)) se puede proporcionar un análisis directo e interactivo de datos extraidos en bruto del INE.

4.1 Características Principales

  1. Interactividad: plotly destaca por sus capacidades interactivas, permitiendo a los usuarios hacer zoom, desplazar, y obtener información detallada mediante “hover” sobre los elementos del gráfico.
  2. Compatibilidad con ggplot2: plotly puede convertir gráficos estáticos de ggplot2 en gráficos interactivos sin necesidad de reescribir el código original.
  3. Soporte para gráficos en 3D: plotly facilita la creación de gráficos tridimensionales, como superficies y dispersión en 3D, que son difíciles de lograr con otras herramientas.
  4. Integración con R Markdown y Shiny: los gráficos de plotly pueden integrarse fácilmente en documentos R Markdown y aplicaciones Shiny, mejorando la presentación de informes y el desarrollo de aplicaciones interactivas.
  5. Variedad de tipos de gráficos: desde gráficos de líneas y barras hasta mapas y gráficos de superficie, plotly soporta una amplia gama de visualizaciones.

4.2 Tipos de gráficos

La base de plotly es la interactividad de los gráficos que permite exploraciones más profundas y detalladas. En general, se pueden realizar:

  • Mapas interactivos: Permiten explorar datos geoespaciales por diferentes áreas.
  • Gráficos de barras: Facilitan la comparación de categorías y pueden permitir la selección dinámica de subcategorías.
  • Series temporales: Posibilitan filtrar por años y observar tendencias a lo largo del tiempo.
  • Histogramas interactivos: Permiten ajustar el número de bins y explorar la distribución de los datos.
  • Box plots: Ofrecen interactividad para seleccionar y resaltar datos atípicos o rangos específicos.
  • Gráficos de dispersión: Permiten hacer zoom y seleccionar áreas específicas para análisis detallado.
  • Gráficos de calor: Visualizan matrices de datos con interactividad para resaltar valores específicos.
  • Gráficos de burbujas: Facilitan la visualización de relaciones entre múltiples variables con capacidad de ajuste de tamaño y color de las burbujas.

4.2.1 Nota

Debido a que los gráficos generados con ploty son interactivos, se genera un conflicto a la hora de guardar estos como pdf ya que se debe seleccionar una de las posibles vistas estáticas de dichos gráficos. La siguiente línea de código incluye el paquete webshot que se encarga de guardar capturas (imágenes estáticas) de dichos gráficos interactivos a la hora de imprimir la página como .pdf .

4.3 Ejemplos de Uso

4.3.1 Gráfico interactivo

A continuación se muestra un ejemplo básico de cómo crear un gráfico interactivo con plotly a partir de un conjunto de datos:

# Instalar y cargar el paquete plotly
# install.packages("plotly")

# Verificar si está instalado
if (!require("plotly")) install.packages("plotly")
if (!require("dplyr")) install.packages("dplyr")
if (!require("webshot")) install.packages("webshot")
if (!require("ineapir")) install.packages("ineapir")

# Cargar paquete
library(dplyr)
library(plotly)
library(webshot)
library(ineapir)

# Datos de ejemplo
data <- mtcars
# Crear un grfico interactivo de dispersión
p <- plot_ly(data,
  x = ~wt, y = ~mpg, width = 800, height = 800, type = "scatter", mode = "markers",
  marker = list(size = 10, color = "rgba(255, 182, 193, .9)", line = list(color = "rgba(152, 0, 0, .8)", width = 2))
) %>%
  layout(
    title = "Relación entre Peso y Consumo de Combustible",
    xaxis = list(title = "Peso (1000 lbs)"),
    yaxis = list(title = "Millas por Galón")
  )

# Mostrar el gráfico
p

En este ejemplo, se utiliza el conjunto de datos mtcars para crear un gráfico de dispersión interactivo que muestra la relación entre el peso del vehículo y el consumo de combustible. El argumento marker permite personalizar la apariencia de los puntos en el gráfico, mientras que layout se utiliza para añadir títulos y etiquetas a los ejes.

4.3.2 Tree Maps

En este apartado se va a exponer como crear los Tree Maps un tipo de gráfico muy útil para ver como se distribuye una cierta característica entre diferentes categorías. Por ejemplo, en este caso, como se distribuye el gasto medio por persona en España dentro de los grupos ECOICOP8.

La ventaja de usar plotly es que nos permite construir TreeMaps interactivos, es decir, con distintos niveles de profundidad. En este caso en particular si apretamos en como se distribuye el gasto para el ECOICOP 01: Agricultura, ganadería, caza y servicios relacionados con las mismas, nos permite inspeccionar como se distribuye el gasto medio dentro de ese subnivel.

  1. En la web del ine buscamos la tabla que contiene los datos deseados, relativos a Gasto total, gastos medios y distribución del gasto de los hogares, que tiene por id 25143. (Véase https://www.ine.es/jaxiT3/Tabla.htm?t=25143&L=0)

  2. Usando ineapir extraemos los datos usando el servicio API del INE. Ejecutando get_metadata_table_varval(25143) vemos por que variables debemos filtrar para obtener los datos deseados.

get_metadata_table_varval(25143)
##        Id Fk_Variable
## 1   16473         349
## 2    8997          70
## 3    8998          70
## 4    8999          70
## 5    9000          70
## 6    9001          70
## 7    9002          70
## 8    9003          70
## 9    9004          70
## 10   9005          70
## 11   9006          70
## 12   9007          70
## 13   9008          70
## 14   9009          70
## 15   9010          70
## 16   9011          70
## 17   9012          70
## 18   9013          70
## 19   9015          70
## 20   8995          70
## 21 304092         762
## 22 304093         762
## 23 304094         762
## 24 304095         762
## 25 304096         762
## 26 304097         762
## 27 304098         762
## 28 304099         762
## 29 304100         762
## 30 304101         762
## 31 304102         762
## 32 304103         762
## 33 304104         762
## 34     72           3
## 35   8641           3
## 36   8642           3
## 37   8856          57
## 38   8857          57
## 39   8858          57
## 40   8859          57
## 41   8860          57
##                                                                                Nombre
## 1                                                                      Total Nacional
## 2                                                                           Andalucía
## 3                                                                              Aragón
## 4                                                             Asturias, Principado de
## 5                                                                      Balears, Illes
## 6                                                                            Canarias
## 7                                                                           Cantabria
## 8                                                                     Castilla y León
## 9                                                                Castilla - La Mancha
## 10                                                                           Cataluña
## 11                                                               Comunitat Valenciana
## 12                                                                        Extremadura
## 13                                                                            Galicia
## 14                                                               Madrid, Comunidad de
## 15                                                                  Murcia, Región de
## 16                                                        Navarra, Comunidad Foral de
## 17                                                                         País Vasco
## 18                                                                          Rioja, La
## 19                                                                              Ceuta
## 20                                                                            Melilla
## 21                                                                     Índice general
## 22                                                 Alimentos y bebidas no alcohólicas
## 23                                                       Bebidas alcohólicas y tabaco
## 24                                                                  Vestido y calzado
## 25                             Vivienda, agua, electricidad, gas y otros combustibles
## 26 Muebles, artículos del hogar y artículos para el mantenimiento corriente del hogar
## 27                                                                            Sanidad
## 28                                                                         Transporte
## 29                                                                     Comunicaciones
## 30                                                                     Ocio y cultura
## 31                                                                          Enseñanza
## 32                                                             Restaurantes y hoteles
## 33                                                           Otros bienes y servicios
## 34                                                                          Dato base
## 35                                                 Variación respecto al año anterior
## 36                                                     Variación respecto al año base
## 37                                                                        Gasto total
## 38                                                            Distribución porcentual
## 39                                                              Gasto medio por hogar
## 40                                                            Gasto medio por persona
## 41                                                  Gasto medio por unidad de consumo
##    Codigo
## 1      00
## 2      01
## 3      02
## 4      03
## 5      04
## 6      05
## 7      06
## 8      07
## 9      08
## 10     09
## 11     10
## 12     11
## 13     12
## 14     13
## 15     14
## 16     15
## 17     16
## 18     17
## 19     18
## 20     19
## 21     00
## 22     01
## 23     02
## 24     03
## 25     04
## 26     05
## 27     06
## 28     07
## 29     08
## 30     09
## 31     10
## 32     11
## 33     12
## 34       
## 35       
## 36       
## 37       
## 38       
## 39       
## 40       
## 41

Vemos que necesitamos filtrar por:

  • Geografía: Total Nacional.
  • ECOICOP(2 dígitos): Todos.
  • Tipo de dato: Dato base.
  • Gasto: Gasto medio por persona.

Es decir, lo ponemos en formato de lista para poder pasarlo por la función get_data_table()como filtro.

# Filtro
filter_ecoicop_1 <- list(
  "349" = "16473", # Total Nacional
  "762" = "", # Todos GRUPOS de 2 dígitos del ECOICOP
  "3" = "72", # Dato Base
  "57" = "8859" # Gasto medio por persona
) # Dato base


# Obtenemos datos
# nlast=1 para devolver sólo para el último periodo
data_ecoicop_1 <- get_data_table(
  filter = filter_ecoicop_1, idTable = 25143, nlast = 1, tip = "AM", unnest = TRUE,
  metacodes = TRUE, validate = FALSE, metanames = TRUE
)

Como hemos dicho que queremos que en el gráfico se pueda mostrar cómo se distribuye el gasto también dentro de cada grupo de ECOICOP, necesitamos un dígito más de desagregación en la clasificación ECOICOP, es decir, 3 dígitos. Buscamos de nuevo en la web del INE en que tabla se encuentran estos datos y filtramos de nuevo por lo pertinente. (Véase https://www.ine.es/jaxiT3/Tabla.htm?t=25144&L=0)

# Vemos por que variables se puede fitrar
# get_metadata_table_varval(25144)

Vemos que necesitamos filtrar por:

  • Geografía: Total Nacional.
  • ECOICOP(3 dígitos): Todos.
  • Tipo de dato: Dato base.
  • Gasto: Gasto medio por persona.
filter_ecoicop_2 <- list(
  "349" = "16473", # Total Nacional
  "796" = "", # Todos GRUPOS de 2 dígitos del ECOICOP
  "3" = "72", # Dato base
  "57" = "8859" # Gasto medio por persona
)

# Obtenemos datos
# nlast=1 para devolver sólo para el último periodo
data_ecoicop_2 <- get_data_table(filter = filter_ecoicop_2, idTable = 25144, nlast = 1, tip = "AM", unnest = TRUE, metacodes = TRUE, validate = FALSE, metanames = TRUE)

Una vez obtenidos todos los datos, debemos juntar los datos en un data frame que contenga la siguiente estructura:

  • id: único para cada fila
  • label: etiqueta con cada grupo de ECOICOP
  • parent: indica quien es el superior jerárquico de dicha fila. Por ejemplo de ECOICOP 01.1 su parent es 01. Es necesario para poder mapear bien el gráfico.
  • values: indica el valor que toma dicha entrada.
# Datos para ECOICOP con 3 dígitos
data_ecoicop_2 <- data_ecoicop_2[, c("Subgrupos.de.gasto.(3.dígitos)", "Subgrupos.de.gasto.(3.dígitos).Codigo", "Valor")]

# quitamos el total
data_ecoicop_2 <- data_ecoicop_2[data_ecoicop_2[, "Subgrupos.de.gasto.(3.dígitos).Codigo"] != "00", ]





# Función que a cada elemento de ECOICOP 3 dígitos, asocia su grupo de agregación de 2 dígitos
get_label <- function(inputs, label) {
  # Extrae los primeros dos caracteres de cada elemento del vector de entrada
  prefixes <- substr(inputs, 1, 2) # tomamos sólo 2 primeros eltos Ej: 01.1 tomamos 01
  # Usa sapply para aplicar la función a cada prefijo
  sapply(prefixes, function(prefix) {
    if (prefix == "01") {
      return(label[2])
    } else if (prefix == "02") {
      return(label[3])
    } else if (prefix == "03") {
      return(label[4])
    } else if (prefix == "04") {
      return(label[5])
    } else if (prefix == "05") {
      return(label[6])
    } else if (prefix == "06") {
      return(label[7])
    } else if (prefix == "07") {
      return(label[8])
    } else if (prefix == "08") {
      return(label[9])
    } else if (prefix == "09") {
      return(label[10])
    } else if (prefix == "10") {
      return(label[11])
    } else if (prefix == "11") {
      return(label[12])
    } else if (prefix == "12") {
      return(label[13])
    } else {
      return(NA) # Devuelve NA si el prefijo no coincide con ninguno
    }
  })
}

Ahora definimos los elementos parenty labels necesarios para ejecutar el TreeMap. Concretamente:

  • labels: Define los nomrbes de cada elemento represetnado en el gráfico.
  • parent: Contiene el grupo superior jerárquico de cada elemento. Por ejemplo GRUPO 01. ALIMENTOS Y BEBIDAS NO ALCOHÓLICAS*
# Etiquetas
labels <- c(data_ecoicop_1$`Grupos.de.gasto.(2.dígitos)`, data_ecoicop_2$`Subgrupos.de.gasto.(3.dígitos)`)

# Aplicamos funcion a ECOICOP con 3 dígitos y con label las de ECOICOP 2 dígitos
parent <- get_label(data_ecoicop_2$`Subgrupos.de.gasto.(3.dígitos).Codigo`, label = data_ecoicop_1$`Grupos.de.gasto.(2.dígitos)`)

# parents, el del primer elemento es , es decir, el total. Los del primer nivel
# el parent es Índice Total=labels[1]
# En el segundo nivel, ya lo que corresponda
aux <- data_ecoicop_1$`Grupos.de.gasto.(2.dígitos)`
parents <- c("", rep(aux[1], length(aux) - 1), parent)

Ahora, se representan los datos como un TreeMap, ajustando los parámetros para que no haya problemas de visualización.

fig<-plot_ly(
  type = "treemap",
  labels = labels,
  parents = parents,
  textinfo = "label+value+percent entry+percent root",
  hoverinfo = "label+value+percent entry+percent root",
  values = as.integer(c(data_ecoicop_1$Valor, data_ecoicop_2$Valor)),
  maxdepth = 2,
  branchvalues = "total",
  tiling = list(squarifyratio = 2)
)
# Imporante ajustar este numero para que quede bontito
# Quitarlo para ver que pasa sin el
fig

FIGURA 4.1: Distribución del gasto medio por persona en España para el año 2022.

4.3.3 Series Temporales

Plotly ofrece potentes herramientas para la visualización de series temporales, permitiendo a los usuarios interactuar con los datos de manera dinámica y obtener información valiosa de forma rápida y efectiva. Su capacidad para crear gráficos atractivos y funcionales lo convierte en una opción excelente para el análisis de datos temporales.

Características Clave de Plotly para Series Temporales

  • Interactividad:

    • Zoom y Pan: Los usuarios pueden acercar y alejar secciones del gráfico.
    • Hover: Información detallada aparece al pasar el cursor sobre los puntos de datos.
    • Selección de Rangos: Rangos deslizantes y botones de selector para ajustar la ventana temporal visualizada.
  • Elementos Visuales

    • Líneas y Marcadores: Visualización clara de tendencias y puntos específicos.
    • Colores y Estilos Personalizables: Facilitan la distinción entre diferentes series de datos.
  • Funciones Avanzadas:

    • Rangeselector: Botones para seleccionar periodos específicos (e.g., últimos 3 meses, último año).
    • Rangeslider: Barra deslizante para ajustar el rango de fechas mostrado.
    • Anotaciones y Formateo: Posibilidad de agregar notas y ajustar el formato de fechas.

Los datos los obtendremos usando ineapir, para más información (véase (Crespo 2024)).

  1. En la web del ine buscamos la serie que contiene los datos deseados, población de españa, que tiene por id ECP319(hombres) y ECP318(mujeres).

  2. Usando ineapir extraemos los datos usando el servicio API del INE.

# Población Hombres
# Mirando en la web del INE cual es el código de la operación
# ECP319

# Hombres
a <- get_data_series(codSeries = "ECP319", tip = "AM", dateStart = "1971/01/01", unnest = TRUE)
# Mujeres
b <- get_data_series(codSeries = "ECP318", tip = "AM", dateStart = "1971/01/01", unnest = TRUE)

data <- data.frame(fecha = as.Date(a$Fecha), Year = a$Anyo, Hombres = a$Valor, Mujeres = b$Valor)


# Filtramos
data <- data %>%
  filter(format(as.Date(fecha), "%m") == "01")
# Crear el gráfico interactivo
fig <- plot_ly(data, x = ~Year) %>%
  add_lines(y = ~Mujeres, name = "Mujeres", line = list(color = "#457e76")) %>%
  add_lines(y = ~Hombres, name = "Hombres", line = list(color = "#881333")) %>%
  layout(
    title = "Evolución de la Población",
    xaxis = list(
      title = "Año"
    ),
    yaxis = list(title = "Población"),
    legend = list(title = list(text = "<b>Sexo</b>")),
    hovermode = "closest"
  ) %>%
  config(locale = "es")

# Mostrar el gráfico
fig

4.3.3.1 Evolución IPC

Ahora vamos a mostrar la evolución del IPC y el IPC Subyacente a lo largo de los años. Para ello, lo primero buscamos en la web del INE en que tabla se encuentran dichos datos, siendo esta la “50902”. A continuación, con get_metadata_table_varval(50902) vemos que variables y valores hay que tomar para filtrar IPC por Índice General y por Variación Anual.

  1. En la web del ine buscamos la tabla que contiene los datos deseados, que tiene por id 50902. (Véase https://www.ine.es/jaxiT3/Tabla.htm?t=50902&L=0)

  2. Usando ineapir extraemos los datos usando el servicio API del INE. Ejecutando get_metadata_table_varval(50902).

get_metadata_table_varval(50902)
##        Id Fk_Variable
## 1  304092         762
## 2  304093         762
## 3  304094         762
## 4  304095         762
## 5  304096         762
## 6  304097         762
## 7  304098         762
## 8  304099         762
## 9  304100         762
## 10 304101         762
## 11 304102         762
## 12 304103         762
## 13 304104         762
## 14     83           3
## 15     84           3
## 16     74           3
## 17     87           3
##                                                                                Nombre
## 1                                                                      Índice general
## 2                                                  Alimentos y bebidas no alcohólicas
## 3                                                        Bebidas alcohólicas y tabaco
## 4                                                                   Vestido y calzado
## 5                              Vivienda, agua, electricidad, gas y otros combustibles
## 6  Muebles, artículos del hogar y artículos para el mantenimiento corriente del hogar
## 7                                                                             Sanidad
## 8                                                                          Transporte
## 9                                                                      Comunicaciones
## 10                                                                     Ocio y cultura
## 11                                                                          Enseñanza
## 12                                                             Restaurantes y hoteles
## 13                                                           Otros bienes y servicios
## 14                                                                             Índice
## 15                                                                  Variación mensual
## 16                                                                    Variación anual
## 17                                                      Variación en lo que va de año
##    Codigo
## 1      00
## 2      01
## 3      02
## 4      03
## 5      04
## 6      05
## 7      06
## 8      07
## 9      08
## 10     09
## 11     10
## 12     11
## 13     12
## 14      0
## 15      1
## 16      2
## 17      5

Vemos que necesitamos filtrar por:

  • Grupo: Indice general.
  • Tipo dato: Variación anual.

Posteriormente, se obtienen los datos, mediante el uso de dicho filtro.

# Todos los approaches  de filtrado son similares
# 762(grupo)= 304092(Indie general).      3(tipodato)=74(Variacion anual)
filter <- list(values = c("variación anual", "índice general"))
filter <- list(grupo = "304092", tipodato = "74")
filter <- list("762" = "304092", "3" = "74")



# IPC GENERAL
# Table url: https://www.ine.es/jaxiT3/Tabla.htm?t=50902&L=0
general <- get_data_table(
  idTable = 50902, filter = filter, unnest = TRUE,
  tip = "A", validate = FALSE
)

# IPC SUBYACENTE
# get_metadata_table_varval(50907)
filter <- list(
  "3" = "74", # Fk_variable=Id
  "269" = "12850" # Fk_variable=Id
)
# Filter core cpi
filter <- list(values = c(
  "variación anual",
  "General sin alimentos no elaborados ni productos energéticos"
))

# Request data of core cpi
# Table url: https://www.ine.es/jaxiT3/Tabla.htm?t=50907&L=0
subyacente <- get_data_table(
  idTable = 50907, filter = filter, unnest = TRUE,
  tip = "A", validate = FALSE
)

# Format Fecha column as date
general$Fecha <- as.Date(general$Fecha)
subyacente$Fecha <- as.Date(subyacente$Fecha)

Una vez hemos preparado los datos, los dibujamos en un gráfico interactivo:

# Plot cpi overall index
fig <- plot_ly(general,
  x = ~Fecha, y = ~Valor, name = "General",
  type = "scatter", mode = "lines", line = list(color = "#457e76", dash = "dashed")
)

## Plot core cpi
fig <- fig %>%
  add_trace(
    y = ~ subyacente$Valor, name = "Subyacente",
    mode = "lines", line = list(color = "#881333", dash = "dashed")
  ) %>%
  layout(
    yaxis = list(title = "Variación anual (%)"),
    legend = list(
      title = list(text = "<b> IPC </b>"),
      x = 0.25,
      y = -0.25,
      orientation = "h"
    ),
    hovermode = "x"
  ) %>%
  config(displayModeBar = FALSE) %>%
  config(locale = "es")

fig

4.3.4 Grafico de barras

Los gráficos de barras en Plotly permiten comparar fácilmente valores entre diferentes categorías. Pueden ser verticales u horizontales, y se pueden personalizar con colores específicos para cada barra. También soportan la agrupación de barras (bar charts) y la apilación (stacked bar charts). La orientación, orden y formato de los ejes pueden ser ajustados para mejorar la legibilidad, y se pueden añadir anotaciones y etiquetas detalladas para proporcionar contexto adicional a los datos visualizados.

  1. En la web del ine buscamos la tabla que contiene los datos deseados, que tiene por id 2915. (Véase https://www.ine.es/jaxiT3/Tabla.htm?t=2915&L=0)

  2. Usando ineapir extraemos los datos usando el servicio API del INE. Ejecutando get_metadata_table_varval(2915).

get_metadata_table_varval(2915)
##       Id Fk_Variable                      Nombre Codigo
## 1  16473          70                       Total     00
## 2   8997          70                   Andalucía     01
## 3   8998          70                      Aragón     02
## 4   8999          70     Asturias, Principado de     03
## 5   9000          70              Balears, Illes     04
## 6   9001          70                    Canarias     05
## 7   9002          70                   Cantabria     06
## 8   9003          70             Castilla y León     07
## 9   9004          70        Castilla - La Mancha     08
## 10  9005          70                    Cataluña     09
## 11  9006          70        Comunitat Valenciana     10
## 12  9007          70                 Extremadura     11
## 13  9008          70                     Galicia     12
## 14  9009          70        Madrid, Comunidad de     13
## 15  9010          70           Murcia, Región de     14
## 16  9011          70 Navarra, Comunidad Foral de     15
## 17  9012          70                  País Vasco     16
## 18  9013          70                   Rioja, La     17
## 19  9015          70                       Ceuta     18
## 20  8995          70                     Melilla     19
## 21 20275          34                       Total      A
## 22 20267          34               Menos de 101       B
## 23 20264          34               De 101 a 500       C
## 24 20270          34              De 501 a 1.000      D
## 25 20260          34           De 1.001 a 2.000       E
## 26 20262          34           De 2.001 a 5.000       F
## 27 20274          34          De 5.001 a 10.000       G
## 28 20273          34         De 10.001 a 20.000       H
## 29 20263          34         De 20.001 a 50.000       I
## 30 20265          34        De 50.001 a 100.000       J
## 31 20266          34       De 100.001 a 500.000       K
## 32 20268          34             Más de 500.000       L

Vemos que necesitamos filtrar por:

  • Tamaño de municipios: Total.
filter <- list("34" = "20275") # 34(Tamaño municipios)=20275(Total)
data2 <- get_data_table(2915, filter = filter, unnest = TRUE, tip = "AM", nlast = 1, metanames = TRUE) # nlast=1 nos devuelve el útlimo año sólo
data2 <- data2[-1, ] # Quitamos primera observación. Total España
# Ordenar el dataframe por la columna 'poblacion'
data2 <- data.frame(poblacion = data2$Valor, ccaa = data2$Comunidades.y.Ciudades.Autónomas)
data2 <- data2[order(data2$poblacion), ]



# Crear el gráfico de barras horizontales
fig <- plot_ly(data2,
  x = ~poblacion, y = ~ factor(ccaa, levels = data2$ccaa), type = "bar", orientation = "h",
  marker = list(color = "#ddeeec", line = list(color = "#457e76", width = 1.5))
) %>%
  layout(
    title = "Población por Comunidad Autónoma",
    xaxis = list(
      title = "Población",
      tickformat = ".,", # Formatear los números para que se muestren con punto como separador de miles
      tickprefix = " ", # Espacio para mejorar la legibilidad
      separatethousands = TRUE # Asegurar que los miles se separen correctamente
    ),
    yaxis = list(title = "Comunidad Autónoma"),
    margin = list(l = 150) # Ajustar el margen izquierdo para evitar que las etiquetas se corten
  ) %>%
  config(locale = "es")
# Mostrar el gráfico
fig

4.3.5 Gráfico Sankey

Este tipo de gráfico es poco conocido pero muy útil para visualizar ciertos fenómenos sociales/demográficos. Por ejemplo: mostrar la evolución de la intención de voto, representando como se han desplazado las intenciones entre diferentes periodos; mostrar la evolución de la situación laboral de la comunidad, mostrando los flujos entre distintos estados laborales en distintos periodos.

Veamos pues este último gráfico. El objetivo es intentar reproducir la aplicación del INE Flujos de personas en el mercado laboral. En este caso, dentro de bookdown, la aplicación no se puede hacer tan dinámica como la presentada en la web del INE, ya que el formato no es el adecuado para ello 9.

  1. En la web del ine buscamos la tabla que contiene los datos deseados, que tiene por id 13930. (Véase https://www.ine.es/jaxiT3/Tabla.htm?t=66257&L=0)

  2. Usando ineapir extraemos los datos usando el servicio API del INE. Ejecutando get_metadata_table_varval(66257).

# Tabla 66257. Información del mercado laboral
# Vemos sus metadatos para ver por que filtrar
get_metadata_table_varval(66257)
##        Id Fk_Variable                         Nombre Codigo
## 1     454          18                    Ambos sexos       
## 2     452          18                        Hombres      1
## 3     453          18                        Mujeres      6
## 4  283949         386       Total (trimestre actual)       
## 5   21332         386    Ocupados (trimestre actual)       
## 6   21335         386     Parados (trimestre actual)       
## 7   20279         386   Inactivos (trimestre actual)       
## 8  283949         539     Total (trimestre anterior)       
## 9   21332         539  Ocupados (trimestre anterior)       
## 10  21335         539   Parados (trimestre anterior)       
## 11  20279         539 Inactivos (trimestre anterior)       
## 12 283997         539 No consta (trimestre anterior)

Vemos que debemos filtrar por ambos sexos:

filter <- list("18" = "454") # "Sexo"="Ambos sexos"

datos <- get_data_table(66257, filter = filter, metanames = TRUE, tip = "AM", metacodes = TRUE, unnest = TRUE, nlast = 1)

# Quitamos los datos totales
datos <- datos %>%
  filter(Relación.con.la.actividad.en.el.trimestre.actual.Id != "283949") %>%
  filter(Relación.con.la.actividad.en.trimestre.anterior.Id != "283949")

Para el sankey plot hay que crear un “diccionario” de etiquetas para saber como pintarlas. Véase documentación para más información.

# Necesario para el sankey plot
# Crear etiquetas únicas
labels <- unique(c(
  datos$Relación.con.la.actividad.en.trimestre.anterior,
  datos$Relación.con.la.actividad.en.el.trimestre.actual
))
labels <- c(labels[3], labels[1], labels[2], labels[4], labels[7], labels[5], labels[6])
# Crear un dataframe para mapear las etiquetas a índices
label_map <- data.frame(label = labels, id = seq_along(labels) - 1)
# Hacemos join con las etiquetas
filtered_data <- datos %>%
  left_join(label_map, by = c("Relación.con.la.actividad.en.trimestre.anterior" = "label")) %>%
  rename(source = id) %>%
  left_join(label_map, by = c("Relación.con.la.actividad.en.el.trimestre.actual" = "label")) %>%
  rename(target = id)
# Asignar colores a los enlaces (opcional)
link_colors <- ifelse(filtered_data$source == 0, "#FFD700", # Inactivos
  ifelse(filtered_data$source == 1, "#CD853F", # Ocupados
    ifelse(filtered_data$source == 2, "#FF4500", # Parados
      "#9e3a26" # No consta
    )
  )
)


fig <- plot_ly(
  type = "sankey",
  orientation = "h",
  node = list(
    label = labels,
    color = c("#FFD700", "#CD853F", "#FF4500", "#9e3a26", "#FFD700", "#CD853F", "#FF4500", "#9e3a26"),
    pad = 15,
    thickness = 20,
    line = list(color = "black", width = 0.5)
  ),
  link = list(
    source = filtered_data$source,
    target = filtered_data$target,
    value = filtered_data$Valor,
    color = link_colors
  )
)

fig <- fig %>%
  layout(
    title = "Transición de Actividades Económicas entre Trimestres",
    font = list(size = 10)
  ) %>%
  config(locale = "es")
fig

FIGURA 4.2: Flujos de personas en el mercado laboral en España 2024 T2

4.4 Más información

Para más información sobre el paquete plotly y sus posibles funciones, buscar en la siguiente web:

https://plotly.com/r/getting-started/

References

Crespo, David. 2024. Ineapir: Obtaining Data Published by the National Statistics Institute. https://github.com/es-ine/ineapir.

  1. La ECOICOP es una clasificación europea de consumo, que facilita la consulta conjunta con otras estadísticas como el IPC, y a su vez permite la comparabilidad de datos con otros países. Clasifica los bienes y servicios en 12 grandes grupos de gasto (del 01 al 12).↩︎

  2. Para ver una aplicación dinámica como la presente en la web del INE, ver apartado de Shiny Apps o FlexDashboards.↩︎