Search code examples
rggplot2terratidyterra

pretty_breaks not working with geom_spatraster


I am trying to use scales::pretty_breaks with geom_spatraster like

library(terra)
library(ggplot2)
library(tidyterra)

r1 <- rast(system.file("ex/elev.tif", package="terra"))
r2 <- r1 

r <- c(r1, r2)

names(r) <- c("R1", "R2")

p <- ggplot() +
  geom_spatraster(data = r) +
  facet_wrap(~lyr, ncol = 2)+
  scale_fill_viridis_c(na.value = "transparent", name = "Elevation",
                       option = "viridis", direction = -1) +
  theme(text=element_text(family = "serif", size=15), 
        axis.text.x = element_text(colour="black"), 
        axis.text.y = element_text(colour="black", angle = 90, hjust = 0.5))

p + scale_x_continuous(breaks = scales::pretty_breaks(n = 3)) +
  scale_y_continuous(breaks = scales::pretty_breaks(n = 3))

which returns the following error

Error in min(lon) : invalid 'type' (closure) of argument

How can I solve this error?


Solution

  • This is an issue on ggplot2 side (see https://github.com/tidyverse/ggplot2/issues/4622, https://github.com/tidyverse/ggplot2/pull/5442 and How to specify exacts axis breaks in a map using sf and ggplot2?).

    In the meantime tidyterra FAQs suggests an approach that I adapted a bit for your case:

    library(terra)
    #> terra 1.7.55
    library(ggplot2)
    library(tidyterra)
    
    r1 <- rast(system.file("ex/elev.tif", package = "terra"))
    r2 <- r1
    
    r <- c(r1, r2)
    
    names(r) <- c("R1", "R2")
    
    # Plot
    p <- ggplot() +
      geom_spatraster(data = r) +
      facet_wrap(~lyr, ncol = 2) +
      scale_fill_viridis_c(
        na.value = "transparent", name = "Elevation",
        option = "viridis", direction = -1
      ) +
      theme(
        text = element_text(family = "serif", size = 15),
        axis.text.x = element_text(colour = "black"),
        axis.text.y = element_text(colour = "black", angle = 90, hjust = 0.5)
      )
    
    p + ggtitle("Default breaks")
    

    # Get bounding box in EPSG 4326 
    ext <- r %>%
      project("EPSG:4326", mask = TRUE) %>%
      ext() %>%
      as.vector()
    
    # Include "manually" the breaks
    p +
      scale_y_continuous(breaks = scales::breaks_pretty(n = 3)(ext[c("ymin", "ymax")])) +
      scale_x_continuous(breaks = scales::breaks_pretty(n = 3)(ext[c("xmin", "xmax")])) +
      ggtitle("Custom breaks")
    

    Created on 2023-11-07 with reprex v2.0.2