gganimate:在标题表达式中包含除状态级别变量或框架以外的其他变量

时间:2018-12-20 08:27:41

标签: r ggplot2 gganimate

我想将我的数据的另一个列值插入一个gganimate动画标题中。

例如,这里的状态级别变量为x,我想添加到标题变量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 

这按预期工作:

ggplot(df, aes(x, x)) +
  geom_point() +
  labs(title = '{closest_state}') +
  transition_states(x,
                    transition_length = 0.1,
                    state_length = 0.1)

enter image description here

此操作失败:

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)
  

eval中的错误(parse(text = text,keep.source = FALSE),envir):
  找不到对象“ y”

也尝试过此操作,但是y不会更改:

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)

enter image description here

另一种选择是将y映射为状态级别变量,并使用frame变量而不是x,但是在我的应用程序中y是不必要的-像上面一样的唯一字符变量,或者它是一个数字变量,但又不是唯一的且不是必需的顺序。在这种情况下,gganimate(或ggplot?)将按其认为合适的顺序对其进行排序,从而使最终结果不被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)

enter image description here

那么如何简单地添加无序y变量的无序变化值呢?

最后:有人问here这个问题,但没有可重复的示例,因此没有得到回答,希望这个问题会更好。

3 个答案:

答案 0 :(得分:2)

一个肮脏的解决方案是将变量paste合并在一起,然后在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  

然后,我们可以在ordet中使用gsub()从不需要的部分剥离closest_state,如下所示:

gsub(pattern = "\\d+-", replacement = "", "1-a") 
"a"

所以:

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)

enter image description here

答案 1 :(得分:1)

以下是使用 dplyr 的解决方案,基于 Giora 提供的 gganimate 开发人员 Thomas 的解决方案。

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)

gganimate 标题对动画标题元素使用 glue 语法,您可以在其中包含整个 dplyr 数据操作管道。

您可以在 closest_state 调用中引用 gganimate::transition_states() 提供的 dplyr 变量。在这里,由于动画的帧是由 x 的连续级别索引的,我使用 filter() 根据 df 的值对给定的帧进行子集 x,然后参考y 列的相应行,其中包含我想在标题中显示的附加信息。使用 pull,您可以获取与 y 对应的 x 的单个值并将其显示在动画标题中。

这是一种干净而直接的方法,优点是您可以例如通过在 summarize() 管道中添加 magrittr 和其他调用来计算要即时显示的汇总值.

答案 2 :(得分:0)

gganimate的作者本人在我提出的问题之后提出了另一种可能性,即更为紧凑:

https://github.com/thomasp85/gganimate/issues/252#issuecomment-450846868

根据托马斯:

  

输入数据中的随机列有多种原因   无法访问,因此没有比这更好的东西了。