rterramap-projectionstidyterra

Stop projected data from double-wrapping around map in particular projections (tidyterra)


When plotting global data using tidyterra, I'm experiencing a weird issue with the way the data wraps around the edges of the map (e.g. the -180/180 boundary). As shown in the example below, everything is fine when plotting using lat/lon, or when I reproject to mollweide (despite the weirdly ending lat/lon lines). But when I retroject to Equal Earth (Greenwich, "ESRI:53035"), some of the data gets plotted twice - you can see a fair bit of Russia showing up on the left, and Alaska/Canada on the right, even though both continents are displayed in full on the other side of the map. Is there any way to tell geom_spatraster() to enforce the -180 limit on the left and the 180 limit on the right? I've played around with limits and expand=FALSE, but haven't been able to come up with anything.

Example:

library(terra)
library(geodata)
library(tidyterra)

#sample data
tavg <- worldclim_global("tavg", 10, ".")
tavg <- mean(tavg)

#plot in lat/lon
ggplot() +
  geom_spatraster(data = tavg) +
  scale_fill_whitebox_c(palette='atlas')

#project to mollweide - works (except for
ggplot() +
  geom_spatraster(data = tavg) +
  scale_fill_whitebox_c(palette='atlas') +
  coord_sf(crs = st_crs("ESRI:54009")) + 
  labs(title='Mollweide')

#project to equal earth greenwich
ggplot() +
  geom_spatraster(data = tavg) +
  scale_fill_whitebox_c(palette='atlas') +
  coord_sf(crs = st_crs("ESRI:53035")) + 
  labs(title='Equal Earth')

Data plotted on mollweide projection Data plotted on equal earth projection


Solution

  • This is a known bug in tidyterra https://github.com/dieghernan/tidyterra/issues/115. I created a Pull Request that will fix the problem: https://github.com/dieghernan/tidyterra/pull/169

    For the moment, the workaround is to project the data in terra before plotting, with mask=TRUE:

    library(terra)
    library(geodata)
    #sample data
    tavg <- worldclim_global("tavg", 10, ".")
    tavg <- mean(tavg)
    # project, using maks=TRUE to avoid wrapping around the globe
    tavg_proj <- project(tavg, "+proj=eqearth", mask=TRUE)
    library(tidyterra)
    library(ggplot2)
    ggplot() +
      geom_spatraster(data = tavg_proj) +
      scale_fill_whitebox_c(palette='atlas') +
      coord_sf(crs = "+proj=eqearth") + 
      labs(title='Equal Earth')
    

    enter image description here

    Edit: the patch has made it into the dev version of tidyterra. So, after installing the dev version from r-universe:

    install.packages("tidyterra", repos = c(
      "https://dieghernan.r-universe.dev",
      "https://cloud.r-project.org"
    ))
    

    you can plot directly tavg with:

    ggplot() +
      geom_spatraster(data = tavg, mask_projection = TRUE ) +
      scale_fill_whitebox_c(palette='atlas') +
      coord_sf(crs = "+proj=eqearth") + 
      labs(title='Equal Earth')
    

    (note the mask_projection=TRUE param in geom_spatraster)