29 Embedding images

There are a few ways to embed images in a plotly graph. Perhaps the easiest is to point the image source to a hyperlink containing a bitmap file (e.g., png, jpeg, tiff, etc).

plot_ly() %>%
  layout(
    images = list(
      source = "https://www.rstudio.com/wp-content/uploads/2018/10/RStudio-Logo-Flat.png",
      x = 0, y = 1, 
      sizex = 0.2, sizey = 0.1,
      xref = "paper", yref = "paper", 
      xanchor = "left", yanchor = "bottom"
    ),
    margin = list(t = 50)
  )
Embedding an image using a hyperlink. This example uses paper coordinates (i.e., normalized 0-1 scale relative to the graph area) to place the image just above the graph.

FIGURE 29.1: Embedding an image using a hyperlink. This example uses paper coordinates (i.e., normalized 0-1 scale relative to the graph area) to place the image just above the graph.

The approach in Figure 29.1 has a downside though – if that hyperlink breaks, then so does your plot. It’d be better to download the file to your machine and use the dataURI() function from the base64enc package (or similar) to embed the image as a data URI (Urbanek 2015).

plot_ly() %>%
  layout(
    images = list(
      source = base64enc::dataURI(file = "images/rstudio.png"),
      x = 0, y = 1, 
      sizex = 0.2, sizey = 0.1,
      xref = "paper", yref = "paper", 
      xanchor = "left", yanchor = "bottom"
    ),
    margin = list(t = 50)
  )
Embedding an image using a data URI. This approach ensures your image stays embedded in the plot.

FIGURE 29.2: Embedding an image using a data URI. This approach ensures your image stays embedded in the plot.

Another approach is to convert a raster object into a data URI, which the raster2uri() function in plotly is designed to do. R actually ships with native support for raster objects and many image processing R packages either build on this data structure or provide a utility to convert to a raster object (perhaps via as.raster()). For example, the readPNG() function from the png package reads image data in an R array, which can be converted to a raster object (Urbanek 2013).

pen <- png::readPNG("images/penguin.png")

plot_ly() %>%
  layout(
    images = list(
      source = raster2uri(as.raster(pen)),
      x = 2, y = 2, 
      sizex = 2, sizey = 1,
      xref = "x", yref = "y",
      xanchor = "left", yanchor = "bottom",
      sizing = "stretch"
    )
  )
Reading a png image into R with png::readPNG(), converting the RBGA array into a raster object, generating a data URI of the raster via raster2uri(), then embedding the URI as an image in a plotly graph.

FIGURE 29.3: Reading a png image into R with png::readPNG(), converting the RBGA array into a raster object, generating a data URI of the raster via raster2uri(), then embedding the URI as an image in a plotly graph.

Moreover, thanks to the R package magick it’s possible to rasterize non-raster file formats (e.g., pdf, svg, etc) directly in R, so if you wanted, you could also embed non-bitmap images by using image_read() and image_convert() to generate a raster object (Ooms 2019).

References

Urbanek, Simon. 2015. Base64enc: Tools for Base64 Encoding. https://CRAN.R-project.org/package=base64enc.

Urbanek, Simon. 2013. Png: Read and Write Png Images. https://CRAN.R-project.org/package=png.

Ooms, Jeroen. 2019. Magick: Advanced Graphics and Image-Processing in R. https://github.com/ropensci/magick#readme.