Добавить масштабную линейку на карту ggplot, масштабируемую с помощью corre_sf?

Aug 18 2020

Я создал карту, используя пакет 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 и местоположение. Я вижу плохо масштабируемую масштабную полосу, когда удаляю вызов функцииordin_sf (), что заставляет меня поверить в то, что ggsn не распознает масштабирование карты с помощью функции corre_sf ().

Как я могу это исправить? ggsn, похоже, нелегко изменить. Я открыт для использования другого пакета или метода, но мне нужно продолжать вызывать ggplot аналогичным образом, поскольку у меня есть гораздо более сложная карта, основанная на той же структуре.

Спасибо!

Ответы

2 nniloc Aug 18 2020 at 07:33

Как вы упомянули, если вы закомментируете coord_sfчасть своего кода, появится масштабная линейка. Я предполагаю ggsn::scalebar, что его topleftместоположение должно быть получено из всего state_provнабора данных, и при масштабировании с coord_sfпомощью масштабной полосы оно обрезается.

Изменить: остерегайтесь крайних искажений при размещении масштабной линейки на карте с проекцией широты / долготы в этом масштабе:https://stackoverflow.com/a/41373569/12400385

Вот несколько вариантов отображения масштабной линейки.

Опция 1

Используйте ggspatial::annotation_scaleвместо ggsnwhich, кажется, распознает масштаб, как определено в 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)