按列在ggplot中为多边形(由concaveman制作)着色

Coloring polygons (made with concaveman) in ggplot by column

我正在为其他人制作的地图改编代码,该地图使用包 concaveman 从点生成凹包。目标是在海洋中绘制许多不同的多边形,并通过分组变量对它们进行颜色编码。该代码非常适合制作所有多边形的地图并按身份对它们进行颜色编码:

library(sf)
library(concaveman) 
library(data.table)
library(ggplot2)

dat <- data.table(longitude = c(-131.319783, -131.141266, -131.08165, -131.079066, -130.894966, 
             -131.063783, -131.10855, -131.215533, -131.189816, -131.14565, 
             -131.200866, -131.046466, -130.94055, -130.928983, -130.7513, 
             -130.8406, -130.833433, -130.830666, -130.82205, -130.89, -63.3666666666667, 
             -63.3666666666667, -63.1666666666667, -64.1833333333333, -63.3166666666667, 
             -63.3, -63.85, -63.9333333333333, -63.9333333333333, -63.5833333333333, 
             -63.5833333333333, -63.7, -63.7, -63.2833333333333, -63.5833333333333, 
             -63.95, -64.1833333333333, -63.8833333333333, -63.8, -63.2166666666667, 
             -5.6788, -5.4408, -5.6835, -5.424, -5.6475, -5.4371, -5.6181, 
             -5.4446, -5.6753, -5.4366, -5.6746, -5.4448, -5.6642, -5.4411, 
             -5.666, -5.4408, -5.624, -5.4321, -5.6806, -5.4473),
           latitude = c(52.646633, 52.589683, 52.556516, 52.559816, 52.402916, 52.5983, 
             52.554216, 52.550883, 52.539166, 52.658216, 52.627966, 52.481733, 
             52.486033, 52.469033, 52.469166, 52.261833, 52.292133, 52.301066, 
             52.3523, 52.366966, 48.4666666666667, 48.4666666666667, 48.65, 
             49.0166666666667, 48.8166666666667, 48.8166666666667, 49.1, 48.8666666666667, 
             48.8666666666667, 48.8, 48.8166666666667, 48.4833333333333, 48.4833333333333, 
             48.8, 48.8166666666667, 48.8833333333333, 49.05, 49.0833333333333, 
             48.7166666666667, 48.6666666666667, 54.7201, 54.6033, 54.7191, 
             54.5733, 54.7225, 54.5923, 54.7261, 54.6076, 54.719, 54.5978, 
             54.7195, 54.6108, 54.7204, 54.6062, 54.7214, 54.5923, 54.7275, 
             54.592, 54.7207, 54.6188),
           group = c(rep('NEPac',20),rep('NWAtl',20),rep('NEAtl',20))
           )

split <- split(dat, dat$group)
split.sf <- lapply(split, st_as_sf, coords = c("longitude", "latitude"))
concave <- lapply(split.sf, concaveman, concavity = 3, length_threshold = 2)
concave.binded <- do.call('rbind', concave)
concave.spdf <- as_Spatial(concave.binded)

ggplot() +
  geom_polygon(data = concave.spdf,
               aes(x = long, y = lat, group = group, fill = group, color = group)) 

但是,除了 group 之外,我不知道如何用任何东西填充多边形。这是我的尝试:

concave.spdf$ocean <- c('P','A','A')

ggplot() +
  geom_polygon(data = concave.spdf,
               aes(x = long, y = lat, group = group, fill = ocean, color = ocean)) 

引发此错误:Error in FUN(X[[i]], ...) : object 'ocean' not found

我认为问题在于 split 在传递给 concaveman 时按身份对多边形进行分组,但如果我更改它,它们将无法正确绘制(因为不同多边形的点将被合并)。如何保持单独绘制多边形但通过分组变量为它们着色? (如果可能的话,出于审美原因,我更愿意在真实情节中坚持使用 concaveman [这比这个代表复杂得多] - 我知道如果我使用不同的方法来绘制多边形,这会更容易。)

最简单的方法是添加 scale_fill_manual:

ggplot() +
  geom_polygon(data = concave.spdf,
               aes(x = long, y = lat, group = group, fill = group)) +
  scale_fill_manual(values = c("red", "green", "blue"),
                    labels = c("Ocean 1", "Ocean 2", "Ocean 3"))

可以说,更好的方法是转换为一个简单的特征集合,您可以向其中添加您喜欢的任何列,并使用 geom_sf

自动绘图
concave.spdf <- st_as_sf(concave.spdf)
concave.spdf$ocean <- c("Ocean 1", "Ocean 2", "Ocean 3")

ggplot(concave.spdf) +
  geom_sf(aes(fill = ocean))

请注意,这也会自动给出正确的 co-ordinate 比例。