Insert geom_sf layer underneath existing geom_sf layers

南笙酒味 提交于 2019-12-24 01:27:08

问题


I have a basic map of India with states and borders, some labels, and a number of other specifications stored as a gg object. I'd like to generate a number of maps with a district layer, which will bear data from different variables.

To prevent the district maps overwriting state and country borders, it must be before all the previous code, which I'd like to avoid repeating.

I thought I could do this by calling on $layers for the gg object as per this answer. However, it throws an error. Reprex is below:

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

Intended outcome

Any help would be much appreciated!


回答1:


If you look at geom_sf(data=distSF) you'll see that it is a list made up of two elements - you want the first one which contains the layer information, so geom_sf(data = distSF, fill = "gold")[[1]] should work.

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

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



回答2:


I'm still not sure if I'm missing a detail of what you're looking for, but ggplot2 draws layers in the order you provide them. So something like

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

will draw columns, then points on top of those, then lines on top of the previous layers.

Same goes for sf plots, which makes it easy to make a plot like this of multiple geographic levels.

(I'm using rmapshaper::ms_simplify on the sf objects just to simplify them and speed things up for plotting.)

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

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

Then you can plot by adding up the layers in the order you need them displayed. Keep in mind that if you needed to do other calculations with any of these sfs, you could do that in advance or inside your 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)

Regarding trying to add one plot to another: ggplot2 works in layers, so you create a single base ggplot object, then add geometries on top of it. So you could make, for example, two valid plots:

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

But you can't add them, because you would have 2 base ggplot objects. This should be the error you mentioned:

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

Instead, if you need to make a plot, then add something else on top of it, make the base ggplot, then add geometry layers, such as a geom_sf with a different set of data.

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

Created on 2018-10-29 by the reprex package (v0.2.1)



来源:https://stackoverflow.com/questions/53036873/insert-geom-sf-layer-underneath-existing-geom-sf-layers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!