1. Introducción

En este taller aprenderemos el uso del paquete ggplot2, un paquete de R basado en la gramática de gráficos que permite visualizar datos de una manera consistente y estructurada. Para hacer más versátil su uso, se recomienda conocer el funcionamiento del paquete dplyr y el uso de tuberías (pipes %>%). ggplot2 no está contenido en la librería tidyverse. Por eso, hay que instalarlo de forma separada. tidiverse sí incluye otros paquetes como dplyr que, a su vez, incluye los pipes (%>%). Para más detalles sobre tidyverse puede ir al Taller de Introducción a R y RStudio.

1.1. Conceptos básicos a desarrollar

En esta práctica se desarrollarán los siguientes conceptos:

  • Gramática de gráficos
  • Visualización de datos

1.2. Librerías necesarias para el taller

Por favor cargue las siguientes librerías

library(knitr)
library(tidyverse)
library(lubridate)
library(ggplot2)

1.3. Objetivos

  • Reconocer las funciones que componen el paquete ggplot2.
  • Realizar gráficos básicos con la estructura de ggplot2.

2. Gramática de gráficos

ggplot2 recibe su nombre precisamente de la abreviación del término gramática de gráficos (gg). La gramática de los gráficos se refiere a un enfoque conceptual propuesto y desarrollado por Leland Wilkinson para la creación de gráficos, el cual sirvió como base para el desarrollo de ggplot2 a manos de Hadley Wickham. La gramática de los gráficos proporciona un marco conceptual para pensar sobre cómo construir y entender visualizaciones de datos de una manera coherente y estructurada. En términos simples, la gramática de los gráficos descompone un gráfico en sus componentes fundamentales y define cómo se combinan estos componentes para representar datos.

Estos componentes básicos son:

  1. Datos (Data): representan los datos que queremos visualizar. Puede ser una tabla de datos (data.frame) en R u otra fuente de datos.

  2. Estética (Aesthetics): definen cómo se mapean los atributos de los datos a propiedades visuales del gráfico, como posición en el eje X (x), posición en el eje Y (y), color, forma, tamaño, etc. Esto se especifica mediante la función aes() en ggplot2.

  3. Geometría (Geometry): representa la forma en que los datos se visualizan en el gráfico, como puntos, líneas, barras, áreas, etc. Cada tipo de gráfico tiene su función correspondiente en ggplot2, como geom_point() para un gráfico de dispersión o geom_bar() para un gráfico de barras.

  4. Escala (Scale): define cómo se mapean los valores de los datos a los valores visuales, como el rango de colores o el rango de los ejes. ggplot2 ajusta automáticamente las escalas, pero también puedes personalizarlas con funciones como scale_log10(),``scale_x_continuous() o scale_color_manual().

  5. Facetas (Facets): permiten dividir los datos en subconjuntos y mostrarlos en paneles múltiples (facetas) según ciertas variables. Puedes usar facet_wrap() o facet_grid() en ggplot2 para implementar esta funcionalidad.

  6. Temas (Themes): controlan la apariencia visual general del gráfico, como títulos, etiquetas de ejes, fondos, etc. Puedes personalizar el tema con la función theme() en ggplot2.

Ahora, veremos cada uno de los componentes para realizar gráficos de datos con ggplot2.

3. Datos para ggplot2

Siempre se requiere una tabla de datos (una estructura con filas y columnas) para poder ser usada en la estética de los gráficos. Previo al uso de ggplot2, suele ser necesario realizar un proceso de limpieza y organización de los datos. Para este taller usaremos una base de datos limpia, que nos permita hacer las visualizaciones sin la necesidad de pre-procesar los datos.

La tabla de datos para este taller puede encontrarla en: https://github.com/TRACE-LAC/TRACE-LAC-data/blob/main/otros/muestra_covid.RDS?raw=true.

Si ya cuenta con los datos en su computador, puede ejecutar los el siguiente comando

covid19 <- readRDS("data/muestra_covid.RDS")

Una vez obtenida la tabla de datos es necesario explorar sus datos para conocer su estado actual.

glimpse(covid19)
## Rows: 10,000
## Columns: 23
## $ fecha_reporte_web            <dttm> 2021-06-29, 2021-04-23, 2021-06-07, 2021…
## $ id_de_caso                   <dbl> 4208058, 2737390, 3576919, 2944674, 23005…
## $ fecha_de_notificacion        <dttm> 2021-06-15, 2021-04-19, 2021-05-24, 2021…
## $ codigo_divipola_departamento <dbl> 68, 5, 68, 11, 13001, 54, 66, 5, 81, 25, …
## $ nombre_departamento          <chr> "SANTANDER", "ANTIOQUIA", "SANTANDER", "B…
## $ codigo_divipola_municipio    <dbl> 68001, 5001, 68001, 11001, 13001, 54001, …
## $ nombre_municipio             <chr> "BUCARAMANGA", "MEDELLIN", "BUCARAMANGA",…
## $ edad                         <dbl> 39, 73, 15, 45, 22, 20, 45, 48, 71, 24, 3…
## $ sexo                         <chr> "F", "F", "M", "F", "M", "M", "M", "F", "…
## $ tipo_de_contagio             <chr> "Relacionado", "Comunitaria", "Relacionad…
## $ ubicacion_del_caso           <chr> "Casa", "Casa", "Casa", "Casa", "Casa", "…
## $ estado                       <chr> "Leve", "Leve", "Leve", "Leve", "Leve", "…
## $ recuperado                   <chr> "Recuperado", "Recuperado", "Recuperado",…
## $ fecha_de_inicio_de_sintomas  <dttm> 2021-06-10, 2021-04-16, 2021-05-19, 2021…
## $ fecha_de_muerte              <date> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ fecha_de_diagnostico         <dttm> 2021-06-26, 2021-04-20, 2021-06-04, 2021…
## $ fecha_recuperacion           <dttm> 2021-06-30, 2021-04-30, 2021-06-08, 2021…
## $ tipo_de_recuperacion         <chr> "Tiempo", "Tiempo", "Tiempo", "Tiempo", "…
## $ pertenencia_etnica           <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,…
## $ nombre_del_grupo_etnico      <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ fecha_nacimiento             <dbl> 1983, 1949, 2007, 1977, 2000, 2002, 1977,…
## $ retraso_notificacion         <dbl> 5, 3, 5, 12, 7, 4, 1, 4, 4, 1, 0, NA, 1, …
## $ tiempo_recuperacion          <dbl> 20, 14, 20, 19, 14, 14, 14, 14, 18, 213, …

Tras observar la estructura actual de la tabla de datos, se debe preguntar qué datos desea graficar.

4. Estética (Aesthetics)

En el contexto de la gramática de los gráficos, la estética (aesthetics) se refiere a cómo mapeamos los atributos de nuestros datos a propiedades visuales en el gráfico. Estas propiedades visuales pueden ser elementos tales como la posición en el eje X (x), la posición en el eje Y (y), el color, la forma, el tamaño, etc. Al mapear estos atributos podemos crear visualizaciones que nos permiten comprender y comunicar patrones y relaciones en los datos de manera efectiva.

En ggplot2 la función principal para especificar la estética es aes(). Aquí hay algunos ejemplos para ilustrar cómo usar la estética en ggplot2:

Ejemplo 1: Gráfico de dispersión (Scatter plot)

Supongamos que tenemos una tabla de que cuenta con las variables x e y. Queremos crear un gráfico de dispersión donde la variable x se mapea en el eje X y la variable y en el eje Y. Además, queremos que los puntos se coloreen según la variable grupo. Mediante la función aes() de ggplot2 es posible asignar estas variables a los correspondientes atributos visuales del gráfico, como veremos en el ejemplo a continuación.

Consideremos la base covid19 que cargamos anteriormente. Imagine que requiere un gráfico de dispersión que muestre la incidencia de casos por fecha de reporte desagregados por sexo. Primero organizamos los datos para lograr una tabla resumen con la información que queremos graficar:

covid19_resumen <- covid19 %>%
  group_by(fecha_reporte_web, sexo) %>%
  summarise(casos = n())

Luego, podemos usar la estética de los gráficos de ggplot2 de la siguiente manera:

ggplot(
  data = covid19_resumen,
  aes(x = fecha_reporte_web, y = casos, color = sexo)
  ) +
  geom_point()

5. Geometría (Geometry):

La geometría representa la forma en que los datos se visualizan en el gráfico; como puntos, líneas, barras, áreas, etc. Cada tipo de gráfico tiene su función correspondiente en ggplot2, como geom_point() para un gráfico de dispersión o geom_bar() para un gráfico de barras.

En la siguiente tabla se muestran algunos ejemplos de los distintos tipos de gráficos soportados por ggplot2 con su correspondiente comando:

Tipo de gráfica Geometría en ggplo2
Gráfica de barras geom_bar()
Gráfico de columnas geom_col()
Histograma geom_hist()
Gráfico de dispersión geom_point()
Gráfico de dispersión con jitter geom_jitter()
Gráfico de líneas geom_line()
Gráfico de cajas y bigotes geom_boxplot()
Gráfico de densidad geom_density()
Gráfico de violín geom_violin()
Mapa de calor geom_heatmap()
Creación de mapas geom_sf()
Línea de regresión geom_smooth()
Gráfico de punto geom_point()

Ejemplo 2: Gráfico de líneas

Supongamos que queremos visualizar la evolución del número de casos de covid-19 a lo largo del tiempo. Para esto, primero debemos preparar la tabla que irá en el gráfico:

covid19_fecha <- covid19 %>%
  group_by(fecha_reporte_web) %>%
  summarise(casos = n())

Una vez la tabla esté lista, procedemos a usar la geometría de ggplot2:

ggplot(
  data = covid19_fecha, 
  aes(x = fecha_reporte_web, y = casos)
  ) +
  geom_line()

Ejemplo 3: Gráfico de barras

Ahora, hagamos una visualización en forma de gráfico de barras del total de casos positivos por sexo:

ggplot(data = covid19) +
  geom_bar(aes(x = sexo))

En el ejemplo 3, se puede observar que ggplot2 automáticamente calcula el eje Y.

Ejemplo 4. Gráfico de barras más complejo

Primero vamos a preparar los datos en una tabla de datos que permita contar el número de casos por departamentos:

covid19_depto <- covid19 %>%
  group_by(nombre_departamento) %>%
  summarise(casos = n())

Ahora, por medio de la geometría de ggplot, hacemos la visualización usando el argumento stat = "identity" que calcula la suma de la variable y = casos agrupando por la variable x = nombre_departamento:

ggplot(data = covid19_depto, aes(x = nombre_departamento, y = casos)) +
  geom_bar(stat = "identity")

Se puede notar que no es posible ver bien los nombres de los departamentos. Para solucionar este problema, una alternativa es dar la vuelta a los ejes, usando al final el comando coord_flip

ggplot(data = covid19_depto, aes(x = nombre_departamento, y = casos)) +
  geom_bar(stat = "identity") +
  coord_flip()

Si adicionalmente queremos ordenar los departamentos por el número de casos, podemos utilizar el comando reorderen el eje donde está el departamento. La función reorder tiene dos argumentos: el primero es la variable a ordenar y el segundo es la variable que otorga el orden. En este caso sería reorder(nombre_departamento, -casos)si queremos ordenar de menor a mayor.

ggplot(
  covid19_depto,
  aes(x = reorder(nombre_departamento, -casos), y = casos)
) +
  geom_bar(stat = "identity") +
  coord_flip()

Pregunta ¿cómo produciría el mismo gráfico pero en orden descendente?

6. Escala (Scale)

En la gramática de los gráficos, la escala se refiere a cómo se mapean los valores de los datos a los valores visuales en el gráfico; es decir, cómo se representan los datos en la visualización. La elección adecuada de las escalas es esencial para que los gráficos sean interpretables y precisos.

A continuación, veremos algunos ejemplos de cómo usar la escala en ggplot2 con el data.frame covid19.

Ejemplo 5. Gráfico de mapa de calor con escala logarítmica scale_y_log10()

Usamos exáctamente el mismo ejemplo anterior, pero en este caso al final agregamos la escala logarítmica scale_y_log10()

ggplot(covid19_depto, aes(x = reorder(nombre_departamento, -casos), y = casos)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_y_log10(name = "Casos Confirmados (escala log)")

Por favor describa, ¿qué pasó en el ejercicio 5? ¿cuál es la diferencia con el ejercicio 4?

7. Facetas (Facets)

Las Facetas (Facets) en la gramática de los gráficos son una forma de dividir los datos en subconjuntos y representarlos en múltiples paneles dentro del mismo gráfico. Esto nos permite visualizar diferentes aspectos de los datos o comparar grupos de manera más efectiva. En ggplot2, podemos usar la función facet_wrap() o facet_grid() para implementar las facetas.

Ejemplo 5. Gráfico con facet wrap

Usando los datos de covid-19, vamos a representar la variable tiempo_recuperación en dos páneles por sexo usando facet_wrap.

ggplot(data = covid19, aes(x = edad, y = tiempo_recuperacion)) +
  geom_point() +
  facet_wrap(~sexo)

De acuerdo a lo aprendido anteriormente, intentemos que cada faceta quede de un color diferente, es decir, asignando color a la varible sexo. ¿cómo cambiaría el código? El gráfico que debe producir es el siguiente:

8. Tema (Theme)

En la gramática de los gráficos, el tema se refieren a la personalización de la apariencia visual general del gráfico, como los títulos, etiquetas de ejes, fondos, colores, tamaños de fuente, entre otros elementos. Con los temas, podemos mejorar la legibilidad y estética de los gráficos, asegurando que la información se comunique de manera efectiva y atractiva.

En ggplot2, podemos aplicar un tema predeterminado utilizando la función theme_gray(), pero también podemos personalizar cada aspecto visual mediante la función theme(). A continuación, proporcionamos algunos ejemplos de cómo utilizar los temas en ggplot2 con la base de datos covid19.

Usando la misma gráfica anterior, comparemos dos temas: theme_classic() y theme_dark(). Describa en sus propias palabras las diferencias

Ejemplo 6. Usando theme classic

ggplot(data = covid19, aes(x = edad, y = tiempo_recuperacion)) +
  geom_point() +
  facet_wrap(~sexo) +
  theme_classic()

Ejemplo 7. Usando theme classic

ggplot(data = covid19, aes(x = edad, y = tiempo_recuperacion)) +
  geom_point() +
  facet_wrap(~sexo) +
  theme_dark()

Para revisar la lista de theme() que tiene disponible ggplot2, puede consultarse en https://ggplot2.tidyverse.org/reference/ggtheme.html

Finalmente, veamos un ejemplo de como modificar los themes manualmente.

Ejemplo 8. Cambiando títulos, subtítulos y ejes

Podemos usar comandos como xlab, ylab para cambiar los nombres de los ejes. Igualmente, comandos como title y subtitle.

ggplot(data = covid19, aes(x = edad, y = tiempo_recuperacion, colour = sexo)) +
  geom_point() +
  facet_wrap(~sexo) +
  labs(
    y = "Tiempo de recuperación en días", x = "Edad en años",
    colour = "Sexo",
    title = "Distribución del tiempo de recuperación de COVID-19 en Colombia"
  )

9. Reto

Usando la base de datos covid19 con la que hemos trabajado, intentemos recrear el siguiente gráfico en ggplot:

Hemos llegado al final de la práctica ggplot2. ¡Muchas gracias por su participación!

Sobre este documento

Contribuciones: Zulma M. Cucunubá: primera versión