Skip to content

Support nativeRaster in annotation_raster #3388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kent37 opened this issue Jul 2, 2019 · 2 comments
Closed

Support nativeRaster in annotation_raster #3388

kent37 opened this issue Jul 2, 2019 · 2 comments
Labels
feature a feature request or enhancement layers 📈 tidy-dev-day 🤓 Tidyverse Developer Day

Comments

@kent37
Copy link
Contributor

kent37 commented Jul 2, 2019

annotation_raster can be quite slow to display a large image. The current implementation converts the numeric image to text (via grDevices::as.raster) which must be converted back to numeric values for actual drawing by grid::rasterGrob. Supporting nativeRaster removes this round-trip conversion and dramatically speeds rendering.

This reprex uses a modified annotation_raster_native to demonstrate the improvement. A ggplot2 implementation could simply skip the as.raster call in annotation_raster if the incoming raster object inherits from nativeRaster. No changes are needed in GeomRasterAnn because grid::rasterGrob, which it uses, works with nativeRaster objects.

library(ggplot2)

# Image from https://github.com/akoyabio/phenoptrExamples/blob/master/inst/extdata/samples/Set12_20-6plex_%5B14146%2C53503%5D_composite_image.jpg
path = "Set12_20-6plex_[14146,53503]_composite_image.jpg"
image = jpeg::readJPEG(path)
dim(image) # 1400 x 1868

# This takes about 4 seconds to display the plot in RStudio on my computer
print(ggplot() + annotation_raster(image,
                                 xmin=0, xmax=1,
                                 ymin=0, ymax=1))

image2 = jpeg::readJPEG(path, native=TRUE)

# annotation_raster without the grDevices::as.raster conversion
annotation_raster_native <- function(raster, xmin, xmax, ymin, ymax,
                              interpolate = FALSE) {
  layer(
    data = ggplot2:::dummy_data(),
    mapping = NULL,
    stat = StatIdentity,
    position = PositionIdentity,
    geom = GeomRasterAnn,
    inherit.aes = FALSE,
    params = list(
      raster = raster,
      xmin = xmin,
      xmax = xmax,
      ymin = ymin,
      ymax = ymax,
      interpolate = interpolate
    )
  )
}

# This version takes less than two seconds to display.
print(ggplot() + annotation_raster_native(image2,
                                   xmin=0, xmax=1,
                                   ymin=0, ymax=1))
@paleolimbot
Copy link
Member

This sounds easy and quite reasonable to me. For reference, it would just mean wrapping the call to grDevices::as.raster() in a conditional.

annotation_raster <- function(raster, xmin, xmax, ymin, ymax,
interpolate = FALSE) {
raster <- grDevices::as.raster(raster)
layer(

@paleolimbot paleolimbot added feature a feature request or enhancement layers 📈 labels Jul 22, 2019
@AB-Kent
Copy link

AB-Kent commented Jul 22, 2019

Yes, thank you @paleolimbot for getting the essence of my wordy request. If line 42 of annotation-raaster.r is changed to this:

if (!inherits(raster, 'nativeRaster'))
  raster <- grDevices::as.raster(raster)

then reading raster images using native=TRUE and rendering them with annotation_raster will be significantly faster than the current approach.

@thomasp85 thomasp85 added the tidy-dev-day 🤓 Tidyverse Developer Day label Jan 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement layers 📈 tidy-dev-day 🤓 Tidyverse Developer Day
Projects
None yet
Development

No branches or pull requests

4 participants