You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用gganimate实现geom_density_2d_filled的累积时间动画?

实现geom_density_2d_filled的累积动画

要将2D密度动画改为累积模式(每一帧基于当前及之前所有时间点的数据计算密度),最可靠的方式是先预处理生成累积数据集,再配合gganimate渲染动画。以下是具体实现方案:

方法一:预处理生成累积数据集

通过purrr::accumulate生成每个时间点对应的累积数据子集,确保每个帧使用的是从起始到当前月份的所有点:

library(dplyr)
library(sf)
library(geofi)
library(ggplot2)
library(gganimate)
library(purrr)

# 加载芬兰 municipality 数据
muns <- geofi::get_municipalities(year = 2022)

# 生成样本点数据
points <- sf::st_sample(muns, 240) %>% as.data.frame()
points[c("x", "y")] <- sf::st_coordinates(points$geometry)
monthly <- seq(as.Date("2020/1/1"), by = "month", length.out = 24) %>%
  rep(., each = 10)
points$monthly <- monthly

# 生成累积数据集:每个帧对应到该月份及之前的所有点
cumulative_points <- points %>%
  arrange(monthly) %>%
  split(.$monthly) %>%  # 按月份拆分数据
  accumulate(~bind_rows(.x, .y)) %>%  # 累积合并子集
  bind_rows(.id = "frame_month") %>%
  mutate(frame_month = as.Date(frame_month))  # 转换为日期格式

# 绘制累积动画
p <- ggplot() +
  # 使用累积数据计算密度,group参数确保每个帧独立计算
  geom_density_2d_filled(data = cumulative_points, 
                         aes(x = x, y = y, alpha = after_stat(level), group = frame_month)) +
  geom_sf(data = muns, fill = NA, color = "black") +
  coord_sf(default_crs = sf::st_crs(3067)) +
  geom_point(data = cumulative_points, 
             aes(x = x, y = y), 
             alpha = 0.1) +
  scale_alpha_manual(values = c(0, rep(0.75, 13)), guide = "none") +
  # 按累积帧切换
  transition_states(frame_month, 
                    transition_length = 1, 
                    state_length = 40) +
  labs(title = "Month: {closest_state}") + 
  ease_aes("linear")

# 渲染并保存动画
animate(p, renderer = gganimate::gifski_renderer())
gganimate::anim_save(filename = "cumulative_so.gif", path = "anim")

原理说明

  • 预处理阶段:accumulate函数会依次将每个月份的子集与之前所有子集合并,生成24个累积数据集(对应24个月份),每个数据集标记对应的frame_month。
  • 绘图阶段:group = frame_month确保geom_density_2d_filled为每个帧单独计算基于累积数据的密度分布,而非复用之前的计算结果。

替代思路:动态数据过滤

如果不想生成完整的累积数据集,也可以在ggplot中使用动态过滤配合transition_time,但这种方法对统计类图层的支持稳定性稍弱:

p <- ggplot() +
  geom_density_2d_filled(data = points, 
                         aes(x = x, y = y, alpha = after_stat(level), 
                             frame = monthly, cumulative = TRUE)) +
  geom_sf(data = muns, fill = NA, color = "black") +
  coord_sf(default_crs = sf::st_crs(3067)) +
  geom_point(data = points, 
             aes(x = x, y = y, frame = monthly, cumulative = TRUE), 
             alpha = 0.1) +
  scale_alpha_manual(values = c(0, rep(0.75, 13)), guide = "none") +
  transition_time(monthly) +
  labs(title = "Month: {frame_time}") + 
  ease_aes("linear")

内容的提问来源于stack exchange,提问作者Vesanen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:40:34