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
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
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
tutorials with time. If you create something with gganimate please share it on
twitter, as I’m eager to see what people will make of it.
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
Now, Go Animate!