Cómo añadir animación a un gráfico de ggplot

Llegó el último día del Calendario de Adviento especial ggplot. Para hoy dejamos una de las características más especiales de una visualización: la animación.

Para ello, contamos con una librería extra llamada gganimate que amplía la base de ggplot con nuevas capas que definen la animación del gráfico. En resumen, estas son las capas que proporciona:

  • transition_*() define cómo deben distribuirse los datos y cómo se relacionan consigo mismos a través del tiempo

  • view_*() define cómo deben cambiar las escalas de posición a lo largo de la animación

  • shadow_*() define cómo los datos de otros puntos en el tiempo deben ser presentados en el punto de tiempo dado

  • enter_*()/exit_*() define cómo deben aparecer los nuevos datos y cómo deben desaparecer los antiguos durante el transcurso de la animación

  • ease_aes() define cómo se deben suavizar las diferentes estéticas durante las transiciones

Datos y gráfico base

En primer lugar, tomamos como base el gráfico de Netflix del útlimo post sobre edicación avanzada de texto en ggplot.

library(tidyverse)
library(lubridate)
library(ggrepel)

df <- read.csv('https://raw.githubusercontent.com/elartedeldato/datasets/main/netflix_titles.csv')
df %>% 
  filter(str_detect(description, 'high school'), type=='Movie') %>%
  mutate(duration:=as.numeric(str_remove(duration, ' min'))) %>%
  select(release_year, duration, title) -> df_title

df_title %>%
  mutate(top_duration:=rank(desc(duration))) -> df_title
  
ggplot(df_title) + 
  geom_point(aes(x=1, y=duration), color='red') + 
  theme_bw() +
  theme(legend.position= 'none',
        axis.title.y = element_text(family='PermanentMarker-Regular', size=10, color='white', margin=margin(5,0,5,0)),
        axis.text.y = element_text(family='PermanentMarker-Regular', size=10, color='white'),
        axis.text.x = element_blank(),
        axis.title.x = element_blank(),
        panel.grid = element_blank(),
        panel.grid.major.y = element_line(size=0.05, color='white'),
        panel.background = element_rect(fill='black'),
        plot.background = element_rect(fill='black', color='black'),
        panel.border = element_blank(),
        plot.title = element_text(family='BebasNeue-Regular', color='red',size=45, margin=margin(15,0,5,0)),
        plot.subtitle = element_text(family='PermanentMarker-Regular', size=10, color='white'),
        plot.caption =  element_text(family='PermanentMarker-Regular', color='white',size=7,  margin=margin(30,0,0,0))) +
  labs(title='Netflix',
       subtitle='Duración de las películas sobre High School por año de estreno\n{closest_state}',
       caption = "Fuente: Kaggle",
       x='Año de estreno', y='Duración en min') -> p
p

En este paso hemos incluido principalmente dos cambios:

  • El subtítulo incluye ahora el estado o {closest_state} que mostrará el año de estreno en cada transición

  • Los puntos se sitúan en el mismo punto x ya que no necesitamos que el eje mapee la variable temporal, al ya incluirse en la animación en sí

Animar una visualización con gganimate

A continuación, cargamos la librería library(gganimate) y definimos como va a “entrar” y “salir” los datos de cada estado en cada una de las transiciones con enter_face() y exit_shrink().

library(gganimate)

p + 
  transition_states(release_year, transition_length = 2, state_length = 1) +
  enter_fade() + 
  exit_shrink()

Finalmente, para guardar el gráfico podemos hacerlo a través de la función anim_save().

Paula L. Casado
Paula L. Casado
Data Scientist

Científica de datos especializada en visualización de datos.

Relacionado