rggplot2terrarstoolbox

ggRGB unable to plot masked image using RStoolbox R package


ggRGB unable to plot the masked image. Here is a minimal, reproducible example

library(terra)
library(ggplot2)
library(RStoolbox)

lsat

plotRGB(lsat,
        r = 3,
        g = 2,
        b = 1,
        stretch = 'hist')

m <- draw(x="polygon", n = 5)

lsat.masked <- crop(lsat, m, mask = T)

ggplot() + ggRGB(img = lsat.masked,
                 r = 3,
                 g = 2,
                 b = 1,
                 stretch = 'hist',
                 ggLayer = T)

enter image description here

It returns the following error

Error in grid.Call.graphics(C_raster, x$raster, x$x, x$y, x$width, x$height, : cannot allocate memory block of size 67108864 Tb In addition: Warning message: In matrix(z, nrow = nrow(rr), ncol = ncol(rr), byrow = TRUE) : data length [5888] is not a sub-multiple or multiple of the number of rows [88]


Solution

  • This is an incomplete answer as I was not able to find the issue in ggRGB, but you can consider using the tidyterra package instead, see a reprex:

    library(terra)
    #> terra 1.8.5
    library(ggplot2)
    library(RStoolbox)
    #> This is version 1.0.0 of RStoolbox
    
    lsat
    
    plotRGB(lsat, r = 3, g = 2, b = 1, stretch = "hist")
    
    
    # SpatVector as standalone object
    
    m <- structure(list(geom = "POLYGON ((620947.959184 -412745.345369, 621312.951334 -414249.11303, 623254.709576 -414526.507064, 623897.095761 -413154.136578, 621152.354788 -411767.166405, 620947.959184 -412745.345369))"),
      class = "data.frame",
      row.names = c(NA, -1L)
    )
    
    # To SpatVector with the right CRS
    m <- vect(m$geom)
    crs(m) <- crs(lsat)
    
    
    plot(m, add = TRUE, col = "red")
    

    lsat.masked <- crop(lsat, m, mask = T)
    
    plotRGB(lsat.masked, r = 3, g = 2, b = 1, stretch = "hist")
    

    ggplot() +
      ggRGB(
        img = lsat.masked,
        r = 3,
        g = 2,
        b = 1,
        stretch = "hist",
        ggLayer = T
      )
    #> Warning in matrix(z, nrow = nrow(rr), ncol = ncol(rr), byrow = TRUE): data
    #> length [5793] is not a sub-multiple or multiple of the number of rows [92]
    #> Error in grid.Call.graphics(C_raster, x$raster, x$x, x$y, x$width, x$height, : cannot allocate memory block of size 67108864 Tb
    

    With tidyterra you just need to perform the stretching outside the plotting function and then apply geom_spatraster_rgb:

    # Alternative with tidyterra
    library(tidyterra)
    #> 
    #> Adjuntando el paquete: 'tidyterra'
    #> The following object is masked from 'package:stats':
    #> 
    #>     filter
    
    # Strecth as standalone fun, equivalent to plotRGB(..., stretch = "hist")
    
    lsat.masked_st <- stretch(lsat.masked, histeq = TRUE, scale = 255)
    
    ggplot() +
      geom_spatraster_rgb(data = lsat.masked_st, r = 3, g = 2, b = 1) +
      geom_spatvector(data = m, color = "red", fill = NA, linewidth = 3)
    

    plot with tidyterra

    Created on 2025-01-05 with reprex v2.1.1