Permalink
Fetching contributors…
Cannot retrieve contributors at this time
118 lines (92 sloc) 4.41 KB
---
title: Animated TIE Fighter
author: Jake Thompson
date: '2018-05-04'
categories:
- rstats
tags:
- ggplot2
- gganimate
---
```{r setup, include = FALSE, message = FALSE}
library(knitr)
library(animation)
animation::ani.options(
autobrowse = FALSE,
interval = 0.2
)
knitr::opts_knit$set(animation.fun = function(x, options, format = "gif") {
x = c(knitr:::sans_ext(x), knitr:::file_ext(x))
fig.num = options$fig.num
format = sub("^[.]", "", format)
fig.fname = paste0(sub(paste0(fig.num, "$"), "*", x[1]),
".", x[2])
mov.fname = paste0(sub(paste0(fig.num, "$"), "", x[1]), ".",
format)
# order correctly
figs <- Sys.glob(fig.fname)
figs <- figs[order(as.numeric(stringr::str_match(figs,
paste0("(\\d+)\\.", x[2]))[, 2]))]
animation::im.convert(figs, output = mov.fname)
# For Github output
# sprintf("![%s](%s)", options$label, paste0(opts_knit$get("base.url"),
# mov.fname))
# For HTML output
sprintf('<div class="figure %s"><img src="%s"></div>', options$fig.align,
mov.fname)
})
knitr::opts_chunk$set(
collapse = TRUE,
message = FALSE,
warning = FALSE,
comment = "#>",
echo = TRUE,
cache = FALSE,
fig.align = "center",
fig.width = 6,
fig.asp = 0.7,
out.width = "80%"
)
```
Recently I've been looking for an excuse to try out [Thomas Lin Pedersen's](https://twitter.com/thomasp85) new grammar of animation, which is an extension of [**ggplot2**](http://ggplot2.tidyverse.org) and a retooling of the existing [**gganmiate**](https://github.com/thomasp85/gganimate/tree/v0.1.1) package. You can find the new package [here](https://github.com/thomasp85/gganimate).
Luckily for me, Rafael Irizarry provided the perfect inspiration:
`r blogdown::shortcode("tweet", "992397723532963841")`
So in honor of Star Wars day, I decided to create Rafael's TIE fighter GIF using the new **gganimate**. Before we start, we need to install **gganimate** from GitHub, and load the packages we'll need.
```{r load-packages, message = FALSE}
# devtools::install_github("thomasp85/gganimate")
library(tidyverse)
library(gganimate)
```
## Create data to plot
We first need to create a data set. We'll start by defining the number of locations we want our TIE fighter to float between. Here, I've set this to be 20 locations. Next, we create the data frame. We set an `id` for each location, set a random `x` and `y` coordinate for each, and then make the label be the shape of the TIE fighter (I've also set a random seed so we can exactly replicated these locations later).
```{r create-data}
set.seed(20180504)
locations <- 20
tie_data <- data_frame(
id = seq_len(locations),
x = runif(locations),
y = runif(locations),
label = "|-o-|"
)
tie_data
```
## Create a static plot
Now that we have our data, we can the plot out all of the locations at once to see where our TIE fighter will be flying to. To make it more space like, we can make the plot background black using `theme`, and make our TIE fighters white and bold. Finally, our TIE fighters will be centered on the `x` and `y` coordinates we generated by default. This means that when the coordinates are close to the edge, we risk the wings getting cut off by the plot borders. One solution would be to set the horizontal and vertical alignment based on the coordinates. However, an easier solution is just to expand the limits of the plot using `expand_limits`, to make sure there is enough padding all the way around.
```{r static-plot}
ggplot(tie_data, aes(x = x, y = y, label = label)) +
geom_text(color = "white", fontface = "bold", size = 12) +
expand_limits(x = c(-0.1, 1.1), y = c(-0.1, 1.1)) +
theme_void() +
theme(panel.background = element_rect(fill = "black"))
```
## Create an animated plot
Finally, we can animate the plot using **gganmiate** with just one additional line of code! We simply add a `transition_states` call, and specify that each `id` is its own state. We can also specify the relative length of the states and the transitions between them.
```{r animate-plot}
ggplot(tie_data, aes(x = x, y = y, label = label)) +
geom_text(color = "white", fontface = "bold", size = 12) +
expand_limits(x = c(-0.1, 1.1), y = c(-0.1, 1.1)) +
theme_void() +
theme(panel.background = element_rect(fill = "black")) +
transition_states(id, transition_length = 4, state_length = 1)
```
And that's it! Just like that we have an animated TIE fighter using **ggplot2** and **gganimate**! Happy Star Wars day!