Skip to content
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

Incompatibility with tidyterra plotting #159

Open
JsLth opened this issue Mar 7, 2025 · 1 comment
Open

Incompatibility with tidyterra plotting #159

JsLth opened this issue Mar 7, 2025 · 1 comment

Comments

@JsLth
Copy link

JsLth commented Mar 7, 2025

terra rasters stored using geotargets::tar_terra_rast signal an external pointer is not valid when used in a ggplot using tidyterra::geom_spatraster. This does not happen when simply accessing the SpatRaster object or when plotting it through terra::plot. See the minimal example below.

res <- tar_dir({
  tar_script({
    library(geotargets)
    
    tar_option_set(packages = c("terra", "ggplot2", "tidyterra", "magick"))
    
    list(
      tar_terra_rast(
        name = rastex,
        command = rast(data.frame(x = c(1, 2), y = c(3, 4), z = c(100, 200)))
      ),
      
      tar_target(
        name = rastex_plot,
        command = ggplot() +
          geom_spatraster(data = rastex)
      ),
      
      tar_target(
        name = plot_rastex_base,
        command = {
          png(tempf <- tempfile(fileext = ".png"))
          plot(rastex)
          dev.off()
          image_ggplot(image_read(tempf))
        }
      )
    )
  })
  
  tar_make()
  list(
    tar_read(rastex),
    tar_read(rastex_plot),
    tar_read(plot_rastex_base)
  )
})

res[[1]]
#> class       : SpatRaster 
#> dimensions  : 2, 2, 1  (nrow, ncol, nlyr)
#> resolution  : 1, 1  (x, y)
#> extent      : 0.5, 2.5, 2.5, 4.5  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84) 
#> source      : rastex 
#> name        :   z 
#> min value   : 100 
#> max value   : 200

res[[2]]
#> Warning message:
#> Computation failed in `stat_terra_spat_raster()`.
#> Caused by error:
#> ! external pointer is not valid

res[[3]]

Image

Relevant package versions:

pkg <- c("tidyterra", "targets", "geotargets", "ggplot2")
lapply(setNames(pkg, pkg), packageVersion)
#> $tidyterra
#> [1] ‘0.7.0’
#> 
#> $targets
#> [1] ‘1.10.1’
#> 
#> $geotargets
#> [1] ‘0.2.0.9000’
#> 
#> $ggplot2
#> [1] ‘3.5.1’
@Aariq
Copy link
Collaborator

Aariq commented Mar 7, 2025

Thanks, I'm aware of this. tar_read(rastex) works in your example because the rastex target was created with tar_terra_rast() and there is currently no equivalent target constructor for these special ggplot objects created with geom_spatraster(). I'm fairly certain this is due to the same issue that necessitates tar_terra_rast() for use with SpatRasters—the ggplot object must contain an a pointer to memory that only is valid in the R session it was created in.

We might consider a tar_*() function to handle this, but I suspect marshalling and unmarshalling the ggplot object will be a lot trickier. What I've done in my own workflows is created targets that save plots out to a file and used format = "file". You might also have success with pulling the data out in one target with tidyterra::as_tibble() and then plotting with geom_raster() in a downstream target. You may want to re-project high resolution rasters to a managable resolution before converting to a tibble though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants