class: center, middle, title-slide .title[ # Animations ] .author[ ### Claus O. Wilke ] .date[ ### last updated: 2024-04-22 ] --- ## Animations can create more engaging displays .center.move-up-1em[ <img src="animations_files/figure-html/gdp-anim-bar-race-1.gif" width="50%" /> ] .absolute-bottom-right.tiny-font[ Data source: World Bank ] --- ## Animations can create more engaging displays .center[ <img src="animations_files/figure-html/gdp-anim-lines-race-1.gif" width="66%" /> ] .absolute-bottom-right.tiny-font[ Data source: World Bank ] --- ## We make animations in R with **gganimate** .width-70[ ```r library(tidyverse) library(gganimate) # make fun animations ... ``` ] The **gganimate** package adds powerful animation tools to **ggplot2** <img src = "https://gganimate.com/reference/figures/logo.png", width = 15%, style = "position:absolute; top: 19%; right: 13%;" /> --- ## Getting the data We'll be working with the `gdp_ranked` dataset: .tiny-font[ ```r gdp_ranked <- read_csv("https://wilkelab.org/SDS375/datasets/gdp_ranked.csv") %>% mutate(rank = fct_rev(factor(rank))) gdp_ranked ``` ``` # A tibble: 500 × 6 country country_code year gdp rank gdp_rel <chr> <chr> <dbl> <dbl> <fct> <dbl> 1 Brazil BRA 1970 42.3 10 0.0395 2 Brazil BRA 1971 49.2 10 0.0424 3 Brazil BRA 1972 58.5 10 0.0457 4 Brazil BRA 1973 79.3 10 0.0555 5 Brazil BRA 1974 105 9 0.0677 6 Brazil BRA 1975 124 9 0.0738 7 Brazil BRA 1976 153 9 0.0818 8 Brazil BRA 1977 176 8 0.0846 9 Brazil BRA 1978 201 8 0.0855 10 Brazil BRA 1979 225 8 0.0856 # ℹ 490 more rows ``` ] --- class: center middle ## How should we think about making an animation? --- ## Think of an animation as faceting by time .center.move-up-1em[ <img src="animations_files/figure-html/gdp-anim-bar-facets-1.svg" width="80%" /> ] --- ## We know how to make a faceted plot .tiny-font[ ```r gdp_ranked %>% filter(year > 1985 & year %% 5 == 0) %>% ggplot(aes(gdp, rank)) + geom_col(aes(fill = country)) + facet_wrap(~year) ``` ] .center[ <img src="animations_files/figure-html/gdp-facet-demo-out-1.svg" width="50%" /> ] --- ## Making an animation is about as complicated .tiny-font[ ```r gdp_ranked %>% # gganimate uses the `group` aesthetic to track objects across frames ggplot(aes(gdp, rank, group = country)) + geom_col(aes(fill = country)) + transition_states(year, transition_length = 5) ``` ] .center[ <img src="animations_files/figure-html/gdp-bar-race-demo-1.gif" width="40%" /> ] --- ## Adding country names and plot title .tiny-font.pull-left.width-50[ ```r gdp_ranked %>% ggplot(aes(gdp, rank, group = country)) + geom_col(aes(fill = country)) + geom_text( aes(x = -200, label = country), hjust = 1, size = 14/.pt ) + xlim(-7000, 23000) + labs(title = "year: {closest_state}") + theme_minimal_vgrid(14, rel_small = 1) + theme( axis.text.y = element_blank(), axis.title.y = element_blank(), axis.ticks.y = element_blank(), axis.line.y = element_blank() ) + guides(fill = "none") + transition_states(year, transition_length = 5) ``` ] .pull-right.width-40[ <img src="animations_files/figure-html/gdp-anim-fancy-out-1.gif" width="100%" /> ] --- ## We make time series with `transition_reveal()` .tiny-font.pull-left.width-50[ ```r selected <- c("China", "Japan", "United States", "Germany", "Brazil") gdp_ranked %>% filter(country %in% selected) %>% ggplot(aes(year, gdp, color = country)) + geom_line() + geom_point(size = 3) + scale_y_log10() + transition_reveal(year) ``` ] .pull-right.width-45[ <img src="animations_files/figure-html/gdp-line-race-demo-out-1.gif" width="100%" /> ] --- ## This works also with **ggrepel** for labeling .tiny-font.pull-left.width-50[ ```r gdp_ranked %>% filter(country %in% selected) %>% ggplot(aes(year, gdp, color = country)) + geom_line() + geom_point(size = 3) + geom_text_repel( aes(label = country), hjust = 0, nudge_x = 2, direction = "y", xlim = c(NA, Inf), segment.color = NA ) + scale_y_log10() + guides(color = "none") + coord_cartesian(clip = "off") + theme(plot.margin = margin(7, 100, 7, 7)) + transition_reveal(year) ``` ] .pull-right.width-45[ <img src="animations_files/figure-html/gdp-line-race-labeled-out-1.gif" width="100%" /> ] --- ## Reproducing the famous gapminder animation .xtiny-font.pull-left.width-50[ ```r library(gapminder) gapminder %>% filter(continent != "Oceania") %>% ggplot() + aes(gdpPercap, lifeExp, size = pop) + geom_point(alpha = 0.7, color = "#0072B2") + scale_size(range = c(2, 12), guide = "none") + scale_x_log10(name = "GDP per capita") + facet_wrap(~continent, nrow = 2) + labs( title = "Year: {frame_time}", y = "life expectancy" ) + transition_time(year) + ease_aes("linear") ``` See Hans Rosling [video here.](https://www.youtube.com/watch?v=jbkSRLYSojo) ] .pull-right.width-45[ <img src="animations_files/figure-html/gapminder-bubbles-out-1.gif" width="100%" /> ] --- ## Further reading - **gganimate** documentation: [Getting started](https://gganimate.com/articles/gganimate.html) - **gganimate** reference documentation: [`transition_states()`](https://gganimate.com/reference/transition_states.html) - **gganimate** reference documentation: [`transition_reveal()`](https://gganimate.com/reference/transition_reveal.html)