Just to start of the year in a positive way, I’m happy to announce that gganimate is now available on CRAN. This release is the result of a pretty focused development starting in the spring 2018 prior to my useR keynote about it.
The gganimate package has been around for quite some time now with David Robinson making the first commit in early 2016. David’s vision of gganimate revolved around the idea of frame-as-an-aesthetic and this easy-to-grasp idea gave it an early success. The version developed by David never made it to CRAN, and as part of ramping down his package development he asked me if I was interested in taking over maintenance. I was initially reluctant because I wanted a completely different API, but he insisted that he supported a complete rewrite. The last version of gganimate as maintained by David is still available but I very quickly made some drastic changes:
While this commit was done in the autumn 2017, nothing further happened until I decided to make gganimate the center of my useR 2018 keynote, at which point I was forced (by myself) to have some sort of package ready by the summer of 2018.
A fair amount of users have shown displeasure in the breaking changes this history has resulted in. Many blog posts have already been written focusing on the old API, as well as code on numerous computers that will no longer work. I understand this frustration, of course, but both me and David agreed that doing it this way was for the best in the end. I’m positive that the new API has already greatly exceeded the mind-share of the old API and given a year the old API will be all but a distant memory…
Such drastic breaking changes were required because of a completely different vision for how animation fitted into the grammar of graphics. Davids idea was that it was essentially a third dimension in the graphic and the animation was simply flipping through slices along the third dimension in the same way as you would look through the output of a CT scan. Me, on the other hand, wanted a grammar that existed in parallel to the grammar of graphics — not as part of it.
My useR keynote goes in to a lot of detail about my motivation and inspiration for taking on this approach, and I’ll not rehash it in this release post. Feel free to take a 1h break from reading as you watch the talk
The gist of it all is that animations are a multifaceted beast and requires much more than an additional aesthetic to be tamed. One of the cornerstones of the talk is the separation of animations into scenes and segues. In short, a segue is an animated change in the underlying laws of the graphic (e.g. changes to coordinate systems, scales, mappings, etc.), whereas a scene is a change in the data on display. Scenes are concerned with what and segues are concerned with how. This separation is important for several reasons: It gives me a natural focus area for the current version of gganimate (scenes), it serves as a theoretical backbone to group animation operation, and it is a central limit in animation good practices: “You should never change how and what at the same time”.
So, the version I’m presenting here is a grammar of animation uniquely focused on scenes. This does not mean that I’ll never look into segues, but they are both much harder, and less important than getting a scene grammar to make sense, so segues have to play second fiddle for now.
What’s in a scene
There are two main components to a scene: What we are looking at, and where we are looking from. The former is handled by transitions and shadows, whereas the latter is handled by views. In brief:
- transitions populates the frames of the animation with data, based on the data assigned to each layer. Several different transitions exists that interpret the layer data differently.
- shadows gives memory to each frame by letting each frame include data from prior or future frames.
- views allow you to modify the range of the positional scales (zoom and pan) either directly or as a function of the data assigned to the frame.
On top of these three main grammar components there is a range of functions to modify how key parts of animations behave — for a general introduction to the ins and outs of the API, please see the *Getting Started** guide.
Grammar vs API
While it may appear that grammar and API are the same, this is not the case. A
grammar is a theoretical construct, a backbone from which an API can be defined.
Several APIs could implement the same grammar in multiple, incompatible, ways.
For gganimate I have tried to align the API as much as possible with the ggplot2
API, so that the line between the two packages becomes blurred. You change a
plot to an animation by adding functions from gganimate to it, and the animation
is rendered when printing the animation object in the same way as ggplots are
rendered when printing the object. An example of this is adding
transition_reveal() to a plot to make it appear gradually along a numeric
library(ggplot2) library(gganimate) ggplot(airquality) + geom_line(aes(x = Day, y = Temp, group = Month))
last_plot() + transition_reveal(Day)
For the most part, the marriage between the ggplot2 and gganimate APIs is a happy one, though it does show at points that the ggplot2 API was never designed with animation in mind. I am particularly pleased with how powerful the API has turned out, and I have already seen countless uses I had never anticipated.
While this release is a milestone for gganimate, it is not a signal of it being
done as many things are still missing (even if we ignore the whole segue part
of the grammar). It does signal a commitment to stability from now on, though so
you should feel confident in using this package without fearing that your code
will break in the future. You can follow the state of the package at its
I’ll do a sort-of live cookbook talk on gganimate at this years RStudio conf in Austin, so if you are there and interested to learn more about the package do swing by.
Now, Go Animate!