With the following code one can generate a leaflet map:
library(leaflet)
library(mapview)
library(dplyr)
library(sf)
bbox <- st_bbox(my_polygon)
print(bbox)
xmin ymin xmax ymax
-0.5509286 39.4419540 -0.4397764 39.4779036
poly <- st_as_sfc(bbox, crs = 4326)
leaflet() %>%
addTiles() %>%
addPolygons(data = poly, opacity = 1, fillOpacity = 1, fillColor = 'red') %>%
mapshot(file = 'example.png', vwidth = 9256, vheight = 6600)
However, when viewing the image, you can tell there's a lot of "blank space" (see current output)
No matter what I try (e.g: setMaxBounds, fitBounds, a bunch of onRender combinations I've seen over here, etc) the map's zoom won't be adjusted properly, and what do I mean by "properly adjusted"?, what the actual aforementioned functions (setMaxBounds and fitBounds) should do (see desired output).
And yes, the image is required to be that large.
Leaflet has a parameter called zoomSnap = 1 = which is the amount by which you can zoom by one scroll operation. Typically, you can zoom from 0 (all zoomed out) to 20. In this case, your leaflet widget becomes very large though, because you basically force the browser into the dimension 9256px * 3966px. So a zoomSnap of 1 is just too much - the gap becomes to wide. To still keep the polygon in frame leaflet has to choose a smaller zoomLevel. So my thought was, to set zoomSnap down. This worked, but mapshot() was still capturing the wrong image. I changed to mapshot2 which fixed this issue. Simplified: mapshot uses webshot under the hood, it basically generates a leaflet widget, opens it in a browser, sets the window size and then takes an image of a specific DOM-element; in this case the map. You have to keep this in mind, when working with it. fitBounds does not quite work as expected. It flies you to the mean of lon/lat, and sets the zoom level in a range that keeps the given bounds visible.
Note: The smaller you set zoomSnap, the narrower the edge will become.
# R version 4.5.1 (2025-06-13 ucrt)
library(leaflet) # leaflet_2.2.3
library(mapview) # mapview_2.11.4
library(sf) # sf_1.0-21
bb <- sf::st_bbox(c(xmin = -0.5509286, xmax = -0.4397764, ymin = 39.4419540, ymax = 39.4779036))
poly <- sf::st_as_sfc(bb)
leaflet(options = leafletOptions(zoomSnap = 0.25)) |>
addTiles() |>
addPolygons(data = poly, opacity = 1, fillOpacity = 1, fillColor = 'red') |>
mapshot2(file = 'mapshot.png', vwidth = 9256, vheight = 3966)
## Alternatively use webshot directly
p <- leaflet(options = leafletOptions(zoomSnap = 0.25)) |>
addTiles() |>
addPolygons(data = poly, opacity = 1, fillOpacity = 1, fillColor = 'red')
temp <- tempfile(fileext = ".html")
htmlwidgets::saveWidget(p, temp)
webshot2::webshot(url = paste0("file://", temp),
file = "webshot.png",
selector = ".leaflet",
vwidth = 9256,
vheight = 3966)
unlink(temp)