This is a variant of transition_states() that is intended for data where the states are representing specific point in time. The transition length between the states will be set to correspond to the actual time difference between them.

transition_time(time, range = NULL)



An unquoted expression giving the time, and thus state membership, of each observation.


The time range to animate. If NULL it will be set to the range of time

Label variables

transition_time makes the following variables available for string literal interpretation, in addition to the general ones provided by animate():

  • frame_time gives the time that the current frame corresponds to

Object permanence

transition_time uses the group aesthetic of each layer to identify which rows in the input data correspond to the same graphic element and will therefore define which elements will turn into each other between time points. The group aesthetic, if not set, will be calculated from the interaction of all discrete aesthetics in the layer (excluding label), so it is often better to set it explicitly when animating, to make sure your data is interpreted in the right way. If the group aesthetic is not set, and no discrete aesthetics exists then all rows will have the same group. If the group aesthetic is not unique in each state, then rows will be matched first by group and then by index. Unmatched rows will appear/disappear, potentially using an enter or exit function.

Computed Variables

It is possible to use variables calculated by the statistic to define the transition. Simply inclose the variable in stat() in the same way as when using computed variables in aesthetics.


anim <- ggplot(airquality, aes(Day, Temp)) +
  geom_point(aes(colour = factor(Month))) +

# Removing a time point will prolong the tweening between neighbouring time
# points so the time dimension stays linear
airquality_missing <- airquality[airquality$Day <= 10 | airquality$Day >= 20, ]
anim1 <- ggplot(airquality_missing, aes(Day, Temp)) +
  geom_point(aes(colour = factor(Month))) +

# Range can be constrained if needed
anim2 <- ggplot(airquality, aes(Day, Temp)) +
  geom_point(aes(colour = factor(Month))) +
  transition_time(Day, range = c(10L, 20L))

# The group aesthetic is used to connect elements
# No grouping
anim3 <- ggplot(airquality, aes(Day, Temp)) +
  geom_line() +

# Group by month
anim4 <- ggplot(airquality, aes(Day, Temp)) +
  geom_line(aes(group = Month)) +
  transition_time(Month) +
  enter_fade() +