首页 > 解决方案 > 有什么方法可以创建以范围为过渡时间的动画(gganimate)?

问题描述

有没有办法让 gganimate 为几年范围内的过渡时间工作?在我的数据中,我有三个时间点,其中两个是如下所示的范围。

数据:

Year   rate   group
2012-2014   7   Other CT, White 
2015-2017   11  Other CT, White 
2018    3   Fairfield, Black    
2018    2   Fairfield, Hispanic

这是我想要制作动画的 ggplot 代码示例

data %>% ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {frame_time}") +
  transition_time(Year)

当我将转换时间输入为“年份”时,我收到一个错误,因为我的年份变量是一个容纳范围的字符。这是我得到的错误:

Error: time data must either be integer, numeric, POSIXct, Date, difftime, orhms

我能做些什么来绕过这个错误并继续原样的范围吗?

标签: rggplot2gganimate

解决方案


我建议要么使用transition_manual并将年份视为类别(失去平滑过渡),要么将年份范围转换为数字。

library(tidyverse); library(gganimate)
df1 <- tribble(~Year, ~rate, ~group,
               "2012-2014", 7, "grp1",
               "2015-2017", 11, "grp1",
               "2018", 3, "grp1")

第一种方法,将 Year 保持原样:

df1 %>% 
  ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {current_frame}") +
  transition_manual(Year)

enter image description here

Second approach, converting year to numeric. In this case, I just used the first year, but you could alternatively assign the value to the average year, or add rows with the value for each year in the range.

df1 %>% 
  mutate(Year_numeric = parse_number(Year)) %>%
  ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {round(frame_time)}") +
  transition_time(Year_numeric)

enter image description here

Finally, if you want to represent all the ranged years at the given level, you can create rows for all the component years. But this takes some elbow grease:

df1 %>% 
  # For ranged years, find how many in range:
  mutate(year_num = 1 + if_else(Year %>% str_detect("-"), 
                            str_sub(Year, start = 6) %>% as.numeric() - 
                              str_sub(Year, end = 4) %>% as.numeric(), 
                            0)) %>%
  # ... and use that to make a row for each year in the range
  tidyr::uncount(year_num) %>%
  group_by(Year) %>%
  mutate(Year2 = str_sub(Year, end = 4) %>% as.numeric() + 
                 row_number() - 1) %>%
  ungroup() %>%

# FYI at this point it looks like:
# A tibble: 7 x 4
#  Year       rate group Year2
#  <chr>     <dbl> <chr> <dbl>
#1 2012-2014     7 grp1   2012
#2 2012-2014     7 grp1   2013
#3 2012-2014     7 grp1   2014
#4 2015-2017    11 grp1   2015
#5 2015-2017    11 grp1   2016
#6 2015-2017    11 grp1   2017
#7 2018          3 grp1   2018

ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {round(frame_time)}") +
  transition_time(Year2)

enter image description here


推荐阅读