R中使用ggplot多面绘图进行地理空间映射?

4

我有一个名为Watershed的流域,其中包含33个子流域。我无法编写可重现的代码来绘制该集水区的shapefile文件,因此我附上了我的Shapefile文件。我有四个模型,用于生成2005-2008年的蒸散发(ET)数据。我想使用ggplotfaceting功能比较每年四个模型的数据产品。我尝试了一些方法(请参见我的示例代码),但未能成功。我希望能够找到解决方法。

library(sf)
library(tidyverse)

shape <- read_sf(dsn = ".", layer = "Watershed")


ETM1 = data.frame(Subbasin = 1:33, Yr2005 = runif(33, 500,700), Yr2006 = runif(33, 600,750), Yr2007 = runif(33, 450,750),
                  Yr2008 = runif(33, 550,800), Model = rep("M1", 33))

ETM2 = data.frame(Subbasin = 1:33, Yr2005 = runif(33, 600,750), Yr2006 = runif(33, 550,750), Yr2007 = runif(33, 600,750),
                  Yr2008 = runif(33, 700,800), Model = rep("M2", 33))

ETM3 = data.frame(Subbasin = 1:33, Yr2005 = runif(33, 500,750), Yr2006 = runif(33, 650,750), Yr2007 = runif(33, 700,750),
                  Yr2008 = runif(33, 500,800), Model = rep("M3", 33))

ETM4 = data.frame(Subbasin = 1:33, Yr2005 = runif(33, 400,750), Yr2006 = runif(33, 450,750), Yr2007 = runif(33, 300,750),
                  Yr2008 = runif(33, 400,800), Model = rep("M4", 33))

ETData = rbind(ETM1,ETM2,ETM3,ETM4)
Combine = gather(ETData, key = "Variable", value = "Value", -c("Model","Subbasin"))

SpData = merge(shape, Combine, by='Subbasin')

ggplot() + 
  geom_polygon(SpData, aes(x = Lat, y = Long_, fill = Value))+
  facet_wrap(~Model, nrow = 4, ncol = 4)

这是我使用 plot(shape$geometry) 绘制的形状文件图片。 enter image description here

以下是我想要绘制的大致图形,尽管它只有三行。 enter image description here

我画了一张手绘的图,反映了我的最终目标——每个椭圆形(有点像)代表我的集水区形状文件,其中分成了子流域。对于我糟糕的绘画,我深表歉意。 enter image description here

1个回答

4
你已经接近解决方案了。你的最终数据包含了绘制图形所需的所有内容。
基本上,您可以使用facet_grid来分离“年份”和“型号”变量,并使用数据集的“几何形状”列来绘制形状(更多信息请参见https://ggplot2.tidyverse.org/reference/ggsf.html), 然后通过将该值作为填充传递到aes中完成其余部分。
在这里,我使用scale_fill_gradient来设置颜色以及一些函数来获取与您期望的绘图尽可能接近的绘图:
library(sf)
library(tidyverse)

ggplot() +
  geom_sf(data = SpData, aes(fill = Value))+
  facet_grid(Variable~Model)+
  scale_fill_gradient(name =  "Evapotranspiration (ET)", low = "green", high = "red",
                      limits = c(300,900), 
                      breaks = c(300, 500, 700, 900))+
  theme_void()+
  theme(legend.position = "bottom")

enter image description here


谢谢 - 我从你提供给我一些问题的解决方案中学到了很多技巧。 - Hydro
不用谢!很高兴能帮助你 ;) (我也在通过回答你的问题并使用你的例子来学习;) - dc37

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接