Create a gif from a series of Leaflet maps in R - r

I am looking for an automated method to convert leaflet R Studio plots into image files.
Seems like exporting a leaflet widget to HTML is straightforward (Saving leaflet output as html). However I cannot find any answers or docs about how to save the image produced by a leaflet widget as an image. It seems strange that I can do this manually in R Studio but that there isn't some function within R Studio that can be called to do the same thing.
I've tried the usual suspects, variations on the following:
png("test_png.png")
map
dev.off()
But these all just print white or print a file that can't even be opened. IF I understand this Git discussion correctly, seems like something in leaflet is not available but is desired by users.
In the meantime, R Studio clearly has a way to render this image into an image file, making me press a button to do it. Is there a way to automate this? How can I export the images plotted in R Studio to image files? I need image files and I need this to be programmatic because I want to make a gif out of a few hundred maps.
Alternately, I'd welcome suggestions for a workaround. I might try this: Python - render HTML content to GIF image but if someone has alternatibve suggestions, please share.

I've been trying to do this with a combination of the webshot package and saveWidget from htmltools, although it's pretty slow. For a few hundred maps, it's probably not too bad if you're only doing it here and there. But, for real-time application it is too slow.
There are two external applications you need for this workflow. webshot takes screenshots of webpages and requires you to install PhantomJS first (it's tiny and easy). I also use ImageMagick (and needs to be accessible from the command line) to create the .gif files, but I'm sure there many other programs you could use to make gifs.
The idea is just to create the maps in a loop, save them to a temporary html file with saveWidget and use webshot to turn it into a png (slow). Then, once you have all the pngs, use ImageMagick to convert them to a gif (fast).
Here is an example, I also load ggmap, but only to get a location to zoom in on.
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')
}
Then, it is just converting pngs to gif. I did this on a Windows, so command might be slightly different on a mac/linux (I think just single quotes instead of double quotes or something). These commands are from a command line/shell, but you could also use system/system2 to call from R or try the animation package that has some wrapper functions for ImageMagick. To make a simle gif with nothing fancy is simply, convert *.png animation.gif. I used a slightly longer code to make the pngs smaller/add some delays/and have the sequence go in and out.
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

You can create a series of PNG files as answered by jenesaisquoi (first answer). Then create gif with the png files using the below code with magick package.
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)
You don't require to install ImageMagick software on PC.
Code Link: Animation.R

I have table with 3 columns: lat,lon,day (376 days).
The process is: create the map -> save the map as HTML -> save the map as PNG -> import the pic -> plot it (with plot + ggimage)
All this process, will be in a loop
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
}
})

Related

How do I save a wordcloud as a .png using the wordcloud2 package in r?

I've created a wordcloud using the 'wordcloud2' package in r and I want to save the output as a .png (or really any image file). I know that I can just save the initial output as a .png and use that, but the data that the wordcloud uses changes every time the document is knit (the data is tweets gathered using the rtweet::search_tweet function), and I want the wordcloud to be updated with the same info.
I've tried using the webshot & htmlwidget packages to save the wordcloud as .png, but I always get a blank image. I've even changed the delay to 120 seconds to make sure that I gave the wordcloud enough time to load properly. The original wordcloud output is ~1.6 MB if the size might be a problem.
Here's my code:
library(wordcloud2)
library(webshot)
library(htmlwidgets)
Bcloud <-
wordcloud2(wordFreq,
size = 1,
figPath = "images/#Bv2.png",
color = colorVec)
Bcloud
#
saveWidget(Bcloud, "tmp.html", selfcontained = F)
webshot("tmp.html", "wordcloud.png", delay = 120, vwidth = 2000, vheight = 2000)
UPDATE: I removed figPath = "images/#Bv2.png" and changed the shape to one of the standard options (star, triangle, diamond, etc.) and now the wordcloud saves as a .png using saveWidget() and webshot(). I guess the issue is with the mask. The image I'm using for the mask is 13.1 KB.

Reading PDF plots, arranging them on a grid, save in one-page PDF using R

I have 3 R plots saved as pdf files (upper_left.pdf, upper_right.pdf, lower.pdf) as vector graphic and want to make a one-page pdf file and arrange them on it as follows:
What I have tried already
I have tried reading the pdf's using magick::image_read_pdf and appending them using magick::image_append. More specifically,
library(magick)
panel.ul <- image_read_pdf("upper_left.pdf")
panel.ur <- image_read_pdf("upper_right.pdf")
panel.l <- image_read_pdf("lower.pdf")
whole <- c(panel.ul, panel.ur) %>%
image_append() %>%
c(panel.l) %>%
image_append(stack = TRUE)
The first issue is magick::image_read_pdf imports the plot as png (if I'm right, not vector graphic though).
magick::image_append also 'works' and gives me what I want in viewer pane (in RStudio, next to Help).
I then try to save them using export::graph2pdf(whole), but it gives me a blank page.
So, if I am to use magick, there are two issues that need to be solved:
importing plots as vector graphic objects (do not know the technical term in R)
Exporting the stacked plot to a vector pdf file.
How can I solve it? thanks in advance.
You're basically done. You only need to add
plot(whole) # plot the external object generated in ImageMagick to R's plotting device
savePlot(type = "pdf") # saves the current plotting device to a pdf file.
You will find your plot in your workoing directory called "Rplot.pdf".
savePlot has many options to customize your pdf output. Make sure to check ?savePlot.
To recreate your scheme from above youll need to temporarily save the upper panel as a separate pdf before you paste it to on top of the lower panel:
whole2 <- image_append(c(panel.ul, panel.ur))
plot(whole2)
savePlot("whole2.pdf", type = "pdf")
If the upper and lower panel do not look proportionate you can use the heght and width parameters of savePlot to adjust the size of the first pdf.
panel.upr <- image_read_pdf("whole2.pdf")
final <- image_append(c(image_append(panel.upr),panel.l), stack = TRUE)
plot(final)
savePlot("final.pdf", type = "pdf")

reading images in r program

I want to read 12 images at a time in R.
I don't know how to do it. I am complete new to working on images in R.
How can I read couple of images from a folder in my system?
I am using windows10 operating system. RAM 8 gb. CORE i5 processor.
GPU is Intel(R) HD Graphics 620.
I am able to read only single image in R and that image is displaying as numeric values. I tried to convert it into raster format and then tried to print image to view the image. But I am still finding the color codes in values but not the image in print.
Can anyone help me on this?
Thanks a lot.
install.packages("magick")
library(magick)
install.packages("rsvg")
install.packages("jpeg")
library(jpeg)
img <- readJPEG("C:/Users/folder/Abc.jpg", native = FALSE)
img1 <- as.raster(img, interpolate = F)
print(img1)
I want to read couple of images at a time into R console and want to view or print images.
The suggested duplicate gives you the basics for how to read in a number of files at once, but there are a few potential gotchas, and it won't help you with displaying the images.
This first bit is purely to set up the example
library(jpeg)
library(grid)
# Create a new directory and move to it
tdir <- "jpgtest"
dir.create(tdir)
setwd(tdir)
# Copy the package:jpeg test image twice, once as .jpg and once as .jpeg
# to the present working directory
file.copy(system.file("img", "Rlogo.jpg", package="jpeg"),
to=c(file.path(getwd(), "test.jpg"), file.path(getwd(), "test.jpeg")))
Then we can list the files, either using a regex match, or choose them interactively, then read and store the images in a list.
# Matches any file ending in .jpg or .jpeg
(flist <- list.files(pattern="*\\.jp[e]?g$"))
# Interactive selection
flist <- file.choose()
jpglist <- lapply(flist, readJPEG)
To display the images I tend to use grid, but there are a number of alternatives.
grid.raster(jpglist[[1]], interpolate=FALSE)
Remove temporary directory
setwd("..")
unlink(tdir)

Very confused about how to merge two images to create a gif

I have looked at previous posts. Especially this one. I see the code is this
library(animation)
## make sure ImageMagick has been installed in your system
saveGIF({
for (i in 1:10) plot(runif(10), ylim = 0:1)
})
I installed ImageMagick (after much confusion).
I ran the above code, and do not see anything happening? I have two images on my computer saved in a file. I want to combine them to create a short gif. How do I go about doing this? What portion of the above code combines multiple images that are saved on my computer? How do I go about doing this using the animation library and imagemagick?
I am running into a wall here. Any help will be greatly appreciated.
You can do it using ImageMagick, as follows:
install.packages("magick")
library(magick)
list.files(path = "<<path to your images>>", pattern = "*.png", full.names = T) %>%
image_read %>% # reads each image file
image_join() %>% # joins image
image_animate(fps=2) %>% # animates, can opt for number of loops
image_write("merged_pngs.gif")
Hope it helps.

Print a Googlevis chart to pdf in R

I created a shiny app and now i want to plot a chart to pdf. So, is there any way to print a googlevis Chart to pdf in R.
I know its not possible directly, as stated in the help pages. But is there a way to print a static image (similar to a screenshot)? If possible without sweave/knitr?
Thank you in advance
You can do this using wkhtmltopdf, which you need to install and possibly add to your system path. I have got this working for other googlevis objects, where in some cases I did not need the --enable-javascript --javascript-delay option....
output$downloadmap <- downloadHandler("mymap.pdf" ,
content = function(file) {
#print gmap googlevis R object to a html file
print(gmap, file="gmap.html")
#call to wkhtmltopdf installed on server/pc to convert html file to pdf.
#add a delay otherwise (i got an) empty plot
system("wkhtmltopdf --enable-javascript --javascript-delay 2000 gmap.html gmap.pdf")
#copy pdf file to output
file.copy("gmap.pdf", file)
#remove created files from local storage
file.remove("gmap.pdf")
file.remove("gmap.html")
}
)

Resources