Leaflet: Is it possible to add more complex objects like ggplots?

Created on 26 Mar 2015  路  7Comments  路  Source: rstudio/leaflet

Is it possible to add more complex objects like ggplots?
For example I might have a data.frame with columns lat, long, x, y:

lat, long, x, y
40, 5, 1, 6
40, 5, 2, 8
40, 5, 5, 3
41, 7, 3, 9
41, 7, 7, 10
41, 7, 9, 13

and I would like to build two ggplots(...) + geom_line(...) - one for 40, 5 and one for 41, 7 - which are printed as embetted graphs on their respective coordinates, namely 40, 5 and 41, 7.

Would that be possible and if so, how?
If not, what would be an option? (E.g. a different package instead of rstudio/leaflet or a different package instead of ggplot2.)

Most helpful comment

It's possible now. The trickiest part is encoding the plot as a data URI; I've provided a makePlotURI function to help you with that here.

library(leaflet)
library(ggplot2)

makePlotURI <- function(expr, width, height, ...) {
  pngFile <- plotPNG(function() { expr }, width = width, height = height, ...)
  on.exit(unlink(pngFile))

  base64 <- httpuv::rawToBase64(readBin(pngFile, raw(1), file.size(pngFile)))
  paste0("data:image/png;base64,", base64)
}

plot1 <- makePlotURI({
  print(ggplot(cars, aes(speed, dist)) + geom_point())
}, 200, 200, bg = "transparent")

plot2 <- makePlotURI({
  print(ggplot(cars, aes(speed, dist)) + geom_point())
}, 200, 200, bg = "transparent")

df <- data.frame(
  lat = c(40, 41),
  lng = c(5, 7),
  plots = c(plot1, plot2),
  stringsAsFactors = FALSE
)

leaflet(df) %>% addTiles() %>%
  addMarkers(icon = ~icons(plots))

All 7 comments

It is certainly possible, although not straightforward at the moment. Hopefully it will become easier after we merge #48.

That'd be great! What is the timeline for that - if there is?

In the meantime: How would I do this until then? An example would be great.

Hopefully by the end of next week. Examples will be given when this feature is ready.

How is the status? Could you provide a link to the examples?

How is this going? How is the status? Link to examples?

It's possible now. The trickiest part is encoding the plot as a data URI; I've provided a makePlotURI function to help you with that here.

library(leaflet)
library(ggplot2)

makePlotURI <- function(expr, width, height, ...) {
  pngFile <- plotPNG(function() { expr }, width = width, height = height, ...)
  on.exit(unlink(pngFile))

  base64 <- httpuv::rawToBase64(readBin(pngFile, raw(1), file.size(pngFile)))
  paste0("data:image/png;base64,", base64)
}

plot1 <- makePlotURI({
  print(ggplot(cars, aes(speed, dist)) + geom_point())
}, 200, 200, bg = "transparent")

plot2 <- makePlotURI({
  print(ggplot(cars, aes(speed, dist)) + geom_point())
}, 200, 200, bg = "transparent")

df <- data.frame(
  lat = c(40, 41),
  lng = c(5, 7),
  plots = c(plot1, plot2),
  stringsAsFactors = FALSE
)

leaflet(df) %>% addTiles() %>%
  addMarkers(icon = ~icons(plots))

very nice example @jcheng5. It might be helpful to add library(shiny) for plotPNG. Thanks for posting this.

Was this page helpful?
0 / 5 - 0 ratings