Con ggplot2 puedes crear gráficos de paneles, también llamados gráficos de Trellis o facetas con las funciones facet_grid
o facet_wrap
. Estas funciones son muy similares, pero existen algunas diferencias entre ellas, ya que la primera crea una matriz de paneles en base a dos variables discretas (también funciona para una, pero no se recomienda) mientras que la segunda crea un conjunto de paneles en base a una única variable categórica (también funciona con dos, pero no se recomienda).
facet_wrap
Considera, por ejemplo, que tienes un conjunto de observaciones que pertenecen a grupos diferentes. En este escenario, puedes mostrar todos los datos en el mismo gráfico y resaltar los grupos con un color o marcador diferente.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Gráfico de dispersión por grupo
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point()
El problema es que en ocasiones el gráfico no es legible, por lo que una alternativa sería dividir los datos en diferentes gráficos para ver cada grupo de manera individual. Para ello puedes hacer uso de la función facet_wrap
pasando el nombre de la variable que define los grupos como una fórmula, esto es: ~grupo
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo)
Cambia el orden de los paneles ordenando los niveles de la variable categórica con factor
.
Número de filas y columnas
El número por defecto de filas y columnas dependerá de tus datos. Si tu variable categórica tiene cuatro grupos como es el caso, la función facet_wrap
creará dos columnas y dos filas, pero en este ejemplo quizás sea mas interesante tener una fila, ya que hace el gráfico más legible. Para ello puedes establecer nrow = 1
o ncol = 4
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos (2 columnas)
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo, nrow = 1) # O ncol = 4
Si en lugar de facet_wrap
usásemos facet_grid
se crearían los mismos paneles, pero siempre habría una sola fila o una sola columna, por eso no se recomienda su uso y es mejor usar facet_wrap
y poder tener la libertad de poder elegir el número de filas o columnas.
Escalas de los ejes
Por defecto, todos los paneles tendrán la misma escala de los ejes, pero si los datos presentan distinta escala para cada grupo puedes hacer que cada panel tenga su propia escala estableciendo scales = "free"
, de modo que cada gráfico tendrá rangos diferentes. Liberar las escalas hace más sencillo leer patrones en cada panel, mientras que dejarlas fijas hace más sencillo ver patrones entre los paneles. Ten en cuenta que también puedes dejar libre un único eje con scales = "free_x"
o scales = "free_y"
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo, scales = "free")
Dirección de los paneles
La dirección por defecto de los paneles es horizontal (dir = "h"
) pero también puedes establecerla como vertical con dir = "v"
. Observa que al cambiarlo, el panel superior de la derecha ahora corresponde al tercer grupo en lugar de al segundo.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Vertical ribbon of plots
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo, dir = "v")
Posición de las etiquetas
La función facet_wrap
proporciona un argumento llamado strip.position
que permite personalizar la posición de las etiquetas o cintas. El valor por defecto es "top"
(arriba), pero también podría ser "bottom"
(abajo), "left"
(izquierda) o "right"
(derecha).
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo, strip.position = "bottom")
Resaltar cada grupo mostrando todos los datos en los paneles
Es posible agregar todos los datos a todos los paneles y resaltar los datos correspondientes para cada uno de ellos. Para ello tendrás que crear una nueva capa pasando como entrada el mismo data frame pero eliminando la variable categórica (en este ejemplo se llama grupo
).
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(data = transform(df, grupo = NULL), colour = "grey85") +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo, strip.position = "bottom")
facet_grid
La función facet_grid
es muy similar a facet_wrap
, pero esta función crea paneles mostrando todas las combinaciones de datos para dos variables categóricas. Existen dos formas de introducir datos: la función puede tomar una fórmula como entrada con los nombres de las variables categóricas o puedes pasar los nombres de las variables a los argumentos rows
(para las filas) y cols
(para las columnas) haciendo uso de la función vars
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo1 <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
grupo2 <- ifelse(y < 0.5, "A", "B")
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo1 = grupo1, grupo2 = grupo2)
# Matriz de gráficos
ggplot(df, aes(x = x, y = y, color = grupo1)) +
geom_point(show.legend = FALSE) +
facet_grid(grupo1 ~ grupo2) # O facet_grid(rows = vars(grupo1), cols = vars(grupo2))
Escala de los ejes
La función facet_grid
también proporciona el argumento scales
que da libertad a los ejes para variar a través de las filas y/o columnas.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo1 <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
grupo2 <- ifelse(y < 0.5, "A", "B")
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo1 = grupo1, grupo2 = grupo2)
# Matriz de gráficos
ggplot(df, aes(x = x, y = y, color = grupo1)) +
geom_point(show.legend = FALSE) +
facet_grid(grupo1 ~ grupo2, scales = "free")
Tamaño de los paneles
Si la escala de los paneles varía, puedes utilizar el argumento space
para hacer que los paneles tengan tamaños diferentes. Los posibles valores son "fixed"
(por defecto), "free_y"
para liberar las alturas, "free_x"
, para liberar el ancho y "free"
para dejar que tanto la altura como el ancho varíen. Ten en cuenta que en este ejemplo este argumento no provoca ningún efecto ya que todos los paneles tienen la misma escala.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo1 <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
grupo2 <- ifelse(y < 0.5, "A", "B")
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo1 = grupo1, grupo2 = grupo2)
# Matriz de gráficos
ggplot(df, aes(x = x, y = y, color = grupo1)) +
geom_point(show.legend = FALSE) +
facet_grid(grupo1 ~ grupo2, space = "free_x")
La función facet_grid
proporciona más argumentos, como shrink
, labeller
, as.table
, switch
, drop
y margins
. Recuerda leer la documentación original para obtener detalles adicionales en caso de ser necesario.
Usando los argumentos de la función theme
puedes personalizar los textos y los paneles. En los siguientes ejemplos destacamos algunos casos de uso habituales.
Personalización de las etiquetas de facet_wrap
Puedes personalizar el estilo de texto de las etiquetas con el argumento strip_text
. Este argumento toma la función element_text
como entrada, donde puedes especificar los diferentes estilos, como el color, tamaño, ajuste horizontal, etc. Si quieres eliminar las etiquetas utiliza element_blank
.
Para personalizar el color de fondo tan solo tienes que pasar la función element_rect
a strip.background
y en ella establecer el color de fondo con fill
. Si quieres agregar un borde a la cinta tendrás que establecer un tipo de línea, un color y un grosor con los argumentos correspondientes.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo) +
theme(strip.text = element_text(face = "bold", color = "white", hjust = 0, size = 15),
strip.background = element_rect(fill = "dodgerblue3", linetype = "solid",
color = "black", linewidth = 1))
Personalización de las etiquetas de facet_grid
Si creaste un gráfico de paneles con facet_grid
puedes personalizar las cintas de la misma manera que en el ejemplo anterior, pero también puedes personalizarlas de manera individual para cada eje haciendo uso de strip.text.x
, strip.text.y
, strip.background.x
y strip.background.y
.
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo1 <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
grupo2 <- ifelse(y < 0.5, "A", "B")
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo1 = grupo1, grupo2 = grupo2)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y,)) +
geom_point(show.legend = FALSE) +
facet_grid(grupo1 ~ grupo2) +
theme(strip.text.x = element_text(face = "bold", color = "white", hjust = 1, size = 15),
strip.text.y = element_text(face = "bold", color = "white", hjust = 0, size = 15),
strip.background.x = element_rect(fill = "dodgerblue3", linetype = "solid",
color = "black", linewidth = 1),
strip.background.y = element_rect(fill = "firebrick2", linetype = "solid",
color = "gray30", linewidth = 1))
Eliminar el color de fondo de las etiquetas
Ten en cuenta que es posible eliminar el color de fondo de las etiquetas pasando la función element_blank
a strip.background
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo) +
theme(strip.text = element_text(size = 15),
strip.background = element_blank())
Aumentar o reducir el espacio entre paneles
Por defecto hay un pequeño espacio entre paneles. Puedes incrementar o reducir dicho espacio pasando una unidad (función unit
) al argumento panel.spacing
de la función theme
.
# install.packages("ggplot2")
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo) +
theme(panel.spacing = unit(0, 'points'))
Agregar un borde a los paneles
Recuerda que también puedes personalizar otros parámetros de los gráficos, como por ejemplo agregar un borde a los paneles. Puedes logarlo con panel.border
, siguiendo el ejemplo mostrado a continuación.
library(ggplot2)
# Simulación de datos
set.seed(4)
x <- runif(500)
y <- 4 * x ^ 2 + rnorm(length(x), sd = 5)
grupo <- ifelse(x < 0.4, "G1", ifelse(x < 0.6, "G2", ifelse(x < 0.8, "G3", "G4")))
x <- x + runif(length(x), -0.5, 0.5)
# Data frame
df <- data.frame(x = x, y = y, grupo = grupo)
# Paneles de gráficos
ggplot(df, aes(x = x, y = y, color = grupo)) +
geom_point(show.legend = FALSE) +
facet_wrap(~grupo) +
theme(panel.border = element_rect(fill = "transparent", # Necesario para agregar el borde
color = "black", linewidth = 1.5))
También te puede interesar