--- title: "Short Introduction to gganimate" author: "Arno Kimeswenger" output: html_document: code_folding: none # no hide/show button in html document number_sections: true css: "styles.css" editor_options: markdown: wrap: 72 --- ```{r setup, include=FALSE} knitr::opts_chunk$set( warning = TRUE, message = TRUE, error = TRUE ) options(warn = 1) ``` # Libraries: ```{r} library(tidyverse) library(viridis) library(plotly) library(gganimate) ``` # Data: ```{r} gapminder.coltypes <- cols( country = col_factor(), continent = col_factor(levels = c("Africa", "Americas", "Asia", "Europe", "Oceania")), year = col_integer(), lifeExp = col_double(), pop = col_integer(), gdpPercap = col_double() ) gapminder <- read_csv("gapminder.csv", col_types = gapminder.coltypes) gapminder |> head() ``` These are the values used for year: ```{r} gapminder |> distinct(year) |> arrange(year) |> pull(year) ``` These are the values used for continent: ```{r} gapminder |> pull(continent) |> levels() ``` # 2d Plots 2d plot ignoring year: This is a little weird, because each country appears several times. ```{r, fig.height=8} gapminder |> ggplot() + geom_point(aes(x = gdpPercap, y = lifeExp, fill = continent, size = pop), shape = 21, alpha = 0.8, color = "black") + # shapes 21 - 25 support fill and color scale_fill_manual( "Continent", values = viridis(7)[c(1, 3, 4, 6, 7)], guide = guide_legend(override.aes = list(shape = 21, alpha = 1, size = 5, color = "black")) # ensures the legend key shows the fill color, only some shapes support this ) + scale_size_continuous( "Population", breaks = c(5e7, 1e8, 5e8, 1e9, 2e9), # labels = scales::comma, labels = scales::label_number(scale = 1e-6, suffix = "M"), range = c(0.1, 15) ) + labs(x = "GDP per Capita", y = "Life Expectancy") + theme( legend.text.align = 1 ) ``` 2d plot for one year: Better, but now we plot year 2007 only. ```{r, fig.height=8} gapminder |> filter(year == 2007) |> ggplot() + geom_point(aes(x = gdpPercap, y = lifeExp, fill = continent, size = pop), shape = 21, alpha = 0.8, color = "black") + # shapes 21 - 25 support fill and color scale_fill_manual( "Continent", values = viridis(7)[c(1, 3, 4, 6, 7)], guide = guide_legend(override.aes = list(shape = 21, alpha = 1, size = 5, color = "black")) # ensures the legend key shows the fill color, only some shapes support this ) + scale_size_continuous( "Population", breaks = c(5e7, 1e8, 5e8, 1e9, 2e9), # labels = scales::comma, labels = scales::label_number(scale = 1e-6, suffix = "M"), range = c(0.1, 15) ) + labs(x = "GDP per Capita", y = "Life Expectancy") + theme( legend.text.align = 1 ) ``` 2d plot: We can use shape to distinguish more than one year, but it gets a bit crowded. ```{r, fig.height=8} gapminder |> filter(year %in% c(1997, 2002, 2007)) |> ggplot() + geom_point(aes(x = gdpPercap, y = lifeExp, fill = continent, shape = factor(year), size = pop), alpha = 0.8, color = "black") + # need factor(year) and not year scale_shape_manual( "Year", values = c(21, 22, 23), # shapes 21–25 support both fill and border color guide = guide_legend(override.aes = list(size = 5)) ) + scale_fill_manual( "Continent", values = viridis(7)[c(1, 3, 4, 6, 7)], guide = guide_legend(override.aes = list(shape = 21, alpha = 1, size = 5, color = "black")) # ensures the legend key shows the fill color, only some shapes support this ) + scale_size_continuous( "Population", breaks = c(5e7, 1e8, 5e8, 1e9, 2e9), # labels = scales::comma, labels = scales::label_number(scale = 1e-6, suffix = "M"), range = c(0.1, 15) ) + labs(x = "GDP per Capita", y = "Life Expectancy") + theme( legend.text.align = 1 ) ``` Can you find India, China, and the USA in the plot above? Maybe it is okay to look at fewer countries and plot all years using fill ```{r, fig.height=8} gapminder |> filter(country %in% c("China", "India", "United States", "Germany", "Austria")) |> ggplot() + geom_point(aes(x = gdpPercap, y = lifeExp, fill = year, shape = country, size = pop), alpha = 0.8, color = "black") + # use year and not factor(year) here scale_shape_manual( "Country", values = c(21, 22, 23, 24, 25), # shapes 21 - 25 support fill and color guide = guide_legend(override.aes = list(size = 5)) ) + scale_fill_viridis_c("Year") + scale_size_continuous( "Population", breaks = c(5e7, 1e8, 5e8, 1e9, 2e9), # labels = scales::comma, labels = scales::label_number(scale = 1e-6, suffix = "M"), range = c(0.1, 15) ) + labs(x = "GDP per Capita", y = "Life Expectancy") + theme( legend.text.align = 1 ) ``` # 3d Plot In rare cases, it makes sense to build 3d plots. ```{r, fig.height = 8} plot_ly() |> add_markers(data = gapminder, x = ~gdpPercap, y = ~year, z = ~lifeExp) ``` # Animation A better alternative is to use time directly and create an animation: ```{r} p <- ggplot(gapminder) + geom_point(aes(x = gdpPercap, y = lifeExp, fill = continent, size = pop), shape = 21, alpha = 0.8, color = "black") + # shapes 21 - 25 support fill and color scale_fill_manual( "Continent", values = viridis(7)[c(1, 3, 4, 6, 7)], guide = guide_legend(override.aes = list(shape = 21, alpha = 1, size = 5, color = "black")) # ensures the legend key shows the fill color, only some shapes support this ) + scale_size_continuous( "Population", breaks = c(5e7, 1e8, 5e8, 1e9, 2e9), # labels = scales::comma, labels = scales::label_number(scale = 1e-6, suffix = "M"), range = c(0.1, 15) ) + labs(x = "GDP per Capita", y = "Life Expectancy") + theme( legend.text.align = 1 ) + transition_time(year) + ease_aes("linear") n <- gapminder |> distinct(year) |> pull(year) |> length() animate(p, nframes = n, fps = 1) # we only plot our 12 time steps. Increasing means interpolating, one frame per second ``` Which country is on the top right? ```{r} gapminder |> filter(gdpPercap > 70000) ```