ggplot空间数据和ggsave for循环中的唯一ID

b5buobof  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(63)

我有一个跨越3个省的流域数据集。每个流域都有一个相应的shapefile,在3个rcp(气候预测模型)下,生态系统破坏的评分从0到1。下面是我的dataframe的头:

ws            rcp  ecodisrup                       geometry
ANNAPOLIS_sp rcp26 0.09090909 MULTIPOLYGON (((-64.86239 4...
BARRINGTON_C rcp26 0.00000000 MULTIPOLYGON (((-65.4722 43...
CHETICAMP_RI rcp26 0.09090909 MULTIPOLYGON (((-60.59559 4...
CLAM_HRB_ST. rcp26 0.27272727 MULTIPOLYGON (((-61.38909 4...
COUNTRY_HARB rcp26 0.09090909 MULTIPOLYGON (((-61.96444 4...
EAST_INDIAN_ rcp26 0.09090909 MULTIPOLYGON (((-63.94016 4...

流域及其shapefile对于每个rcp(26,45,85)重复,例如:

ws            rcp  ecodisrup                       geometry
ANNAPOLIS_sp rcp26 0.09090909 MULTIPOLYGON (((-64.86239 4...
...          rcp26 0.00000000 MULTIPOLYGON (((-65.4722 43...
46th ws      rcp26 0.09090909 MULTIPOLYGON (((-60.59559 4...
ANNAPOLIS_sp rcp45 0.27272727 MULTIPOLYGON (((-64.86239 4...
...          rcp45 0.09090909 MULTIPOLYGON (((-65.4722 43...
46th ws      rcp45 0.09090909 MULTIPOLYGON (((-60.59559 4...
ANNAPOLIS_sp rcp85 0.09090909 MULTIPOLYGON (((-64.86239 4...
...          rcp85 0.00000000 MULTIPOLYGON (((-65.4722 43...
46th ws      rcp85 0.09090909 MULTIPOLYGON (((-60.59559 4...

我想通过写一个for循环来绘制三个rcp场景下的分水岭,用ecodisrup着色。我遇到的问题是在for循环中包含一个ggsave函数,而且我正在编写的循环只是三次生成相同的map。
稍后在我的分析中,我将需要相同类型的for循环进行Map,但我将添加一个物种列(在3个RCP场景下,为所有流域的每个物种生成一个由ecodisrup着色的Map)。
下面是我以前尝试过的代码,预期输出三个map(每个rcp一个)。相反,我得到了三张Map,但它们都有完全相同的颜色(不确定它们是否只是被最后一张着色?rcp85?

# make empty list to fill in with plots
ecodis_rcp_plots = list()

# define the different rcps
ecodis_rcp = unique(ecodis$rcp)

# begin for loop
for (rcp in ecodis_rcp){
  ecodis_rcp_plots[[rcp]] = ggplot(data = ecodis, aes(geometry = geometry)) + 
    geom_sf(aes(fill = ecodisrup)) +
    scale_fill_viridis_c(option = "viridis", limits = c(0, 1))
  ggsave(paste("C:/Users/myname/Desktop/EcoDis", rcp, ".png"),ecodis_rcp_plots[[rcp]],width=8,height=8,units="in",dpi=300)
}

任何见解将不胜感激,谢谢!

kb5ga3dv

kb5ga3dv1#

一个选项是首先拆分数据集,然后循环遍历结果sf对象的列表。以下是基于sf包中的nc数据集的更通用的示例:

library(ggplot2)
library(sf)
#> Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE

# prepare some example data
nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)
nc$sample_group <- paste("Group", rep(1:5, each = 20))
nc$area <- scales::rescale(nc$AREA)
nc[,c("NAME", "sample_group", "area")]
#> Simple feature collection with 100 features and 3 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS:  NAD27
#> First 10 features:
#>           NAME sample_group       area                       geometry
#> 1         Ashe      Group 1 0.36180905 MULTIPOLYGON (((-81.47276 3...
#> 2    Alleghany      Group 1 0.09547739 MULTIPOLYGON (((-81.23989 3...
#> 3        Surry      Group 1 0.50753769 MULTIPOLYGON (((-80.45634 3...
#> 4    Currituck      Group 1 0.14070352 MULTIPOLYGON (((-76.00897 3...
#> 5  Northampton      Group 1 0.55778894 MULTIPOLYGON (((-77.21767 3...
#> 6     Hertford      Group 1 0.27638191 MULTIPOLYGON (((-76.74506 3...
#> 7       Camden      Group 1 0.10050251 MULTIPOLYGON (((-76.00897 3...
#> 8        Gates      Group 1 0.24623116 MULTIPOLYGON (((-76.56251 3...
#> 9       Warren      Group 1 0.38190955 MULTIPOLYGON (((-78.30876 3...
#> 10      Stokes      Group 1 0.41206030 MULTIPOLYGON (((-80.02567 3...

# split by some factor, resulting list is named according to factor levels:
nc_split <- split(nc, ~sample_group)

# create named list of nc_split names for lapply(), this helps us to get 
# a named list from lapply() while providing access to sample_group values
nc_groups <- setNames(names(nc_split), names(nc_split))
nc_groups
#>   Group 1   Group 2   Group 3   Group 4   Group 5 
#> "Group 1" "Group 2" "Group 3" "Group 4" "Group 5"

# cycle though the list of sf objects and generate list of plots
plots <- lapply(nc_groups, \(grp_name){
  ggplot(nc_split[[grp_name]], aes(fill = area)) +
    geom_sf() +
    scale_fill_viridis_c(limits = c(0, 1)) +
    ggtitle(grp_name) +
    theme_void() +
    theme(legend.position = "none")
})
# resulting list of plots, named:
str(plots, max.level = 1)
#> List of 5
#>  $ Group 1:List of 9
#>   ..- attr(*, "class")= chr [1:2] "gg" "ggplot"
#>  $ Group 2:List of 9
#>   ..- attr(*, "class")= chr [1:2] "gg" "ggplot"
#>  $ Group 3:List of 9
#>   ..- attr(*, "class")= chr [1:2] "gg" "ggplot"
#>  $ Group 4:List of 9
#>   ..- attr(*, "class")= chr [1:2] "gg" "ggplot"
#>  $ Group 5:List of 9
#>   ..- attr(*, "class")= chr [1:2] "gg" "ggplot"

# visualise all plots:
patchwork::wrap_plots(plots, nrow = 3)

# save all
for (plot_name in names(plots)) {
  ggsave(paste0("nc_plot ", plot_name, ".png"),plots[[plot_name]])
}
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image
#> Saving 7 x 5 in image

# check resulting files
fs::dir_info(glob = "nc_plot*")[,1:3]
#> # A tibble: 5 × 3
#>   path                type         size
#>   <fs::path>          <fct> <fs::bytes>
#> 1 nc_plot Group 1.png file        84.1K
#> 2 nc_plot Group 2.png file        96.7K
#> 3 nc_plot Group 3.png file        96.3K
#> 4 nc_plot Group 4.png file        88.9K
#> 5 nc_plot Group 5.png file        93.9K

创建于2023-06-16带有reprex v2.0.2

相关问题