使用 gganimate 将过渡数据放置在堆积条上

placing transition data on stacked bars with gganimate

我正在尝试在 R 中重新创建 this graph,但我无法设法让过渡数据显示在红色堆叠条中。我也不知道如何像 link.

图中那样以另一种颜色显示值下降的条形图

下面是一个示例代码:

df <- data.frame(group=c("A","B","C"), values=c(31,2,4,25,6,7,20,9,10,15,12,13,10,15,16,5,18,19), 
                frame=c(rep('a',3), rep('b',3), rep('c',3), rep('d',3), rep('e',3), rep('f',3)))

ggplot(df, aes(x=group, y=values, fill=group)) +
  coord_flip() +
  geom_bar(stat = 'identity') +
  geom_text(aes(label = values), vjust = -0.3, size = 3.5) +
  transition_manual(frame) +
  theme(legend.position = "none")

在我看来,您的数据 (df) 中缺少信息,无法使用堆积条形图。我创建了一个 frac 列,其中包含 values 列的乘数。在这个简单的示例中,我们将绘制一个堆叠条形图,每个组都有一个条形图,其中堆叠了值和值*frac。这就是你想要的吗?

library(ggplot2)
library(gganimate)
library(dplyr)
library(tidyr)

df <- data.frame(group=c("A","B","C"), 
                 values= c(31,2,4,25,6,7,20,9,10,15,12,13,10,15,16,5,18,19), 
                 frac = c(1, 1, 1, 1.1, 0.9, 0.8, 1.2, 0.8, 0.7, 1.2, 0.7, 0.6, 1.3, 0.6, 0.5, 1.4, 0.5, 0.4),
                 frame=c(rep('a',3), rep('b',3), rep('c',3), rep('d',3), rep('e',3), rep('f',3)))


df <- df %>%
  mutate(values2 = values * frac) %>%
  pivot_longer(cols = contains("values"),
               names_to = "values", 
               values_to = "data")
  

ggplot(df, aes(x = group, y = data)) +
  coord_flip() +
  geom_col(aes(fill = values)) +
  geom_text(aes(label = values), vjust = -0.3, size = 3.5) +
  transition_manual(frame) +
  theme(legend.position = "none")

有几种方法可以获得这种动画。我没有使用某种堆积条形图,而是使用两个 geom_col 层来达到预期的结果。

第一个 geom_col 随时间绘制 values,其中填充基于值相对于基值是增加还是减少。第二个 geom_col 绘制 values 随着时间的推移,其中填充基于值与基值相比是增加还是减少。

seocnd geom_col 简单地绘制基数 values,在这种情况下,我使用 alpha aes 根据值相对于基数是增加还是减少来获得透明度值。

library(ggplot2)
library(gganimate)
library(dplyr)

df <- data.frame(group=c("A","B","C"), values=c(31,2,4,25,6,7,20,9,10,15,12,13,10,15,16,5,18,19), 
                 frame=c(rep('a',3), rep('b',3), rep('c',3), rep('d',3), rep('e',3), rep('f',3)))

df1 <- df %>%
  group_by(group) %>% 
  mutate(base = values[frame == "a"],
         diff = values - base) %>% 
  ungroup()

ggplot(df1, aes(x=group)) +
  coord_flip() +
  geom_col(aes(y=values, fill = diff > 0), position = "identity") +
  geom_col(aes(y=base, alpha = diff > 0), fill = "blue", position = "identity") +
  scale_fill_manual(values = c("blue", "red")) +
  scale_alpha_manual(values = c("TRUE" = 1, "FALSE" = .2)) +
  geom_text(aes(y=values, label = values), vjust = -0.3, size = 3.5) +
  transition_manual(frame) +
  theme(legend.position = "none")
#> nframes and fps adjusted to match transition