6

I realize that this largely defeats the purpose of using an interactive leaflet map, but I'm writing a traditional paper book and I want to show how the leaflet package for R works. I'm writing the book in LaTeX and rendering with knitr. Is there a way to have a leaflet map render as a raster image such that it could be included in this book?

Here is a minimal example:

library(leaflet)
map <- leaflet() %>%
  addTiles() %>%
  addMarkers(lng = -77.03673, lat = 38.89761)

Now if I try a chunk like:

<<>>=
map
@

I get this error:

Error in validateCssUnit(sizeInfo$width): "\maxwidth" is not a valid CSS unit
(e.g., "100%", "400px", "auto")

Trying to save as a PNG doesn't work either:

<<>>=
png(filename = "test.png")
map
dev.off()
@

map doesn't inherit from ggplot, so ggsave won't work either.

Is there any way to make this work?

beanumber
  • 767
  • 5
  • 13
  • Like `dygraph`, `leaflet` is based on `htmlwidgets`. According to [this answer by Yihui](http://stackoverflow.com/a/31820519/2706569) "you cannot use any htmlwidgets-based packages in LaTeX documents". But read the comments, too; there might be workarounds. – CL. Feb 21 '16 at 14:51
  • That makes sense -- thanks for the link. The best solution I've found is to render in RStudio and then use the Export... feature and save as a PNG. – beanumber Feb 21 '16 at 18:06

1 Answers1

8

There has been a recent question on How to save Leaflet in RStudio map as png or jpg file?. If you don't mind installing PhantomJS, the code below should help you create static images from leaflet (or mapview) maps. The only thing left to do then is to not show the saveWidget and webshot code in your book and instead import and display the png file created therefrom.

## install 'webshot' package
library(devtools)
install_github("wch/webshot")

## load packages
library(leaflet)
library(htmlwidgets)
library(webshot)

## create map
m <- leaflet() %>%
  addTiles() %>%
  addMarkers(lng = -77.03673, lat = 38.89761)

## save html to png
saveWidget(m, "leaflet_map.html", selfcontained = FALSE)
webshot("leaflet_map.html", file = "leaflet_map.png",
        cliprect = "viewport")

## optionally display image when using knitr
# p <- knitr::include_graphics("leaflet_map.png")

And here is some LaTeX output for demonstration purposes. If anyone is interested, the complete .Rnw source file is available from GitHub.

LaTeX

Community
  • 1
  • 1
fdetsch
  • 5,239
  • 3
  • 30
  • 58
  • 4
    Great answer. You could add `knitr::include_graphics("leaflet_map.png")`, which is the only additional code required to use your approach in a `knitr` document. – CL. Feb 22 '16 at 11:01
  • You people are awesome. – beanumber Feb 22 '16 at 16:45
  • That's it @CL. Or use `includegraphics` (from **graphicx**) or the like directly in the LaTeX code as I've done in the source file linked above. – fdetsch Feb 23 '16 at 04:20
  • 3
    @fdetsch I'd recommend `knitr::include_graphics()`, because it is agnostic of the output format (LaTeX, Markdown, whatever). I have also been working on automating this process of snapshotting HTML widgets when the output format is not HTML. Hopefully things will be much easier in the near future. – Yihui Xie Feb 23 '16 at 05:33
  • FYI, the work has been done in the current development version of **knitr**: https://github.com/yihui/knitr/blob/master/NEWS.md – Yihui Xie Mar 17 '16 at 19:50