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

如何用gganimate制作按年份分帧的热力图(仅显示当年数据)

解决方案

要实现每年一帧且仅展示对应年份热力图的需求,你需要调整两个关键部分:让密度计算按年份分组,以及使用离散帧切换的过渡函数,而非连续的transition_time。

修正后的代码

library(ggplot2)
library(gganimate)

# 取消数据分组,避免分组逻辑干扰绘图
foo_ungrouped <- dplyr::ungroup(foo)

ggplot(foo_ungrouped) +
  geom_density_2d_filled(
    aes(x = x, y = y, fill = ..level.., group = yearSeason),  # 按年份单独计算密度
    contour_var = "ndensity",
    breaks = seq(0.01, 1, length.out = 10),
    alpha = .5
  ) +
  labs(title = 'Year: {closest_state}') +  # 匹配当前帧的年份
  transition_states(yearSeason, transition_length = 0, state_length = 1) +  # 无过渡,每帧停留
  ease_aes('linear')

关键调整说明

  • 按年份分组计算密度:在aes中添加group = yearSeason,确保geom_density_2d_filled为每个年份单独生成热力图,而非用全部数据生成统一的密度分布。
  • 替换过渡函数:用transition_states替代transition_time——前者针对离散状态(年份),设置transition_length = 0可去掉帧间过渡动画,直接切换到对应年份的热力图;state_length = 1控制每帧的停留时长。
  • 标题变量匹配:用{closest_state}替代{frame_time},适配transition_states的状态变量,准确显示当前帧的年份。

备选方案:手动控制帧

如果偏好手动管理帧逻辑,可使用transition_manual,效果一致:

ggplot(foo_ungrouped) +
  geom_density_2d_filled(
    aes(x = x, y = y, fill = ..level.., group = yearSeason),
    contour_var = "ndensity",
    breaks = seq(0.01, 1, length.out = 10),
    alpha = .5
  ) +
  labs(title = 'Year: {current_frame}') +
  transition_manual(yearSeason)  # 直接按年份作为独立帧

原代码失效原因

  1. 未按年份分组:所有年份数据被合并计算密度,导致每帧仅标题变化,热力图内容无差异。
  2. 错误使用过渡函数:transition_time是连续时间过渡,会在年份间生成中间帧,不符合"每年一帧"的离散需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:50:36