R - tmap_animation 生成带有绿框的 gif

问题描述

我正在尝试使用 tmap 创建动画 GIF 并将其显示在我的 Shiny 应用程序中。当我将 tm_shape() + tm_polygons() 用于单个日期时,生成的图像总是可以的。但是,当我使用 tm_facets() 并将结果提供给 tmap_animation 时,生成的 GIF 具有随机的深绿色帧,如下所示。

enter image description here

这是我用来生成动画的代码

data(World)

confirmed = read.csv('./data/time_series_covid_19_confirmed.csv',stringsAsFactors = T) %>%
  select(-Province.State,-Country.Region) %>%
  pivot_longer(!c('Lat','Long','iso3'),names_to = 'date',values_to = 'confirmed') %>%
  mutate(date = as.Date(gsub('X','',date),'%m.%d.%Y')) %>%
  group_by(iso3,date) %>%
  summarise(confirmed = sum(confirmed)) %>%
  mutate(perc_change = 100 * ifelse(
      lag(confirmed,default = 0) == 0 | confirmed < 1000 | lag(confirmed) > confirmed,(confirmed - lag(confirmed)) / lag(confirmed)
    )
  ) %>%
  inner_join(select(World,iso_a3,geometry),by=c('iso3' = 'iso_a3')) %>%
  st_sf()

conf_anim = confirmed %>%
  filter(date < '2020-02-28') %>%
  tm_shape() + tm_polygons('perc_change',style='cont') +
  # tm_fill('perc_change',palette='Blues',style='fixed',#         breaks=c(0,5,10,15,20,25,30,35,40,45,Inf)) + tm_borders() +
  tm_facets(along='date',free.coords = F)

tmap_animation(conf_anim,filename = './www/conf_anim.gif',delay=50)

有人知道我该如何解决这个问题吗?

解决方法

我遇到了同样的问题。 I asked about it 位于 tmap GitHub 问题选项卡上,团队将其追溯到 gifskitmap 用于生成 gif 动画的问题。我发现使用 gifski 而不使用 tmap 制作的动画也会发生同样的事情。

mtennekes 目前建议的解决方法是将动画保存为 mp4 而不是 gif,后者使用 av 包:

tmap_animation(conf_anim,filename = './www/conf_anim.mp4',delay=50)

不是一个完整的修复,但希望它对您的直接应用有所帮助。

,

如果其他人对此有疑问,我可以使用 tmap、gifski(tmap 用于生成 GIF)、dplyr 和 png 库创建一个解决方法。 此方法速度不快,并且以这种方式生成 GIF 可能需要很长时间。 提到使用 MP4 格式而不是 GIF 的另一个答案 - 如果您可以选择,此方法要快得多。 >

假设您有一个名为 df_sf 的 sf 对象,您正试图将其分面 facet_along_col_str 并且 tm_polygons 的第一个参数是 polygon_col_str,这里是可帮助您生成 GIF 的代码:

library(tmap)
library(gifski)
library(png)
library(dplyr)

generate_gif = function(sf_df,facet_along_col_str,polygon_col_str,gif_file,delay) {
  dims = get_dims(sf_df,polygon_col_str)
  save_gif(get_maps(sf_df),height=dims[1],width=dims[2],delay=delay,gif_file=gif_file)
}

get_dims = function(sf_df,facet_along,polygon_col) {
  slice = st_drop_geometry(select(sf_df,!!as.symbol(map_slice_col)))[[1]][1]
  t = tm_shape(filter(sf_df,!!as.symbol(map_slice_col) == slice)) +
    tm_polygons(polygons_col)
  filename = tempfile(fileext='.png')
  tmap_save(t,filename=filename)
  dims = dim(readPNG(filename))
  file.remove(filename)

  return(dims)
}

get_maps = function(sf_df,polygon_col) {
  slices = st_drop_geometry(select(sf_df,!!as.symbol(map_slice_col)))[[1]]
  slices = sort(unique(slices))
  for (i in 1:length(slices)) {
    t = tm_shape(filter(sf_df,!!as.symbol(facet_along) == slices[i])) +
      tm_polygons(polygon_col)
    print(t)
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...