Вставьте слой geom_sf под существующие слои geom_sf

У меня есть базовая карта Индии с штатами и границами, некоторыми надписями и рядом других спецификаций, хранящихся в виде объекта gg. Я хотел бы сгенерировать несколько карт со слоем местности, который будет содержать данные из разных переменных.

Чтобы карты районов не переписывали границы штатов и стран, это должно быть перед всем предыдущим кодом, который я хотел бы избежать повторения.

Я думал, что смогу сделать это, позвонив по $layers для объекта gg согласно этому ответу. Однако выдает ошибку. Представляем ниже:

library(ggplot2)
library(sf)
library(raster)

# Download district and state data (should be less than 10 Mb in total)

distSF <- st_as_sf(getData("GADM",country="IND",level=2))

stateSF <- st_as_sf(getData("GADM",country="IND",level=1))

# Add border

countryborder <- st_union(stateSF)

# Basic plot

basicIndia <- ggplot() +
  geom_sf(data = stateSF, color = "white", fill = NA) +
  geom_sf(data = countryborder, color = "blue", fill = NA) +
  theme_dark()

basicIndia

# Data-bearing plot

districts <- ggplot() +
  geom_sf(data = distSF, fill = "gold")

basicIndia$layers <- c(geom_sf(data = distSF, fill = "gold"), basicIndia$layers)

basicIndia
#> Error in y$layer_data(plot$data): attempt to apply non-function

Предполагаемый результат

Любая помощь приветствуется!

2 ответа

Решение

Если вы посмотрите на geom_sf(data=distSF) вы увидите, что это список, состоящий из двух элементов - вам нужен первый, который содержит информацию о слое, поэтому geom_sf(data = distSF, fill = "gold")[[1]] должно сработать.

districts <- ggplot() +
  geom_sf(data = distSF, fill = "gold")

basicIndia$layers <- c(geom_sf(data = distSF, fill = "gold")[[1]], basicIndia$layers)

Я до сих пор не уверен, что мне не хватает детали того, что вы ищете, но ggplot2 рисует слои в порядке их предоставления. Так что-то вроде

ggplot(data) +
  geom_col() +
  geom_point(...) +
  geom_line(...)

нарисует столбцы, затем точки над ними, затем линии поверх предыдущих слоев.

То же самое касается sf сюжеты, которые позволяют легко составить такой график из нескольких географических уровней.

(Я использую rmapshaper::ms_simplify на sf объекты, чтобы упростить их и ускорить процесс построения.)

library(dplyr)
library(ggplot2)
library(sf)
library(raster)

distSF <- st_as_sf(getData("GADM",country="IND",level=2)) %>% rmapshaper::ms_simplify()
...

Затем вы можете построить график, сложив слои в том порядке, в котором они вам нужны. Имейте в виду, что если вам нужно было сделать другие расчеты с любым из этих sfs, вы можете сделать это заранее или внутри вашего geom_sf,

ggplot() +
  geom_sf(data = distSF, fill = "gold", size = 0.1) +
  geom_sf(data = stateSF, color = "white", fill = NA) +
  geom_sf(data = countryborder, color = "blue", fill = NA)

Что касается попытки добавить один сюжет в другой: ggplot2 работает в слоях, поэтому вы создаете единую базу ggplot объект, затем добавьте геометрию поверх него. Таким образом, вы можете сделать, например, два действительных графика:

state_plot <- ggplot(stateSF) + 
  geom_sf(color = "white", fill = NA)
country_plot <- ggplot(countryborder) + 
  geom_sf(color = "blue", fill = NA)

Но вы не можете добавить их, потому что у вас будет 2 базы ggplot объекты. Это должно быть ошибкой, которую вы упомянули:

state_plot + 
  country_plot
#> Error: Don't know how to add country_plot to a plot

Вместо этого, если вам нужно сделать сюжет, то добавьте что-нибудь еще поверх него, сделайте основу ggplot, затем добавьте геометрические слои, такие как geom_sf с другим набором данных.

state_plot +
  geom_sf(data = countryborder, fill = NA, color = "blue")

Создано в 2018-10-29 пакетом представлением (v0.2.1)

Другие вопросы по тегам