Adicionar uma barra de escala a um mapa ggplot que foi dimensionado usando coord_sf?

Aug 18 2020

Eu produzi um mapa usando o pacote sf e 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)

que produz o seguinte mapa em Rstudio:

Isso é ótimo, mas preciso adicionar uma barra de escala a ele. Quando tento modificar o código usando ggsn, não vejo a barra de escala.

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) 

Tentei mudar a altura, a distância e o local sem sucesso. Posso ver uma barra de escala mal dimensionada quando removo a chamada para coord_sf (), me fazendo acreditar que ggsn não reconhece que o mapa está sendo ampliado por coord_sf ().

Como faço para corrigir isso? ggsn não parece ser facilmente modificável. Estou aberto a usar outro pacote ou método, mas preciso continuar chamando ggplot de maneira semelhante, pois tenho um mapa muito mais complicado com base na mesma estrutura.

Obrigado!

Respostas

2 nniloc Aug 18 2020 at 07:33

Como você mencionou, se você comentar a coord_sfparte do seu código, a barra de escala aparecerá. Meu palpite é que ggsn::scalebardeve estar obtendo sua topleftlocalização a partir de todo o conjunto de state_provdados, e quando você aumenta coord_sfo zoom, a barra de escala é cortada.

Editar: cuidado com a distorção extrema ao colocar uma barra de escala em um mapa com projeção lat / long nesta escala:https://stackoverflow.com/a/41373569/12400385

Aqui estão algumas opções para fazer uma barra de escala aparecer.

Opção 1

Use em ggspatial::annotation_scalevez de ggsnque parece reconhecer o zoom conforme definido em coord_sf.

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

opção 2

Use seu código original, mas corte state_provantes de plotar para scalebarencontrar o correto 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)