0

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.

help-info.de
  • 6,695
  • 16
  • 39
  • 41
Michael
  • 73
  • 5
  • The `zscale` of the red line is set to 50 instead 1. Does that make the line float above the map?, but without shadow? (I'm not familiar with rayshader). In that case, shift and length might be the effect of perspective (the line being closer = bigger to the camera). – I_O Feb 19 '23 at 09:05
  • The zscale only affects how high up the line is rendered. rayshader renders an interactive map and when I change the perspective the path is still visibly wrong – Michael Feb 19 '23 at 09:25

2 Answers2

1

EDITED: The original plots were for a slightly modified ggData. This post corrects things.

I don't know what the cause is, but the extent argument in your render_path() call is wrong. You can see this if you try plotting straight lines at known latitudes or longitudes. The grid lines are at latitudes -45, 0, 45 and longitudes -120, -60, 0, 60, 120. If you plot paths along those lines, the latitude paths are okay, but the longitude paths are wrong. For example, using this path:

render_path(lat = c(-45, 45), long = c(-60, -60), 
            zscale=50, color="red", antialias=TRUE, linewidth=3,
            extent=st_bbox(world), altitude=unlist(alts))

gives this on the map:

enter image description here

with the path drawn too far west, and too long. If I change the extent argument using

bbox <- st_bbox(world)
bbox[c(1,3)] <- 1.2*bbox[c(1,3)]
bbox[c(2,4)] <- 1.1*bbox[c(2,4)]

it looks better. I found those numbers by trial and error; you (or someone else) will have to do some research if you want to explain them. It's still not perfect, so your path still misses Berlin and Cancun, but not by as much.

user2554330
  • 37,248
  • 4
  • 43
  • 90
1

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

I_O
  • 4,983
  • 2
  • 2
  • 15