使用tmap::tmap_animation()实现RasterStack图层GIF动画的方法及相关问题
tmap 制作 RasterStack 时序GIF动画的实现方案
异常成因
tmap本身就可以直接基于RasterStack制作时序GIF,之前输出带多个小图的单帧的问题,是参数设置不符合动画渲染逻辑导致的:直接将完整RasterStack传入绘图流程时,tmap会默认将每个栅格图层识别为并列空间变量,自动生成多面板分面布局,最终导出的GIF会把整张分面图作为单帧渲染,无法实现逐帧时序切换的效果。
原生栅格动画实现(无需转换sf对象)
核心是明确告知函数按图层维度做帧拆分,而非分面展示,操作步骤:
- 绘图阶段核心逻辑:在
tm_raster()中设置along = "layer"参数,将图层索引绑定为动画时序维度
参考代码:library(tmap) # 注:raster_stack为输入的目标RasterStack,所有图层地理范围一致 # 提前将图层命名为对应日期,导出时会自动作为每帧标题 names(raster_stack) <- c("2023-01-01", "2023-01-02", "2023-01-03") tm_base <- tm_shape(raster_stack) + tm_raster( col = 1:nlayers(raster_stack), along = "layer", # 关键参数:标记按图层维度生成动画帧 legend.reverse = TRUE ) + tm_layout(legend.outside = TRUE) # 固定图例位置,避免每帧位置跳动 # 导出GIF tmap_animation( tm = tm_base, filename = "daily_raster.gif", delay = 100, # 单帧停留时长(单位:毫秒) width = 1000, height = 1000 ) - 一致性设置:提前在
tm_shape()中通过bbox = raster::extent(raster_stack)锁定全局地理范围,避免每帧自动适配范围导致的画面偏移;可在tm_raster()中设置统一的breaks参数,保证所有帧的颜色刻度完全一致。
低效率sf转换方案的优化
如果因版本兼容问题必须走sf转换路径,不要逐图层转sf再手动rbind:直接调用raster::rasterToPolygons(raster_stack, dissolve = FALSE)一次性将完整RasterStack转换为长表格式的sf对象,对象会自动附带每个图层对应的日期/属性字段,后续直接绑定时序字段做动画即可,运行效率较逐图层拼接提升80%以上。
内容的提问来源于stack exchange,提问作者Jackson
相关产品推荐
相关产品推荐

