5.1 Key frame animations
ggplotly() support key frame animations through the
frame attribute/aesthetic. They also support an
ids attribute/aesthetic to ensure smooth transitions between objects with the same id (which helps facilitate object constancy). Figure 3.31 recreates the famous gapminder animation of the evolution in the relationship between GDP per capita and life expectancy evolved over time (Bryan 2015). The data is recorded on a yearly basis, so the year is assigned to
frame, and each point in the scatterplot represents a country, so the country is assigned to
ids, ensuring a smooth transition from year to year for a given country.
data(gapminder, package = "gapminder") gg <- ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) + geom_point(aes(size = pop, frame = year, ids = country)) + scale_x_log10() ggplotly(gg)
As long as a
frame variable is provided, an animation is produced with play/pause button(s) and a slider component for controlling the animation. These components can be removed or customized via the
animation_slider() functions. Moreover, various animation options, like the amount of time between frames, the smooth transition duration, and the type of transition easing may be altered via the
animation_opts() function. Figure 3.32 shows the same data as Figure 3.31, but doubles the amount of time between frames, uses linear transition easing, places the animation buttons closer to the slider, and modifies the default
currentvalue.prefix settings for the slider.
base <- gapminder %>% plot_ly(x = ~gdpPercap, y = ~lifeExp, size = ~pop, text = ~country, hoverinfo = "text") %>% layout(xaxis = list(type = "log")) base %>% add_markers(color = ~continent, frame = ~year, ids = ~country) %>% animation_opts(1000, easing = "elastic", redraw = FALSE) %>% animation_button( x = 1, xanchor = "right", y = 0, yanchor = "bottom" ) %>% animation_slider( currentvalue = list(prefix = "YEAR ", font = list(color="red")) )
frame is a numeric variable (or a character string), frames are always ordered in increasing (alphabetical) order; but for factors, the ordering reflects the ordering of the levels. Consequently, factors provide the most control over the ordering of frames. In Figure 3.33, the continents (i.e., frames) are ordered according their average life expectancy across countries within the continent. Furthermore, since there is no meaningful relationship between objects in different frames of Figure 3.33, the smooth transition duration is set to 0. This helps avoid any confusion that there is a meaningful connection between the smooth transitions. Note that these options control both animations triggered by the play button or via the slider.
meanLife <- with(gapminder, tapply(lifeExp, INDEX = continent, mean)) gapminder$continent <- factor( gapminder$continent, levels = names(sort(meanLife)) ) base %>% add_markers(data = gapminder, frame = ~continent) %>% hide_legend() %>% animation_opts(frame = 1000, transition = 0, redraw = FALSE)
ids attributes operate on the trace level – meaning that we can target specific layers of the graph to be animated. One obvious use case for this is to provide a background which displays every possible frame (which is not animated) and overlay the animated frames onto that background. Figure 3.34 shows the same information as Figure 3.32, but layers animated frames on top of a background of all the frames. As a result, it is easier to put a specific year into a global context.
base %>% add_markers(color = ~continent, alpha = 0.2, showlegend = F) %>% add_markers(color = ~continent, frame = ~year, ids = ~country) %>% animation_opts(1000, redraw = FALSE)
Bryan, Jennifer. 2015. Gapminder: Data from Gapminder. https://CRAN.R-project.org/package=gapminder.