R - tmap_animation 生成带绿框的 gif
R - tmap_animation generates gif with green frames
我正在尝试使用 tmap 创建动画 GIF 并将其显示在我的 Shiny 应用程序中。当我对单个日期使用 tm_shape() + tm_polygons() 时,生成的图像始终正常。但是,当我使用 tm_facets() 并将结果提供给 tmap_animation 时,生成的 GIF 具有随机的深绿色帧,如下所示。
这是我使用的生成动画的代码:
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,
0,
(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)
有人知道我该如何解决这个问题吗?
我遇到了同样的问题。 tmap
GitHub 问题选项卡上的 I asked about it,团队将其追溯到 gifski
包 tmap
用于生成 gif 动画的问题。我发现在不使用 tmap
.
的情况下使用 gifski
制作的动画也会发生同样的事情
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, facet_along_col_str, 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, facet_along, 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)
}
}
我正在尝试使用 tmap 创建动画 GIF 并将其显示在我的 Shiny 应用程序中。当我对单个日期使用 tm_shape() + tm_polygons() 时,生成的图像始终正常。但是,当我使用 tm_facets() 并将结果提供给 tmap_animation 时,生成的 GIF 具有随机的深绿色帧,如下所示。
这是我使用的生成动画的代码:
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,
0,
(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)
有人知道我该如何解决这个问题吗?
我遇到了同样的问题。 tmap
GitHub 问题选项卡上的 I asked about it,团队将其追溯到 gifski
包 tmap
用于生成 gif 动画的问题。我发现在不使用 tmap
.
gifski
制作的动画也会发生同样的事情
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, facet_along_col_str, 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, facet_along, 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)
}
}