如何使用 gganimate、sf 和 ggplot2 为空间地图上的点设置动画?

How can I animate points on a spatial map with gganimate, sf, and ggplot2?

我在为空间地图上的某些点设置动画时遇到了一些问题。出于某种原因,只有大约一半的点出现在动画中。在静态图中,我可以清楚地看到所有的点。

如何确保gganimation 显示所有点? gganimate 不使用空间地图 'play nicely' 吗?

有没有人有更多使用 gganimate 和空间绘图的经验? 我可以使用示例数据集重现该问题:

    library(sf)
    library(ggplot2)
    library(ggspatial)
    library(gganimate)

##Reading example data
    nc <- st_read(system.file("shape/nc.shp", package="sf"))

##Create new sf=variable of random points
    A <- nc %>% 
      st_sample(size = 30) %>% 
      st_coordinates() %>%
      as.data.frame()

##Create static map
    B <- ggplot() +
      annotation_spatial(data=nc) +
      geom_point(data = A, aes(x=X, y=Y), size = 2, col = "#3a6589")

##Create animation with points showing up one by one
    plot_anim <- B +
      transition_states(states = Y, state_length = 0, wrap = FALSE) +
      enter_recolor(fill = "#f0f5f9") +
      shadow_mark(past = TRUE, alpha = 1, fill = "#3a6589")

##Render animation
    animate(plot_anim, fps = 40, end_pause = 60)

我建议通过 ggplot2::geom_sf() 绘制您的点 - 我发现它在动画空间数据方面可靠。

请参阅下面稍作修改的代码;我所做的是:

  • 将 A 对象保留为 sf 格式
  • 用第二个(= Y)坐标创建了一个技术变量Y;然后在您的原始代码中使用它
  • 删除了 ggspatial 依赖项,并重新构造了静态地图调用
  • 删除了 fps = 40(除了文件大小,这应该没有影响);我们需要不到 2 MB 的空间才能在此处上传

您可能会发现需要安装 {transformr} 才能为 sf 对象设置动画;它不应该成为阻碍。

library(sf)
library(ggplot2)
library(gganimate)

##Reading example data
nc <- st_read(system.file("shape/nc.shp", package="sf"))

##Create new sf=variable of random points
A <- nc %>% 
  st_sample(size = 30) %>% 
  st_as_sf() %>% 
  dplyr::mutate(Y = st_coordinates(.)[,2])

##Create static map
B <- ggplot() +
  geom_sf(data = nc) +
  geom_sf(data = A, size = 2, col = "#3a6589")

# save static map
ggsave("static_map.png")

##Create animation with points showing up one by one
plot_anim <- B +
  transition_states(states = Y, state_length = 0, wrap = FALSE) +
  enter_recolor(fill = "#f0f5f9") +
  shadow_mark(past = TRUE, alpha = 1, fill = "#3a6589")

##Render animation
animate(plot_anim, end_pause = 60,
        height = 200, width = 400) # a higher res img would not upload here :(

# save animated map
anim_save("animated_map.gif")

静态地图/30个随机NC点

动态地图/小(因为 2 MB 的上传要求)但在其他方面对我来说看起来是合法的...