I'd like to insert another column value of my data into a gganimate
animation title.
Example, here the states level variable is x
and I'd like to add to title variable y
:
df <- tibble(x = 1:10, y = c('a', 'a', 'b', 'd', 'c', letters[1:5]))
df
A tibble: 10 x 2
x y
<int> <chr>
1 1 a
2 2 a
3 3 b
4 4 d
5 5 c
6 6 a
7 7 b
8 8 c
9 9 d
10 10 e
This works as expected:
ggplot(df, aes(x, x)) +
geom_point() +
labs(title = '{closest_state}') +
transition_states(x,
transition_length = 0.1,
state_length = 0.1)
This fails:
ggplot(df, aes(x, x)) +
geom_point() +
labs(title = '{closest_state}, another_var: {y}') +
transition_states(x,
transition_length = 0.1,
state_length = 0.1)
Error in eval(parse(text = text, keep.source = FALSE), envir) :
object 'y' not found
Also tried this, but y
will not change:
ggplot(df, aes(x, x)) +
geom_point() +
labs(title = str_c('{closest_state}, another_var: ', df$y)) +
transition_states(x,
transition_length = 0.1,
state_length = 0.1)
Another option is to map y
as the states level variable and use the frame
variable instead of x
, but in my application y
is either a not-necessarily-unique character variable like above, or it is a numeric variable but again not-necessarily-unique and not-necessarily-ordered. In which case gganimate
(or ggplot
?) will order it as it sees fit, making the final result weird not ordered by x
:
ggplot(df, aes(x, x)) +
geom_point() +
labs(title = '{frame}, another_var: {closest_state}') +
transition_states(y,
transition_length = 0.1,
state_length = 0.1)
So how to simply add the changing value of the un-ordered, not numeric, y
variable?
Finally: This question was asked here but without a reproducible example so it was not answered, hoping this one is better.
One dirty solution would be to paste
together the variables and make a new one to use in the transition_states
:
df <- mutate(df, title_var = factor(paste(x, y, sep="-"), levels = paste(x, y, sep="-")))
# # A tibble: 6 x 3
# x y title_var
# <int> <chr> <fct>
# 1 1 a 1-a
# 2 2 a 2-a
# 3 3 b 3-b
# 4 4 d 4-d
# 5 5 c 5-c
# 6 6 a 6-a
Then we could use gsub()
in ordet to strip closest_state
from the unwanted part, like this:
gsub(pattern = "\\d+-", replacement = "", "1-a")
"a"
So:
ggplot(df, aes(x, x)) +
geom_point() +
labs(title = '{gsub(pattern = "\\d+-", replacement = "", closest_state)}') +
transition_states(title_var, transition_length = 0.1, state_length = 0.1)
Another possibility, slightly more compact, from the author of gganimate
himself, following the issue I opened:
https://github.com/thomasp85/gganimate/issues/252#issuecomment-450846868
According to Thomas:
There are multiple reasons why random columns from the input data cannot be accessed so it is unlikely to get any better than this...
Here's a solution using dplyr
, based on the gganimate
developer Thomas's solution, provided by Giora.
library(tidyverse)
library(gganimate)
df <- tibble::tibble(x = 1:10, y = c('a', 'a', 'b', 'd', 'c', letters[1:5]))
a <- ggplot(df, aes(x, x)) +
geom_point() +
labs(title = "{closest_state}, another_var: {df %>% filter(x == closest_state) %>% pull(y)}") +
transition_states(x,
transition_length = 0.1,
state_length = 0.1)
animate(a)
The gganimate
titles use glue
syntax for the animated title elements, and you can include entire dplyr
data manipulation pipelines within them.
You can refer to the closest_state
variable provided by gganimate::transition_states()
within your dplyr
calls. Here, since the animation's frames are indexed by successive levels of x
, I use filter()
to subset df
for a given frame based on the value of x
and then refer to corresponding rows of column y
, which contain additional information I'd like to display in the title. Using pull
, you can grab the individual value of y
corresponding to x
and display it within the animation's title.
This is a clean and straightforward way to do it with the advantage that you can, e.g., compute summary values to display on-the-fly by adding summarize()
and other calls in your magrittr
pipeline.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With