Fecha de publicación

12 de noviembre de 2023

Objetivos del manual

  • Comprender la lógica detras de la estructura los gráficos con ggplot2

  • Ser capaz de intregrar en un gŕafico diferentes fuentes de información que representen la complejidad de los datos

 

 

ggplot2

  • Un paquete de R diseñado específicamente para producir gráficos

  • A diferencia de otros paquetes, ggplot2 tiene su propia gramática

  • La gramática se basa en la “Gramática de los gráficos” (Wilkinson 2005)

  • Módulos independientes que pueden combinarse de muchas formas

  • Esta gramática proporciona una gran flexibilidad

 

0.1 Gramática de gráficos

La idea principal es empezar con una capa base de datos brutos y luego añadir más capas de anotaciones y resúmenes estadísticos. El paquete nos permite producir gráficos utilizando la misma estructura de pensamiento que utilizamos al diseñar un análisis, reduciendo la distancia de cómo visualizamos un gráfico en la cabeza y el producto final.

Aprender la gramática no sólo es útil para producir un gráfico de interés, sino también para pensar en otros gráficos más complejos. La ventaja de esta gramática es la posibilidad de crear nuevos gráficos compuestos por nuevas combinaciones de elementos.

 

0.2 Componentes del gráfico

Todos los gráficos ggplot2 contienen los siguientes componentes:

  • Datos - El objeto R con la información que necesita ser trazada
  • Capas - Los datos específicos que serán graficados (ej. ‘x’ & ‘y’)
  • Escala - Rango de datos a incluir
  • Coordenadas - Sistema de coordenadas (no se utiliza muy a menudo)
  • Parcelas (facets) - Determina cómo dividir los datos en subparcelas en un multipanel
  • Tema - Controla el estilo del gráfico

 

Estos componentes se juntan utilizando “+”.

La sintaxis más habitual incluye los datos dentro de la llamada “ggplot” y una capa “geom_”.

 

Primero instala/carga el paquete:

Código
# install
install.packages("ggplot2")

# load library
library(ggplot2)

 

0.3 Gráficos de dispersión

Utilicemos el conjunto de datos “iris” para crear gráficos de dispersión:

Código
ggplot(data = iris, mapping = aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point()

 

This plot is defined by 3 components: 1. “data”- iris 1. “aes” - Sepal.length vs Petal.length 1. “layer” - Points (geom)

 

0.4 Atributos estéticos

También podemos añadir otros atributos estéticos como el color, la forma y el tamaño. Estos atributos se pueden incluir dentro de aes():

Código
# color by species
ggplot(
  data = iris,
  mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species)
) +
  geom_point()

Código
# color and shape by species
ggplot(
  data = iris,
  mapping = aes(
    x = Sepal.Length,
    y = Petal.Length,
    color = Species,
    shape = Species
  )
) +
  geom_point()

 

Tenga en cuenta que los argumentos estéticos también pueden incluirse en la capa “geom”:

Código
ggplot(
  data = iris,
  mapping = aes(x = Sepal.Length, y = Petal.Length)
) +
  geom_point(aes(color = Species, shape = Species))

 

También podemos incluir un valor fijo:

Código
ggplot(
  data = iris,
  mapping = aes(x = Sepal.Length, y = Petal.Length)
) +
  geom_point(color = "red2")

 

Algunos atributos funcionan mejor con algunos tipos de datos:

  • Color y forma: variables categóricas
  • Tamaño: variables continuas

 


Ejercicio 1

Utilizando el conjunto de datos “hylaeformis”:

Código
# lear desde el sitio del curso
hylaeformis_data <- read.csv(
  paste0("https://raw.githubusercontent.com/maRce10/", "r_avanzado_2023/master/data/hylaeformis_data.csv")
)

# or bajar manualmente y leer copia local
hylaeformis_data <- read.csv("hylaeformis_data.csv", stringsAsFactors = FALSE)

head(hylaeformis_data, 20)


1.1 Create a scatter plot of vs “meanfreq” (mean frequency)

1.1 Crear un gráfico de dispersión de duración (“duration”) vs frecuencia promedio (“meanfreq”)


1.2 Añadir un atributo estético para mostrar un color diferente para cada localidad


1.3 Añade otro atributo estético para mostrar el rango de frecuencia dominante (“dfrange”) como tamaño los símbolos


 

0.5 Gráficos multipanel (Facetting)

  • Otra forma de visualizar variables categóricas
  • Permite crear gráficos multipanel para cada nivel de la variable
  • 2 tipos: “grid” & “wrap”
Código
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  facet_wrap(~Species)

Código
# o

ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  facet_grid(~Species)

 

La escala puede ser fija o libre para los ejes x e y, y puede modificarse el número de columnas y filas:

Código
# free x
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  facet_wrap(~Species, scales = "free_x")

Código
# free x and 3 rows
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  facet_wrap(~Species, scales = "free_y", nrow = 3)

Código
# both free and 2 rows
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  facet_wrap(~Species, scales = "free", nrow = 2)

 

Tenga en cuenta que también podemos guardar el componente básico como un objeto R y añadir otros componentes más adelante en el código:

Código
p <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point()

p + facet_wrap(~Species, scales = "free_x", nrow = 3)

0.6 “geoms” adicionales

  • geom_smooth() - añade las líneas de mejor ajuste (incluyendo CI)
  • geom_boxplot() - Distribución de frecuencias
  • geom_histogram() & geom_freqpoly() - distribuciones de frecuencia
  • geom_bar() - distribución de frecuencias de variables categóricas
  • geom_path() & geom_line() - añade líneas a los gráficos de dispersión

 

0.6.1 geom_smooth()

Las líneas de regresión de mejor ajuste pueden añadirse con geom_smooth():

Código
# con CI
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  geom_smooth(method = "lm") +
  facet_wrap(~Species, scales = "free", nrow = 3)

Código
# sin CI
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  facet_wrap(~Species, scales = "free", nrow = 3)

 

Ejercicio 2

Utilizando el conjunto de datos de ejemplo “msleep”:


2.1 Crear un gráfico de dispersión de peso corporal (“bodywt”) frente a peso cerebral (“brainwt”)


2.2 Añadir orden (“order”) como estética del color


2.3 Añadir un componente “faceta” para dividir los gráficos por orden utilizando escalas libres


2.4 Elimine los órdenes con menos de 4 especies en el conjunto de datos y haga un gráfico similar al 2.3


2.5 Añadir una línea de mejor ajuste a cada gráfico del panel


0.6.2 Boxplots

De nuevo, sólo se necesita un nuevo componente “geom” para crear un boxplot:

Código
ggplot(iris, aes(Species, Petal.Length)) +
  geom_boxplot()

Una alternativa interesante son los gráficos de violines:

Código
ggplot(iris, aes(Species, Petal.Length)) +
  geom_violin()

 

0.6.3 Histogramas

Lo mismo ocurre con los histrogramas y los gráficos de frecuencias:

Código
ggplot(iris, aes(Petal.Length)) +
  geom_histogram()

Código
ggplot(iris, aes(Petal.Length)) +
  geom_freqpoly()

Código
ggplot(iris, aes(Petal.Length)) +
  geom_histogram() +
  geom_freqpoly()

 

Podemos controlar la anchura de las barras:

Código
ggplot(iris, aes(Petal.Length)) +
  geom_histogram(binwidth = 1, fill = adjustcolor("red2", alpha.f = 0.3))
Warning: Duplicated aesthetics after name standardisation: fill

 

Y compara la distribución de los distintos grupos dentro del mismo histograma:

Código
ggplot(iris, aes(Petal.Length, fill = Species)) +
  geom_histogram(binwidth = 0.4)

 

0.6.4 Gráfico de barras

Muestran la distribución de variables discretas (categóricas):

Código
tab <- table(msleep$order)

df <-
  as.data.frame(table(msleep$order[msleep$order %in% names(tab)[tab > 3]]))

ggplot(df, aes(Var1, Freq)) +
  geom_bar(stat = "identity")

 

0.7 Personalización de ggplots

Además de las funciones básicas (por ejemplo, componentes) descritas anteriormente, ggplot tiene muchas otras herramientas (tanto argumentos como funciones adicionales) para personalizar aún más los gráficos. Prácticamente todo se puede modificar. Aquí vemos algunas de las herramientas más comunes.

 

0.7.1 Temas

ggplot2 viene con algunos temas por defecto que se pueden aplicar fácilmente para modificar el aspecto de nuestros gráficos:

Código
p <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point()

p + theme_classic()

Código
p + theme_bw()

Código
p + theme_minimal()

 

La mayoría de los temas difieren en el uso de cuadrículas, líneas de borde y patrones de etiquetado de ejes.

 

0.7.2 Personalización de ejes

Los límites de los ejes pueden modificarse como sigue:

Código
ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point() +
  xlim(c(0, 10))

Código
ggplot(iris, aes(Sepal.Length, Petal.Length, col = Species)) +
  geom_point() +
  xlim(c(0, 10)) +
  ylim(c(0, 9))

 

Los ejes también pueden transformarse:

Código
ggplot(iris, aes(Sepal.Length, Petal.Length, col = Species)) +
  geom_point() +
  scale_x_continuous(trans = "log") +
  scale_y_continuous(trans = "log2")

 

o invertidos:

Código
ggplot(iris, aes(Sepal.Length, Petal.Length, col = Species)) +
  geom_point() +
  scale_y_reverse()

0.7.3 Guardar ggplots

Los ggplots pueden exportarse como archivos de imagen utilizando la función ggsave:

Código
ggplot(
  data = msleep[msleep$order %in% names(tab)[tab > 5], ],
  mapping = aes(x = bodywt, y = brainwt)
) +
  geom_point() +
  facet_wrap(~order, scales = "free")
Warning: Removed 21 rows containing missing values (`geom_point()`).

Código
# Export
ggsave("plot.png", width = 5, height = 5)
Warning: Removed 21 rows containing missing values (`geom_point()`).

 

El tipo de archivo de imagen se identificará por la extensión en el nombre del archivo

 

Personalización adicional del eje:

Código
# Log2 scaling of the y axis (with visually-equal spacing)
require(scales)

p + scale_y_continuous(trans = log2_trans())

Código
# show exponents
p + scale_y_continuous(
  trans = log2_trans(),
  breaks = trans_breaks("log2", function(x) 2^x),
  labels = trans_format("log2", math_format(2^.x))
)

Código
# Percent
p + scale_y_continuous(labels = percent)

Código
# dollar
p + scale_y_continuous(labels = dollar)

Código
# scientific
p + scale_y_continuous(labels = scientific)

Código
### Agregar "tick marks" ###

# Cargar librerías
library(MASS)

data(Animals)

# x and y axis are transformed and formatted
p2 <- ggplot(Animals, aes(x = body, y = brain)) +
  geom_point(size = 4) +
  scale_x_log10(
    breaks = trans_breaks("log10", function(x) 10^x),
    labels = trans_format("log10", math_format(10^.x))
  ) +
  scale_y_log10(
    breaks = trans_breaks("log10", function(x) 10^x),
    labels = trans_format("log10", math_format(10^.x))
  ) +
  theme_bw()

# log-log plot without log tick marks
p2

Código
# Show log tick marks
p2 + annotation_logticks()

Código
# # Log ticks on left and right
p2 + annotation_logticks(sides = "lr")

Código
# All sides
p2 + annotation_logticks(sides = "trbl")

 

0.7.4 Otros gráficos

Se pueden generar muchos otros tipos de gráficos. Aquí muestro un ejemplo de gráficos de contorno y de “mapa de calor”:

Código
head(faithful)
eruptions waiting
3.600 79
1.800 54
3.333 74
2.283 62
4.533 85
2.883 55
Código
ggplot(faithfuld, aes(eruptions, waiting)) +
  geom_contour(aes(z = density, colour = after_stat(level)))

Código
ggplot(faithfuld, aes(eruptions, waiting)) +
  geom_raster(aes(fill = density))

 

0.8 Otros paquetes de gráficos en R

  • ggvis (ggplots interactivos)
  • vcd (Warnes 2015)
  • plotrix (Lemon et al. 2006)
  • gplots (Warnes 2015)

Consulte la CRAN Graphics Task View para obtener una lista más completa de herramientas gráficas en R.


 

0.9 References

  • Lemon J (2006) Plotrix: a package in the red light district of R. R-News 6(4):8–12
  • Warnes GR, Bolker B, Bonebakker L, Gentleman R, Liaw WHA, Lumley T, Maechler M, Magnusson A, Moeller S, Schwartz M, Venables B (2015) gplots: various R programming tools for plotting data. R package version 2.17.0. https://CRAN.R-project.org/package=gplots
  • Wickham H (2010) A layered grammar of graphics. J Comput Graph Stat 19(1):3–28
  • Wilkinson L (2005) The grammar of graphics. Statistics and computing, 2nd edn. Springer, New York


Información de la sesión

R version 4.1.2 (2021-11-01)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 22.04.2 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0

locale:
 [1] LC_CTYPE=es_CR.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=es_CR.UTF-8        LC_COLLATE=es_CR.UTF-8    
 [5] LC_MONETARY=es_CR.UTF-8    LC_MESSAGES=es_CR.UTF-8   
 [7] LC_PAPER=es_CR.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] scales_1.2.1       viridis_0.6.2      viridisLite_0.4.2  MASS_7.3-55       
[5] RColorBrewer_1.1-3 ggplot2_3.4.4      knitr_1.45         kableExtra_1.3.4  

loaded via a namespace (and not attached):
 [1] tidyselect_1.1.2  xfun_0.41         purrr_0.3.4       splines_4.1.2    
 [5] lattice_0.20-45   colorspace_2.1-0  vctrs_0.6.4       generics_0.1.2   
 [9] htmltools_0.5.7   yaml_2.3.7        mgcv_1.8-39       utf8_1.2.4       
[13] rlang_1.1.2       isoband_0.2.7     pillar_1.9.0      glue_1.6.2       
[17] withr_2.5.2       DBI_1.1.3         lifecycle_1.0.4   stringr_1.5.0    
[21] munsell_0.5.0     gtable_0.3.4      ragg_1.2.1        rvest_1.0.3      
[25] htmlwidgets_1.5.4 evaluate_0.23     labeling_0.4.3    fastmap_1.1.1    
[29] fansi_1.0.5       highr_0.10        webshot_0.5.5     jsonlite_1.8.7   
[33] farver_2.1.1      systemfonts_1.0.4 textshaping_0.3.6 gridExtra_2.3    
[37] digest_0.6.33     stringi_1.7.12    dplyr_1.0.8       grid_4.1.2       
[41] cli_3.6.1         tools_4.1.2       magrittr_2.0.3    tibble_3.2.1     
[45] pkgconfig_2.0.3   Matrix_1.4-0      xml2_1.3.3        assertthat_0.2.1 
[49] rmarkdown_2.25    svglite_2.1.0     httr_1.4.2        rstudioapi_0.13  
[53] R6_2.5.1          nlme_3.1-155      compiler_4.1.2