可以在R中使用gganimate为多边形填充制作动画吗?

时间:2019-03-04 20:28:01

标签: r ggplot2 gganimate

我有县级数据来记录2002年至2018年该县首次检测到入侵性害虫的年份。我使用ggplot2创建了一张地图,该地图包根据害虫的年份用一种颜色填充了该县的多边形被检测到。

**是否可以使用gganimate软件包对地图进行动画处理,第一帧仅填充检测日期为2002的多边形,第二帧填充检测日期为2003或更早的多边形(因此2002和2003),检测日期为2004或更早(2002、2003、2004)等的第三帧? ** 澄清:我想让所有县多边形始终可见,并最初用白色填充,并且动画的每一帧都会根据检测年份添加县填充。

我尝试将transition_reveal(data$detect_year)与静态图一起使用,但是收到一个错误,“数据必须是整数,数值,POSIXct,日期,时差或orhms”。

以下是可重现示例的一些代码:

library(dplyr)
library(purrr)
library(maps)
library(ggplot2)
library(gganimate)
# Reproducible example
set.seed(42)
map_df <- map_data("county") %>% 
   filter(region == "minnesota")
map_df$detection_year <- NA
# Add random detection year to each county
years <- 2002:2006
map_list <- split(map_df, f = map_df$subregion)
map_list <- map(map_list, function(.x) {
   .x$detection_years <- mutate(.x, detection_years = sample(years, 1))
})
# collapse list back to data frame
map_df <- bind_rows(map_list)
map_df$detection_years <- as.factor(map_df$detection_years)

# Make plot
static_plot <- ggplot(map_df,
                      aes(x = long,
                          y = lat,
                          group = group)) +
   geom_polygon(data = map_df, color = "black", aes(fill = detection_years)) +
   scale_fill_manual(values = terrain.colors(n = length(unique(map_df$detection_years))),
                     name = "Year EAB First Detected") +
   theme_void() +
   coord_fixed(1.3)

animate_plot <- static_plot +
   transition_reveal(detection_years)

如果可能的话,我想这样做,但如果有人有想法,我也愿意接受其他解决方案。

2 个答案:

答案 0 :(得分:3)

可能是这样,但我不确定这是否是预期的输出。

我更改了您的代码,可能您不需要flattenedDateTime = inputZonedDateTime.with(TemporalAdjusters.firstDayOfMonth()); 。我用split为每个地区分配了一年。

group_by

对于过渡,您需要定义set.seed(42) years <- 2002:2006 map_df <- map_data("county") %>% filter(region == "minnesota") map_df <- map_df %>% group_by(subregion) %>% mutate(detection_year = sample(years,1)) ,此处与分组(idsubregion)相同,并为过渡定义正确的日期格式(group )变量(我使用了along

lubridate::year()

enter image description here

这是为你做的吗?

答案 1 :(得分:3)

从@RLave得到几乎满足我要求的答案并花了一点时间在文档上之后,我得以找到一种方法来完成我想要的事情。看起来不太干净,但是可以。

从本质上讲,我每年都需要在动画中创建一个数据帧,以复制其数据帧。然后,对于要设置动画效果的每个检测年份,我都在数据框的副本中编辑了detection_year变量,以便在感兴趣年份或更早检测到的任何县都保留其值,并且尚未将检测值转换为我绘制为白色的值。这样可以确保始终对所有县进行绘图。然后,我需要使用transition_manual以及我赋予原始数据帧的每个副本的唯一ID来确定动画的顺序。

library(dplyr)
library(purrr)
library(maps)
library(ggplot2)
library(gganimate)
# Reproducible example
set.seed(42)
years <- 2002:2006

map_df <- map_data("county") %>% 
   filter(region == "minnesota")

map_df <- map_df %>% 
   group_by(subregion) %>% 
   mutate(detection_year = sample(years,1))

animate_data <- data.frame()
for(i in 2002:2006){
   temp_dat <- map_df %>% 
      mutate(detection_year = as.numeric(as.character(detection_year))) %>% 
      mutate(detection_year = case_when(
         detection_year <= i ~ detection_year,
         detection_year > i ~ 2001
      ),
      animate_id = i - 2001
      )
   animate_data <- bind_rows(animate_data, temp_dat)
}

animate_data$detection_year <- as.factor(as.character(animate_data$detection_year))

# Make plot
static_plot <- ggplot(animate_data,
                      aes(x = long,
                          y = lat,
                          group = group)) +
   geom_polygon(data = animate_data, color = "black", aes(fill = detection_year)) +
   scale_fill_manual(values = c("white",
                                terrain.colors(n = 5)),
                     name = "Year First Detected") +
   theme_void() +
   coord_fixed(1.3) #+
   facet_wrap(~animate_id)

animate_plot <- static_plot +
   transition_manual(frames = animate_id)
animate_plot