如何使用gganimate制作分组条形图动画?

3
我想制作一个分组条形图的动画,使得每个系列依次绘制并保持可见。在下面的示例图中,我希望首先绘制id = 1的条形,并保持可见,然后依次绘制id = 2、id = 3、id = 4的条形。

enter image description here

df <- data.frame(id = factor(c(1:4)),
                    var1 = c(0, 20,60, 80),
                    var2 = c(18, 64, 91, 100),
                    var3 = c(8, 73, 100, 100),
                    var4 = c(18, 48, 67, 85))

df_melt <- melt(df, id.var = "id")
df_melt <- df_melt %>% mutate(show_time = 1, reveal_time = cumsum(show_time))

ggplot(data = df_melt, aes(x = variable, y = value, fill = id)) + 
    geom_bar(stat = "identity", position = "dodge")

我已经能够使用transition_reveal生成动态线图,如此处所述:https://www.datanovia.com/en/blog/gganimate-how-to-create-plots-with-beautiful-animation-in-r/

为了实现我的目标,我尝试过使用transition_reveal和transition_states(单独和结合使用),但到目前为止都没有成功。例如:transition_states(id)。

我还尝试将一个reveal_time列添加到我的数据中,并使用transition_reveal(reveal_time),但没有成功。

我生成的所有动画都将id = 2的值绘制在id = 1的上方,而不是旁边。因此,最后一帧是一个条形图,而不是四组四个柱子。

非常感谢任何帮助-谢谢!


嗨 - 我的理解是 facet_wrap 会绘制四个单独的条形图,逐个出现。我真的很想能够在单个绘图区域上绘制一个分组的条形图,逐系列显示。 - grdn
1个回答

3

这个想法是指定数据存在的时间点。例如,id == 1 的条形图在四个不同的时间点存在(即在 1、2、3、4 点),id == 2 在三个时间点存在,依此类推:

library(tidyr)
library(dplyr)
library(gganimate)
df <- data.frame(id = factor(c(1:4)),
                 var1 = c(0, 20,60, 80),
                 var2 = c(18, 64, 91, 100),
                 var3 = c(8, 73, 100, 100),
                 var4 = c(18, 48, 67, 85))

df$show_time <- 1:4
for(i in 1:nrow(df)){
          df$show_time[i] <- list(df$show_time[i][[1]]:4)
}
df <- unnest(df, show_time)

这是它的外观:

> head(df, 5)
  id show_time variable value
1  1         1     var1     0
2  1         2     var1     0
3  1         3     var1     0
4  1         4     var1     0
5  2         2     var1    20

接下来,我将数据重新塑造成所提出的格式,并绘制动画:

df <- gather(df, variable, value, -c(id,show_time))  # reshape

ggplot(data = df, aes(x = variable, y = value, fill = id)) + 
          geom_bar(stat = "identity", position = "dodge") +
          transition_states(show_time, wrap = F) 


这是结果:

enter image description here


编辑 为了让条形图不是突然出现,你可以通过调整transition_states函数中的transition_length参数,并在动画中添加enter_fade来缓慢显示条形图。

ggplot(data = df, aes(x = variable, y = value, fill = id)) + 
          geom_bar(stat = "identity", position = "dodge") +
          transition_states(show_time, wrap = F, transition_length = 5) +
          enter_fade()

此外,您可以让条形图“漂移”到绘图中:

ggplot(data = df, aes(x = variable, y = value, fill = id)) + 
          geom_bar(stat = "identity", position = "dodge") +
          transition_states(show_time, wrap = F, transition_length = 5) +
          enter_fade() +
          enter_drift(x_mod = 0, y_mod = -max(df$value))

就像我之前所说的,可能有很多不同的方法来实现它,但这是一个开始:

输入图像描述


感谢您的回复和解释。对我所拥有的东西真是一个巨大的改进。最后一个小问题是是否有一种方法可以显示新的条形图,而不是立即出现。我已经尝试从您的代码中进行调整,但一直无法实现这一点。 - grdn
@BenNutzer 这个真是太有灵感了! - Nova

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接