在 R 中从一系列 Leaflet 地图创建 gif

问题描述 投票:0回答:3

我正在寻找一种自动化方法将

leaflet
R Studio 绘图转换为图像文件。

似乎将

leaflet
小部件导出到 HTML 很简单(将传单输出保存为 html)。但是,我找不到有关如何将
leaflet
小部件生成的图像保存为图像的任何答案或文档。似乎很奇怪,我可以在 R Studio 中手动执行此操作,但 R Studio 中没有可以调用某些函数来执行相同的操作。

我尝试了常见的怀疑,以下变化:

png("test_png.png")
map
dev.off()

但是这些都只是打印白色或者打印一个连打开都打不开的文件。如果我正确理解这个Git讨论,似乎

leaflet
中的某些内容不可用,但用户需要。

与此同时,R Studio 显然有办法将此图像渲染成图像文件,让我只需按一个按钮即可完成此操作。 有没有办法自动执行此操作?如何将 R Studio 中绘制的图像导出到图像文件? 我需要图像文件,并且需要将其编程,因为我想用几百张地图制作一个

gif

或者,我欢迎提出解决方法的建议。我可能会尝试这个:Python - 将 HTML 内容渲染为 GIF 图像,但如果有人有替代建议,请分享。

r imagemagick gif r-leaflet
3个回答
13
投票

我一直在尝试结合使用

webshot
包和
saveWidget
中的
htmltools
来做到这一点,尽管速度相当慢。 对于几百张地图来说,如果你只是到处做,那可能还不错。 但是,对于实时应用来说它太慢了。

此工作流程需要两个外部应用程序。

webshot
会截取网页截图,并要求您首先安装 PhantomJS(它很小且简单)。 我还使用 ImageMagick(并且需要从命令行访问)来创建
.gif
文件,但我确信还有许多其他程序可以用来制作 gif。

这个想法只是在循环中创建地图,使用

saveWidget
将它们保存到临时 html 文件中,然后使用
webshot
将其转换为 png (慢)。 然后,一旦您拥有所有 png,请使用 ImageMagick 将它们转换为 gif(快速)。

这是一个例子,我也加载了

ggmap
,但只是为了获得一个放大的位置。

library(webshot)
library(leaflet)
library(htmlwidgets)
library(ggmap)

loc <- geocode('mt everest')  # zoom in everest
zooms <- seq(2,14,3)          # some zoom levels to animate

## Make the maps, this will make some pngs called 'Rplot%02d.png'
## in your current directory
for (i in seq_along(zooms)) {
    m <- leaflet(data=loc) %>%
      addProviderTiles('Esri.WorldImagery') %>%
      setView(lng=loc$lon, lat=loc$lat, zoom=zooms[i])
    if (i==1)
        m <- m %>% addPopups(popup="Going to see Mt Everest")
    if (i==length(zooms))
       m <- m %>%
          addCircleMarkers(radius=90, opacity = 0.5) %>%
          addPopups(popup = 'Mt Everest')

    ## This is the png creation part
    saveWidget(m, 'temp.html', selfcontained = FALSE)
    webshot('temp.html', file=sprintf('Rplot%02d.png', i),
            cliprect = 'viewport')
}

然后,它只是将 png 转换为 gif。 我在 Windows 上执行此操作,因此命令在 mac/linux 上可能略有不同(我认为只是单引号而不是双引号或其他东西)。 这些命令来自命令行/shell,但您也可以使用

system
/
system2
从 R 调用或尝试使用
animation
包,其中包含 ImageMagick 的一些包装函数。 制作一个没有什么花哨的简单 gif 很简单,
convert *.png animation.gif
。 我使用了稍长的代码来使 png 更小/添加一些延迟/并使序列进出。

convert Rplot%02d.png[1-5] -duplicate 1,-2-1, -resize "%50" gif:- | convert - -set delay "%[fx:(t==0||t==4)?240:40]" -quiet -layers OptimizePlus -loop 0 cycle.gif

enter image description here


2
投票

您可以创建一系列 PNG 文件,如 jenesaisquoi (第一个答案)所回答的那样。然后使用以下代码和 magick 包使用 png 文件创建 gif。

library(magick)

    png.files <- sprintf("Rplot%02d.png", 1:20) #Mention the number of files to read
GIF.convert <- function(x, output = "animation.gif")#Create a function to read, animate and convert the files to gif
        {
        image_read(x) %>%
        image_animate(fps = 1) %>%
        image_write(output)
        }

        GIF.convert(png.files)

您不需要在PC上安装ImageMagick软件。

代码链接:Animation.R


1
投票

我有一个包含 3 列的表格:纬度、经度、日期(376 天)。

过程是:创建地图 -> 将地图另存为 HTML -> 将地图另存为 PNG -> 导入图片 -> 绘制它(使用plot + ggimage)

所有这个过程,都会循环进行

library(leaflet)
library(animation)
library(png)
library(htmlwidgets)
library(webshot)
library(ggmap)

saveGIF({
for (i in 1:376) {
  map  = leaflet() %>%
    addTiles() %>%
    setView(lng = lon_lat[1,2], lat = lon_lat[1,1], zoom = 5)%>%
    addMarkers(lng = lon_lat[lon_lat$day == i,2],lat = lon_lat[lon_lat$day == i,1])

  saveWidget(map, 'temp.html', selfcontained = FALSE) ## save the html
  webshot('temp.html', file=sprintf('Rplot%02d.png', 1),cliprect = 'viewport') ## save as png
  img = readPNG("Rplot01.png") ### read the png
  plot(ggimage(img)) ###reading png file
}
})
© www.soinside.com 2019 - 2024. All rights reserved.