Animar distintos ordenamientos para un gráfico de tarta con gganimate
Seguimos jugando con gganimate. Aunque creo que nunca usaré este tipo de animación en un proyecto serio, creo que resulta un ejercicio interesante para comprender las tripas de ggplot2 y de gganimate.
Los datos que vamos a usar y la lógica básica para crear el gráfico que servirá de base (varios subconjuntos o pseudocapas de marcas gráficas apiladas) son los mismos que ya tratamos en un post anterior: “Animar distintos ordenamientos para un gráfico de barras con gganimate”.
Preparar los datos
En el post anterior utilizamos geom_col()
para crear el gráfico, pero tras varias pruebas infructuosas, en esta ocasión usaremos geom_rect()
para generar cada uno de los “quesitos” o porciones de tarta; bueno, realmente crearemos rectángulos, y coord_polar()
se encargará de adecuarlos para el gráfico de tarta.
Para poder usar geom_rect()
tenemos que proveer los datos que permitirán posicionar los cuatro vértices del rectángulo:
xmin
yxmax
: la forma de crear gráficos de tarta conggplot2
es un tanto peculiar: hay que crear un gráfico de barras apiladas (con una única columna), y luego aplicarcoord_polar()
, por lo que el posicionamiento en el ejex
es constante para todos las marcas gráficas. Usaremos los valores0.5
y1.5
ymin
eymax
: tal y como hicimos cuando creamos la animación de un gráfico de barras apiladas, vamos a calcular el valor deymax
como la suma acumulada de los valores (las alturas de cada rectángulo) eymin
será la altura acumulada de un rectángulo menos la altura de ese mismo rectángulo.
Además, vamos a añadir una etiqueta correspondiente a cada rectángulo, para lo que necesitamos calcular la posición en el eje y
; las etiquetas estarán posicionadas a media altura de cada rectángulo
datos1 <- mpg %>%
group_by(drv, class) %>%
mutate(class_drv = paste0(class, " - ", drv)) %>%
summarise(count = n(),
class_drv = unique(class_drv)) %>%
ungroup() %>%
arrange(class_drv) %>%
mutate(orden = row_number(),
ymax = cumsum(count),
ymin = ymax - count,
angulo = ymin + (count/2))
datos2 <- datos1 %>%
arrange(count) %>%
mutate(orden = row_number(),
ymax = cumsum(count),
ymin = ymax - count,
angulo = ymin + (count/2))
datos3 <- datos1 %>%
arrange(drv, count) %>%
mutate(orden = row_number(),
ymax = cumsum(count),
ymin = ymax - count,
angulo = ymin + (count/2))
datos <- datos1 %>%
bind_rows(datos2, datos3, .id = "estado") %>%
mutate(estado = case_when(
estado == 1 ~ "Alfabético",
estado == 2 ~ "Total",
TRUE ~ "drv"
))
Gráfico base
Vamos a montar el gráfico base como lo haríamos para crear un gráfico de tarta con ggplot2, con la direfencia de que en lugar de usar geom_bar()
o geom_col()
, usaremos geom_rect()
.
Además, añadimos un ángulo de inclinación a geom_label()
. El cálculo que debemos realizar variará dependiendo del efecto que queramos conseguir: en este ejemplo, queremos que la línea base de las etiquetas sea tangencial al punto central del arco de cada segmento (y como se puede ver, no lo he conseguido del todo).
(
tarta <- ggplot(datos, aes(x = 1)) +
geom_rect(aes(
xmin = 0.5,
xmax = 1.5,
ymin = ymin,
ymax = ymax,
fill = drv
), color = "black") +
geom_text(aes(
label = orden,
x = 1.6,
y = angulo,
angle = -ymax ^ 1.075
)) +
coord_polar(theta = "y") +
theme_void()
)
Animación
La animación es idéntica a la que ya usamos para animar la versión con barras:
anim <- tarta +
labs(title = "Orden: {closest_state}") +
transition_states(estado, transition_length = 1, state_length = 3)
animate(anim, nframes = 100)