将比例尺添加到已使用 coord_sf 缩放的 ggplot 地图?

Add a scale bar to a ggplot map that has been scaled using coord_sf?

我使用 sf 包和 ggplot2 制作了一张地图:

library(ggplot2)
library(sf)
library(rnaturalearth)
state_prov <- rnaturalearth::ne_states(c("united states of america", "canada"), returnclass="sf")
x <- ggplot(data=state_prov) + 
geom_sf()+
coord_sf(xlim=c(-170, -95), ylim=c(40, 75)) 
print(x)

在 Rstudio 中生成以下地图:

太好了,但我需要为其添加一个比例尺。当我尝试使用 ggsn 修改代码时,我根本看不到比例尺。

library(ggplot2)
library(sf)
library(rnaturalearth)
state_prov <- rnaturalearth::ne_states(c("united states of america", "canada"), returnclass="sf")
x <- ggplot(data=state_prov) + 
geom_sf()+
coord_sf(xlim=c(-170, -95), ylim=c(40, 75)) +
ggsn::scalebar(state_prov, location="topleft", dist = 50, dist_unit = "km", 
                 transform=TRUE, model="WGS84", height=0.1)
print(x) 

我尝试更改高度、st.dist 和位置,但没有成功。当我删除对 coord_sf() 的调用时,我可以看到比例尺比例不佳,这让我相信 ggsn 无法识别地图正在被 coord_sf() 放大。

我该如何解决这个问题? ggsn 似乎不容易修改。我愿意使用其他包或方法,但我确实需要以类似的方式继续调用 ggplot,因为我有一个基于相同结构的更复杂的地图。

谢谢!

正如您提到的,如果您注释掉代码的 coord_sf 部分,则会显示比例尺。我的猜测是 ggsn::scalebar 必须从整个 state_prov 数据集中获取其 topleft 位置,并且当您使用 coord_sf 缩放时,比例尺被裁剪掉了。

编辑: 将比例尺放在地图上时,请注意在 lat/long 投影中以这种比例投影时的极端失真:

这里有几个选项可以显示比例尺。

选项 1

使用 ggspatial::annotation_scale 而不是 ggsn,它似乎可以识别 coord_sf 中定义的缩放。

ggplot(data=state_prov) + 
  geom_sf()+
  coord_sf(xlim=c(-170, -95), ylim=c(40, 75)) +
  ggspatial::annotation_scale(location = 'tl')

选项 2

使用您的原始代码,但在绘图之前裁剪 state_prov,以便 scalebar 可以找到正确的 topleft

state_prov_crop <- st_crop(state_prov, xmin=-170, xmax = -95, ymin = 40, ymax = 75)

ggplot(data=state_prov_crop) + 
  geom_sf()+
  #coord_sf(xlim=c(-170, -95), ylim=c(40, 75)) +
  ggsn::scalebar(state_prov_crop, location="topleft", dist = 50, dist_unit = "km", 
                 transform=TRUE, model="WGS84", height=0.1)