When I run the code below in an R markdown file, all the pixels of the map are properly displayed at all zoom levels. However, when I save the map as a widget and I open the html file at any zoom level there are diagonal lines of missing pixels [ see attached picture ].
How can I correct this?
library(leaflet); library(htmlwidgets)
Map <- leaflet() %>% addProviderTiles("CartoDB.Positron")
saveWidget(Map, file = "file path/Map.html")
Unfortunately, I struggle to show a reproducible example here. The issue occurs only, when I add a locally saved raster file (140mb) to a leaflet map. And I don't know how to share such a large file here. The map shows fine in the rStudio viewer and in Chrome. But it fails to show the raster in Firefox and Safari (Firefox on OSX and iOS). Even auto zoom and pan does not work.
When I add a system raster file, everything works as expected:
library(leaflet)
library(leafem)
library(raster)
library(stars) #to access the stars system.file
tif = system.file("tif/L7_ETMs.tif", package = "stars")
x2 <- raster(tif)
map_raster <- leaflet() %>%
addTiles() %>%
leafem:::addGeoRaster(
x2,
opacity = 1,
colorOptions = colorOptions(
palette = grey.colors(256)
)
)
library(htmlwidgets)
saveWidget(map_raster, file = "TestExport_raster.html", selfcontained = T)
But when I replace x2 with the local raster, it does not work. Tried adding an object from the raster and the stars package, but with no difference.
Any help on that? Is the raster just too big for a leaflet-map?
The question might be related to this one:
saving R leaflet map as html: tiles not included
Best,
Beni
I am new here and wanted help to figure out how to call a Google Maps base layer using the Google Maps API in a Leaflet map in R. Here's what I have learnt till now:
Pavel Shramov's Leaflet plugins allow Google's base maps to be called from inside Leaflet JS, in a manner that is, from what I understand, compliant with Google's ToS. An example of this is available here, which works quite well.
There are general instructions on using arbitrary Leaflet JS plugins in Leaflet for R via htmltools and htmlwidgets.
Based on the above, I understand that my code in R will need to look somewhat as follows, but I can't get a Google basemap to load:
library(leaflet)
library(htmltools)
library(htmlwidgets)
# 1: Tell htmlwidgets where to look for the script and stylesheets
gLeafletPlugin <- htmlDependency("gLeaflet","1.9.0",
src = c(href = "https://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/1.9.0/layer/tile/"),
script = "Google.js")
# FIRST PLACE WHERE I AM STUCK: I am pretty sure, I also need to pass on
# the Google Maps API script reference before or along with the above command,
# but trying to include two htmlDependency objects together in a list, did not
# work. Maybe I wasn't doing it right.
# 2: Make a map and add the htmlDependency object to it
registerPlugin <- function(map, plugin) {
map$dependencies <- c(map$dependencies, list(plugin))
map
}
leaflet() %>%
setView(76.65, 12.32, zoom = 9) %>%
registerPlugin(gLeafletPlugin) %>%
# 3: Pass on custom JS logic: SECOND PLACE WHERE I AM STUCK
onRender("function(el, x) {
L.Google('TERRAIN').addTo(this);
}")
Would be grateful if someone could show me: (a) the correct way of registering the htmlDependency, when more than one script is involved; and (b) the correct syntax to call the extra JS logic needed to display a Google Terrain basemap.
Thanks!
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
}
})
I am using d3heatmap package in R for to draw heatmaps. When I use it in Rstudio, I can save images that it produces by choosing save image from the viewer menu. I am wondering how I can save the heatmap to a file in an Rscript. Apparently, png(filename) does not work.
A potential approach is using htmlwidgets and save it in html form only since the d3heatmap returns object of class "d3heatmap" "htmlwidget"
EG.
library(htmlwidgets)
data(mtcars)
map <- d3heatmap(mtcars, scale = "column")
saveWidget(map, "test.html")