En esta última parte, vamos a revisar como grÔficar varias figuras generadas con ggplot en el mismo panel.

Existen diversos paquetes con los que es posible hacer esta tarea. Entre ellos tenemos

  • COWPLOT
  • gridExtra
  • ggpubr

Estas las puedes revisar en la pagina de STHD

Para fines de este curso, revisaremos a detalle el paquete patchworkel cual tiene una de las formas mas sencillas y directas para generar un panel con distintos grƔficos.

patchwork

Este paquete fue desarrollado por Thomas Lin Pederson y se puede obtener directamente desde los repositorios (CRAN) o desde la pagina de github con el siguiente comando

library(devtools)
install_github("thomasp85/patchwork")

Para este ejercico, nuevamente usaremos nuestra base de datos de msleep:

library(tidyverse)
## -- Attaching packages ---------------------------------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.0     v purrr   0.3.4
## v tibble  3.0.1     v dplyr   0.8.5
## v tidyr   1.0.2     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.5.0
## -- Conflicts ------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(readxl)
library(patchwork)
msleep <- read_excel("data/msleep_database_excel.xls", sheet = "msleep", na = "NA")

glimpse(msleep)
## Rows: 83
## Columns: 11
## $ name         <chr> "Cheetah", "Owl monkey", "Mountain beaver", "Greater s...
## $ genus        <chr> "Acinonyx", "Aotus", "Aplodontia", "Blarina", "Bos", "...
## $ vore         <chr> "carni", "omni", "herbi", "omni", "herbi", "herbi", "c...
## $ order        <chr> "Carnivora", "Primates", "Rodentia", "Soricomorpha", "...
## $ conservation <chr> "lc", NA, "nt", "lc", "domesticated", NA, "vu", NA, "d...
## $ sleep_total  <dbl> 12.1, 17.0, 14.4, 14.9, 4.0, 14.4, 8.7, 7.0, 10.1, 3.0...
## $ sleep_rem    <dbl> NA, 1.8, 2.4, 2.3, 0.7, 2.2, 1.4, NA, 2.9, NA, 0.6, 0....
## $ sleep_cycle  <dbl> NA, NA, NA, 0.1333333, 0.6666667, 0.7666667, 0.3833333...
## $ awake        <dbl> 11.9, 7.0, 9.6, 9.1, 20.0, 9.6, 15.3, 17.0, 13.9, 21.0...
## $ brainwt      <dbl> NA, 0.01550, NA, 0.00029, 0.42300, NA, NA, NA, 0.07000...
## $ bodywt       <dbl> 50.000, 0.480, 1.350, 0.019, 600.000, 3.850, 20.490, 0...

Ahora vamos a generar distintas graficas para describir los datos

1: barplot con la frecuencia relativa de status de conservacion para cada orden, al que llamaremos p1:

p1 <- ggplot(data = msleep, aes(x = order, fill = conservation))+
  geom_bar(position = "fill")+
  theme(axis.text.x=element_text(angle=45, hjust=1))

p1

2: Relación entre las horas totales de sueño con las horas de sueño profundo (rem). Ademas, añade un ajuste con geom_smooth(se =TRUE). A este objeto le llamaremos p2

p2 <- ggplot(msleep, aes(x = sleep_total, y = sleep_rem)) +
  geom_point()+
  geom_smooth(se =TRUE)
p2
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 22 rows containing non-finite values (stat_smooth).
## Warning: Removed 22 rows containing missing values (geom_point).

3: relacion entre la proporcion brainwt / bodywt con las horas de sueƱo total al que llamaremos p3

p3 <- msleep %>%
  mutate(ratiowt = brainwt / bodywt) %>%
  ggplot(., aes(x = ratiowt, y = sleep_total)) + 
  geom_point()+
  geom_smooth(se=TRUE)
p3
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 27 rows containing non-finite values (stat_smooth).
## Warning: Removed 27 rows containing missing values (geom_point).

4: Finalmente, una grƔfica con la proporcion de horas rem en relacion a las horas totales de sueƱo solamente de los ordenes Carnivora y Rodentia. A esta le llamaremos p4

order_sub <- msleep %>%
  filter(order %in% c("Carnivora", "Rodentia")) %>%
  mutate(perc.rem = sleep_rem/sleep_total)
p4 <- ggplot(order_sub, aes(x = sleep_total, y = perc.rem, col = order, fill = order))+
  geom_point()+
  geom_smooth()
p4
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 14 rows containing non-finite values (stat_smooth).
## Warning: Removed 14 rows containing missing values (geom_point).

patchwork

colocar dos graficas horizontalmente

p1 + p2
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

colocar tres grƔficas verticalmente

p2 + p3 + p4 + plot_layout(ncol = 1)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

operadores \ y | para diseƱos intuitivos

(p2 | p3) / p1
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 22 rows containing non-finite values (stat_smooth).
## Warning: Removed 22 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 27 rows containing non-finite values (stat_smooth).
## Warning: Removed 27 rows containing missing values (geom_point).

Ademas, es posible modificar cada elemento de la grƔfica para ajustarlos

(p2 + p3) / p1 + theme(legend.position = "bottom")
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 22 rows containing non-finite values (stat_smooth).
## Warning: Removed 22 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 27 rows containing non-finite values (stat_smooth).
## Warning: Removed 27 rows containing missing values (geom_point).

(p1 + theme(legend.position = "none") | p2)/(p3 | p4)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 22 rows containing non-finite values (stat_smooth).
## Warning: Removed 22 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 27 rows containing non-finite values (stat_smooth).
## Warning: Removed 27 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 14 rows containing non-finite values (stat_smooth).
## Warning: Removed 14 rows containing missing values (geom_point).

(p2 / p3 / p4) | p1
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 22 rows containing non-finite values (stat_smooth).
## Warning: Removed 22 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 27 rows containing non-finite values (stat_smooth).
## Warning: Removed 27 rows containing missing values (geom_point).
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 14 rows containing non-finite values (stat_smooth).
## Warning: Removed 14 rows containing missing values (geom_point).

Ahora probemos con nuestra base de tabla colecta estaciones

mediciones <- read_csv("data/Tabla_Colecta_estaciones.csv")
## Parsed with column specification:
## cols(
##   Individuo = col_double(),
##   Sitio = col_character(),
##   Estacion = col_character(),
##   Sexo = col_character(),
##   Profundidad = col_character(),
##   Longitud_total = col_double(),
##   Longitud_parcial = col_double(),
##   anchura = col_double()
## )

1: Generemos una tabla de disperción con los datos de longitud parcial contra anchura, indicando cada sitio de colecta con un color y forma diferente

m1 <- ggplot(mediciones, aes(x = Longitud_parcial, y = anchura, col = Sitio))+
  geom_point()

m1 

2: Generemos un boxplot con la dispercion de los de los datos de longitud parcial por sitio de colecta

m2 <- ggplot(mediciones, aes(x = Profundidad, y = Longitud_parcial, col = Sitio))+
  geom_boxplot()
m2

3: graficos de densidad de los datos de longitud parcial por sitio identificado con colores diferentes

m3 <- ggplot(mediciones, aes(x = Longitud_parcial, col = Sitio))+
  geom_density()
m3

Utilizando patchworks, une las tres graficas, m1 y m2 en la parte superior y m3 en la parte inferior

(m1 | m2) / m3

Para poder ajustar parametros al conjunto de graficas y no a una sola grafica individual, se usa el operador &. En este caso, vamos a colocar todas las leyendas en la parte inferior

(m1 | m2) / m3 & theme(legend.position = "bottom")

cuando se tienen varios graficos que tengan una leyenda en comun, se puede utilizar el la funcion combined + plot_layout(guides = "collect").

por ejemplo

n1 <- ggplot(mediciones, aes(x = anchura, y = Longitud_parcial, col = Sitio))+
  geom_point()
n1
n_c <- n1 + m1
n_c <- n_c + plot_layout(guides = "collect") 
n_c & theme(legend.position = "bottom")

Ahora crea un objetvo llamado patch donde m1 y m2 no tengan legenda, mientras que m3 tenga la leyenda en la parte inferior

patch <- ((m1 | m2) & theme(legend.position = "none")) / m3 + theme(legend.position = "bottom")
patch

Anotaciones utilizando plot_annotation(tag_levels )

patch <- ((m1 | m2) & theme(legend.position = "none")) / m3 + theme(legend.position = "bottom")

patch + plot_annotation(tag_levels = 'A',title = 'Mediciones de organismos de muestreo',
  subtitle = 'Los datos se muestran por sitio de colecta',
  caption = 'Estas graficas fueron generadas con ggplot2 y patchwork')

Puedes encontrar información mas detallada sobre como agregar anotaciones en patchwork aqui