6
Data <- data.frame(Time = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
                   Group = c("A", "B", "C", "A", "B", "C", "A", "B", "C"),
                   Value = c(20, 10, 15, 20, 20, 20, 30, 25, 35))

I have three Groups with Values at three different points in Time.

library(ggplot2)
library(gganimate)

p <- ggplot(Data, aes(Group, Value)) +
     geom_col(position = "identity") +
  geom_text(aes(label = Value), vjust = -1) +
     coord_cartesian(ylim = c(0, 40)) +
     transition_time(Time)
p 

The above code produces the animation for the transformation of the bars quite well, but the change in the geom_text leaves much to be desired, as the geom_text tweens/transitions with >10 decimal places. Ideally I want the geom_text numeric values to remain as an integer whilst transitioning, or some way to control the degree of rounding.

Edit: Changing Value to an integer type doesn't help.

enter image description here

Nautica
  • 2,004
  • 1
  • 12
  • 35

2 Answers2

4

You can try to calculate the transitions by your own beforehand...

library(gganimate)
library(tidyverse)
Data2 <- Data %>% 
  group_by(Group) %>% 
    arrange(Group) %>% 
    mutate(diff = c((Value - lag(Value))[-1],0))

Seq <- seq(1,3,0.01)
library(gganimate)
tibble(Time_new=rep(Seq,3), Group = rep(LETTERS[1:3], each = length(Seq))) %>% 
  mutate(Time=as.numeric(str_sub(as.character(Time_new),1,1))) %>% 
  left_join(Data2)  %>%
  group_by(Group, Time) %>% 
  mutate(diff = cumsum(diff/n())) %>% 
  mutate(Value2 = Value + diff) %>%
  mutate(new_old = ifelse(Time == Time_new, 2, 1)) %>% 
  ggplot(aes(Group, Value2)) +
  geom_col(position = "identity") +
  geom_text(aes(label = sprintf("%1.2f",Value2)), vjust = -1) +
  coord_cartesian(ylim = c(0, 40)) +
  transition_manual(Time_new) 

enter image description here

or try geom_text(aes(label = round(Value2,2)), vjust = -1)

Roman
  • 17,008
  • 3
  • 36
  • 49
  • Thanks! Great answer! I have been trying to figure out how to go around this for a while, but I don't know the details of tweening enough. This should definitely be accepted as the correct answer, since this currently an open issue in the package. Just one observation that in your second suggestion there is no tweening (so the number stays fixed until the "time" changes). Maybe it is worth mentioning it in your answer. – kikoralston Jun 07 '22 at 21:38
2

There is a very elegant, general solution provided by the package author, which is

..just put "Year: {as.integer(frame_time)}" as your title

From here

stevec
  • 41,291
  • 27
  • 223
  • 311
  • 1
    Sadly this does not seem to work for `geom_text()`. – lauren.marietta Apr 22 '21 at 19:56
  • @lauren.marietta if it’s a different problem to the one in the OP (it sounds like it may be), you could ask a new question showing how it differs. If you provide a minimal example it will hopefully get solved quickly. Feel free to add the link here if you do – stevec Apr 23 '21 at 04:06