rplotr-sfgeo

plot geodata on the globe perspective in R


(how) is it possible to plot geodata – for example a polygon layer – on a globe with d3/perspective view, similar to this graphic on wikipedia?

I'd like a solution with sf and ggplot most, but any solutions are welcome.

(I ask this mostly out of curiosity, but since I see graphics like this fairly often, I guess the question might be useful)


Solution

  • You can use orthographic projection in sf and ggplot2 projecting to "+proj=ortho" coordinate reference system.

    Making the oceans turn blue may take some tweaking; I have resorted to buffering the Null Island by the Earth radius (inspired by this gist).

    For more information of the arguments (i.e. lat_0 & lon_0) used have a look at the PROJ documentation https://proj.org/operations/projections/ortho.html

    For a more graphic example consider this piece of code:

    library(sf)
    library(giscoR) # for the countries dataset only
    library(ggplot2)
    
    # projection string used for the polygons & ocean background
    crs_string <- "+proj=ortho +lon_0=30 +lat_0=30"
    
    # background for the globe - center buffered by earth radius
    ocean <- st_point(x = c(0,0)) %>%
      st_buffer(dist = 6371000) %>%
      st_sfc(crs = crs_string)
    
    # country polygons, cut to size
    world <- gisco_countries %>% 
      st_intersection(ocean %>% st_transform(4326)) %>% # select visible area only
      st_transform(crs = crs_string) # reproject to ortho
    
    # one of the visible ones red (don't really matter which one :)
    world$fill_color <- ifelse(world$ISO3_CODE == "DEU", "interesting", "dull")
       
    # now the action!
    ggplot(data = world) +
      geom_sf(data = ocean, fill = "aliceblue", color = NA) + # background first
      geom_sf(aes(fill = fill_color), lwd = .1) + # now land over the oceans
      scale_fill_manual(values = c("interesting" = "red",
                                   "dull" = "lightyellow"),
                        guide = "none") +
      theme_void()
    

    ortographic view of world countries, with germany in red