Reputation: 704
I want to save my interactive graph as a png, i can do it through viewer and export it as png but i've thousands of them and must take them automatically.
There's a way which is using webshot
package, but i tried this approach and it takes alot of time, because i want to save them at the same time, for example : i've 4000 html graphs generated using R and must save them as image in time interval 1 min, when i use webshot
, it takes arround 43 mins because system2
takes alot of time .
so i want to export them using function which viewer pane use, here's an image explain what i want .
Here's code as an example for interactive graph, that doesn't mean my graphs r leaflet class, i provide it as an example.
library(leaflet)
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
and here's what i'm thinking of :
function(m,"SaveAs.png")
Please i need help, i searched a lot and spent a lot of time trying to find a solution.
according to this question How to save Leaflet in R map as png or jpg file?
It differs from my question , i need generic function for any interactive graphs , there's functions for plotly
but it's only for plotly graphs,Also the question usion webshot function which using PhantomJs and i mentioned above that PhantomJS is tooooo slow also Selenium also wkhtmltoimage, i tried lots of things.
Please notice that i need generic function or at least the function that viewer is using
Upvotes: 1
Views: 3636
Reputation: 78792
The only way to capture a bitmap of htmlwidgets (like leaflet) is to load them in a browser context, capture a bit (or all) of the viewport and write that out to a file. That's an ugly round-trip process in a heavyweight browser context, marshalling data between internal DOM representations to HAR (behind the scenes) — which encodes binary bit into base64, to the browser context broker/driver, to R, them from base64 to memory or a file.
There is an additional issue where many HTML widgets saved to a file will not always load in a static file context (i.e you need a running web server). I have no idea if that's true for googleway saved widgets but it is often true for leaflet.
For the following, you'll need to:
Toy example setup to save out 5 widgets:
library(seleniumPipes)
library(leaflet)
library(purrr)
library(devd) # install_github("hrbrmstr/devd")
m <- leaflet() %>%
addTiles() %>%
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
dir.create("/tmp/pages", showWarnings = FALSE)
dir.create("/tmp/pngs", showWarnings = FALSE)
walk(1:5, ~saveWidget(m, file.path("/tmp/pages", sprintf("%x.html", .x))))
Start a selenium session and also start up a web server:
remDr <- remoteDr(browserName = "chrome", port = 4444L)
proc <- devd_start("/tmp/pages", open_browser = FALSE)
Walk through the files and take screenshots:
list.files("/tmp/pages", "*.html$", full.names = FALSE) %>%
walk(~{
print(system.time({
page_url <- sprintf("http://devd.io:8000/%s", .x)
out_file <- sprintf("/tmp/pngs/%s.png", .x)
remDr %>%
go(page_url) %>%
takeScreenshot(file=out_file)
}))
})
You get:
## user system elapsed
## 0.473 0.082 6.561
## 0.449 0.083 4.110
## 0.447 0.073 4.429
## 0.419 0.068 3.568
## 0.423 0.085 4.493
for that sequence.
It doesn't get much better if we try to just capture the pngs & turn off some takeScreenshot()
features, either:
list.files("/tmp/pages", "*.html$", full.names = FALSE) %>%
map(~{
print(system.time({
page_url <- sprintf("http://devd.io:8000/%s", .x)
out_file <- sprintf("/tmp/pngs/%s.png", .x)
remDr %>%
go(page_url) %>%
takeScreenshot(display=FALSE, useViewer=FALSE, returnPNG=TRUE)
}))
}) -> pngs
## user system elapsed
## 0.448 0.060 4.801
## 0.440 0.058 4.894
## 0.463 0.074 4.857
## 0.466 0.068 5.010
Don't forget to top the web server:
devd_stop(proc)
It is possible to speed this up by doing things in parallel, but others way be more willing to give you free consulting than I am, especially since you weren't and still aren't exactly forthcoming in your question details. The answer is mostly for others with a similar need but less entitlement.
Upvotes: 3