Search code examples
rggplot2rayshader

Rayshader path has offset when plotting a ggplot2 object


I am trying to plot a world map and a path between Berlin and Cancun. So far I managed to plot a world map using library rnaturalearth and convert it to a ggplot2 object which is plotted using rayshader plot_gg function.

After that I tried to add a rayshader path overlay from Berlin (52.5200° N, 13.4050° E) to Cancun (21.1619° N, -86.8515° E). Here is the result:

Path plotted on world map

As you can see the path is up too high and also a bit too long. My best guess right now is that it has to do something with the offset of the rayshader plot and the ggplot object (The white border around the world map).

Here is my code:

#load libraries
library(sf)
library(rayshader)
library(rayrender)
library(rnaturalearth)
library(rnaturalearthdata)
library(tidyverse)

#get ggplot object of world
world <- ne_countries(scale = "medium", returnclass = "sf")
ggData = ggplot(data = world) + geom_sf()

#latitudes, longitudes of Berlin and Cancun as list for render_path()
lats = list()
lats[1] = 52.5
lats[2] = 21.1

longs = list()
longs[1] = 13.4
longs[2] = -86.8
 
#Altitude of the path 
alts = list()
alts[1] = 100
alts[2] = 100

#plot with rayshader, width and height ratio of bbox of ggData
plot_gg(ggData, scale=10, width=3.6, height=1.7359854)
render_path(lat = unlist(lats), long = unlist(longs), zscale=50, color="red", antialias=TRUE, linewidth=3, extent=st_bbox(world), altitude=unlist(alts))

I tried it with different width and height ratios to match the ggplot object as I thought it might have to do something with wrong aspect ratios.


Solution

  • One option is to render the travel path not via rayshader but include it already in your ggplot object like so (required libraries as in OP):

    create feature world:

    world = ne_countries(scale = "medium", returnclass = "sf")
    

    create feature my_path (the travel path) from linestring from point coordinates:

    my_path <- 
      c(13.4, 52.5, ## longs
        -86.6, 21.1 ## lats
        ) |>
      matrix(ncol = 2, byrow = TRUE) |>
      st_linestring() |>
      st_sfc() |> 
      st_set_crs(4326) ## set CRS to geographic (degrees)
    

    add features world and my_path as layers to ggplot object:

    ggData <- 
      ggplot() + 
      geom_sf(data = world) +
      geom_sf(data = my_path, col = 'red') +
      coord_sf(
        ## see ?coord_sf to set map limits etc.
      )
    

    plot

    plot_gg(ggData)
    

    enter image description here