不同 geom_sf ggplots 之间的通用指南图例

Common guide legend between different geom_sf ggplots

我正在单独绘制一组不同的地图 - 没有分面。我希望所有地图上的指南图例都显示相同的数据全球范围,即使在任何一张地图上都可能不会显示数据的整个范围。

在下面的 reprex 中,图 A 显示了数据的全局图例,但图 B 没有。如何为 Plot A 添加全局图例?

library(ggplot2)
library(dplyr)
library(sf)
library(spData)

nz_i_class <- nz %>% 
  mutate(income_class = cut(Median_income, breaks = c(22000, 24000, 26000, 28000, 30000, 32000, 34000), include.lowest = T)) 

breaks<-c("22000-24000", "24000-26000", "26000-28000", "28000-30000", "30000-32000", "32000-34000")

# Plot A with global income classes
ggplot() + geom_sf(data = nz_i_class, aes(fill = income_class)) +
  geom_sf(data = nz_height) +
  scale_fill_viridis_d(labels = breaks) +
  ggtitle("Plot A")

# Plot B shows local, not global, income classes
ggplot() + geom_sf(data = nz_i_class %>% filter(Island == "South"), aes(fill = income_class)) +
  geom_sf(data = nz_height) +
  scale_fill_viridis_d(labels = breaks) +
  ggtitle("Plot B")

编辑:根据@stefan 的评论添加了限制。这会覆盖多边形填充。

# Plot C trying to set limits
ggplot() + geom_sf(data = nz_i_class %>% filter(Island == "South"), aes(fill = income_class)) +
  geom_sf(data = nz_height) +
  scale_fill_viridis_d(guide=FALSE) +
  scale_fill_viridis_d(limits=breaks) +
  ggtitle("Plot C")

要修复多个绘图的图例,您可以为每个 scale_fill_xxx 设置相同的 limits。 Plot C 代码的问题是您将 limits 设置为等于用于 Plot A 的标签。但是,所选标签不是数据中 income_classes 的标签。默认情况下 cut 为间隔分配标签,如 (XXX, YYY]。这就是为什么您得到的地图没有任何填充颜色,因为 income_class 的类别未包含在 limits 的向量中。要解决此问题,请将 cut 中的 labels 设置为等于 breaks:

的向量
library(ggplot2)
library(dplyr)
library(sf)
library(spData)

breaks <- c("22000-24000", "24000-26000", "26000-28000", "28000-30000", "30000-32000", "32000-34000")

nz_i_class <- nz %>% 
  mutate(income_class = cut(Median_income, 
                            breaks = c(22000, 24000, 26000, 28000, 30000, 32000, 34000), 
                            labels = breaks,
                            include.lowest = T)) 

# Plot A with global income classes
ggplot() + geom_sf(data = nz_i_class, aes(fill = income_class)) +
  geom_sf(data = nz_height) +
  scale_fill_viridis_d() +
  ggtitle("Plot A")

# Plot B with 
ggplot() + geom_sf(data = nz_i_class %>% filter(Island == "South"), aes(fill = income_class)) +
  geom_sf(data = nz_height) +
  scale_fill_viridis_d(limits=breaks) +
  ggtitle("Plot C")