rshinyr-leafletr-mapview

R: saving a leaflet with white background


I am currently working on a ShinyApp, which includes maps built using sf objects and leaflet.

I found the solution to change the initial grey background of the map to a white background (by adding css style), and to save the map as png (by using webshot or mapshot).

Nevertheless, when I save the leaflet map, the grey background comes back! And I did not find the solution to save the map with its white background.

Here is a reproducible code illustrating my issue:

# Libraries
library(shiny)
library(shinyWidgets)
library(htmlwidgets)
library(tidyr)
library(sf)
library(leaflet)
library(webshot)
library(mapview)

# Spatial data
d = matrix(c(0,0,10,0,10,10,0,10,0,0), ncol = 2, byrow = TRUE) %>%
  list(.) %>% st_polygon(.) %>% st_sfc(.)

# Shiny app
shinyApp(
  ui = shinyUI(fluidPage(tags$head(tags$style(HTML("#map{ background: none; }"))),
                         leafletOutput("map"),
                         downloadBttn("save", label = ".png"))),
  
  server = function(input, output){
    # Map creation
    map = reactiveVal(NULL)
    map(leaflet(d, options = leafletOptions()) %>% addPolygons())

    # Map render
    output$map = renderLeaflet(map())
    
    # Map download
    output$save = downloadHandler(
      file = function(){return("Rplot.png")},
      content = function(file){
        # Apply the changes user made (move and zoom)
        coords = input$map_center
        zoom = input$map_zoom
        shot = map() %>% setView(lng = coords$lng, lat = coords$lat, zoom = zoom)
        
        # Save the map unsing webshot (I prefer using this method for "heavy" map, like > 10 000 polygons)
        saveWidget(shot, "temp.html", selfcontained = FALSE)
        suppressWarnings({shot = webshot("temp.html", file = file, cliprect = "viewport")})
        
        # Save using mapshot
        # suppressWarnings({shot = mapshot(shot, file = file, cliprect = "viewport")})

        shot
      }
    )
  }
)

Have you any idea ?

I tried different css background styles ("none", "white", "#fff") and different way to save the leaflet map (mapshot, webshot), but nothing worked for me.


Solution

  • We can use leaflet.extras::setMapWidgetStyle to set the background color:

    # Libraries
    library(shiny)
    library(shinyWidgets)
    library(htmlwidgets)
    library(tidyr)
    library(sf)
    library(leaflet)
    library(webshot)
    library(mapview)
    library(leaflet.extras)
    
    # Spatial data
    d = matrix(c(0,0,10,0,10,10,0,10,0,0), ncol = 2, byrow = TRUE) %>%
      list(.) %>% st_polygon(.) %>% st_sfc(.)
    
    # Shiny app
    shinyApp(
      ui = shinyUI(fluidPage(
        # tags$head(tags$style(HTML("#map{ background: none; }"))),
                             leafletOutput("map"),
                             downloadBttn("save", label = ".png"))),
      
      server = function(input, output){
        # Map creation
        map = reactiveVal(NULL)
        map(leaflet(d, options = leafletOptions()) %>% addPolygons() %>%
              setMapWidgetStyle(list(background = "white")))
        
        # Map render
        output$map = renderLeaflet(map())
        
        # Map download
        output$save = downloadHandler(
          file = function(){return("Rplot.png")},
          content = function(file){
            # Apply the changes user made (move and zoom)
            coords = input$map_center
            zoom = input$map_zoom
            shot = map() %>% setView(lng = coords$lng, lat = coords$lat, zoom = zoom)
            
            # Save the map unsing webshot (I prefer using this method for "heavy" map, like > 10 000 polygons)
            saveWidget(shot, "temp.html", selfcontained = FALSE)
            suppressWarnings({shot = webshot("temp.html", file = file, cliprect = "viewport")})
            
            # Save using mapshot
            # suppressWarnings({shot = mapshot(shot, file = file, cliprect = "viewport")})
            
            shot
          }
        )
      }
    )