Rayshader绘制ggplot2对象时路径偏移。

huangapple go评论114阅读模式
英文:

Rayshader path has offset when plotting a ggplot2 object

问题

我试图绘制一个世界地图和柏林到坎昆之间的路径。到目前为止,我已经使用库rnaturalearth绘制了一个世界地图,并将其转换为一个ggplot2对象,然后使用rayshader plot_gg函数绘制出来。

之后,我尝试在柏林(52.5200° N,13.4050° E)到坎昆(21.1619° N,-86.8515° E)之间添加一个rayshader路径覆盖。以下是结果:

Rayshader绘制ggplot2对象时路径偏移。

如您所见,路径太高,而且稍微有点太长。我目前的最佳猜测是,这与rayshader绘图和ggplot对象(世界地图周围的白色边框)的偏移有关。

以下是我的代码:

#加载库
library(sf)
library(rayshader)
library(rayrender)
library(rnaturalearth)
library(rnaturalearthdata)
library(tidyverse)

#获取世界地图的ggplot对象
world <- ne_countries(scale = "medium", returnclass = "sf")
ggData = ggplot(data = world) + geom_sf()

#柏林和坎昆的纬度、经度作为render_path()的列表
lats = list()
lats[1] = 52.5
lats[2] = 21.1

longs = list()
longs[1] = 13.4
longs[2] = -86.8

#路径的高度
alts = list()
alts[1] = 100
alts[2] = 100

#使用rayshader绘图,使用ggData的bbox宽度和高度比例
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))

我尝试了不同的宽度和高度比例,以匹配ggplot对象,因为我认为这可能与不正确的宽高比有关。

英文:

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:

Rayshader绘制ggplot2对象时路径偏移。

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 &lt;- ne_countries(scale = &quot;medium&quot;, returnclass = &quot;sf&quot;)
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=&quot;red&quot;, 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.

答案1

得分: 1

我不知道原因是什么,但你的 render_path() 调用中的 extent 参数是错误的。如果你尝试在已知的纬度或经度上绘制直线,你可以看到这一点。网格线位于纬度 -45、0、45 和经度 -120、-60、0、60、120。如果你沿着这些线绘制路径,纬度路径是正确的,但经度路径是错误的。例如,使用以下路径:

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))

在地图上显示如下:

Rayshader绘制ggplot2对象时路径偏移。

路径绘制得太西,太长了。如果我改变 extent 参数使用以下代码:

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

看起来更好一些。我通过反复试验找到了这些数字;你(或其他人)如果想要解释它们,就需要做一些研究。仍然不是完美的,所以你的路径仍然没有准确经过柏林和坎昆,但误差没有那么大。

英文:

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=&quot;red&quot;, antialias=TRUE, linewidth=3,
            extent=st_bbox(world), altitude=unlist(alts))

gives this on the map:

Rayshader绘制ggplot2对象时路径偏移。

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

bbox &lt;- st_bbox(world)
bbox[c(1,3)] &lt;- 1.2*bbox[c(1,3)]
bbox[c(2,4)] &lt;- 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.

答案2

得分: 1

一种选择是不通过 rayshader 渲染旅行路径,而是将其直接包含在 ggplot 对象中,就像这样(所需的库与 OP 中相同):

创建 world 特性:

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

创建 my_path 特性(旅行路径)从点坐标的线字符串中:

my_path <- 
  c(13.4, 52.5, ## 经度
    -86.6, 21.1 ## 纬度
    ) |>
  matrix(ncol = 2, byrow = TRUE) |>
  st_linestring() |>
  st_sfc() |>
  st_set_crs(4326) ## 将 CRS 设置为地理坐标(度)

worldmy_path 特性作为图层添加到 ggplot 对象中:

ggData <- 
  ggplot() + 
  geom_sf(data = world) +
  geom_sf(data = my_path, col = 'red') +
  coord_sf(
    ## 请参阅 ?coord_sf 设置地图限制等。
  )

绘图:

plot_gg(ggData)
英文:

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 = &quot;medium&quot;, returnclass = &quot;sf&quot;)

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

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

add features world and my_path as layers to ggplot object:

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

plot

plot_gg(ggData)

Rayshader绘制ggplot2对象时路径偏移。

huangapple
  • 本文由 发表于 2023年2月19日 16:56:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499001.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定