如何合并ggpattern与ggplot2图例:整合条纹到颜色图例
解决ggplot2与ggpattern图例合并问题
问题场景
制作世界地图时,用颜色区分国家分组,为适配黑白打印给其中一组添加条纹图案,但当前ggplot2的颜色图例和ggpattern的图案图例是分开的,需要将条纹整合到颜色图例中,移除独立的图案图例。
原始代码
library(tidyverse) library(ggplot2) library(ggpattern) breaks <- c(-Inf, 0, Inf) labels <- c("negative", "positive") world_map <- map_data(map = "world") data <- data.frame(country_map = unique(world_map$region)) data$mean <- -1 data$mean[data$country_map == "Russia"] <- 1 data$group <- cut(data$mean, breaks = breaks, labels = labels) data$pattern <- ifelse(data$mean < 0, "stripe", NA) ggplot(data) + geom_map(aes(map_id = country_map, fill = fct_rev(group)), map = world_map) + #coord_proj("+proj=robin", xlim = c(-135, 178.5), ylim = c(-56, 84)) + geom_polygon(data = world_map, aes(x = long, y = lat, group = group), colour = 'grey', size = 0, fill = NA) + expand_limits(x = world_map$long, y = world_map$lat) + theme_void() + geom_map_pattern(data = data, map = world_map, aes(map_id = country_map, pattern = pattern), pattern_fill = "black", fill = NA, pattern_density = 0.1, pattern_angle = 30, pattern_spacing = 0.02) #+ #scale_fill_manual(name = "Group", drop = FALSE, values = c("red", "blue"), labels = labels)
解决方案
核心思路是让fill和pattern映射到同一个分组变量,通过手动刻度和图例引导来合并两者的图例。修改后的代码如下:
library(tidyverse) library(ggplot2) library(ggpattern) breaks <- c(-Inf, 0, Inf) labels <- c("negative", "positive") world_map <- map_data(map = "world") data <- data.frame(country_map = unique(world_map$region)) data$mean <- -1 data$mean[data$country_map == "Russia"] <- 1 data$group <- cut(data$mean, breaks = breaks, labels = labels) ggplot(data) + # 基础颜色填充层 geom_map(aes(map_id = country_map, fill = group), map = world_map) + # 地图边界层 geom_polygon(data = world_map, aes(x = long, y = lat, group = group), colour = 'grey', size = 0, fill = NA) + # 图案填充层,将pattern映射到group geom_map_pattern(aes(map_id = country_map, pattern = group), map = world_map, pattern_fill = "black", fill = NA, pattern_density = 0.1, pattern_angle = 30, pattern_spacing = 0.02) + # 手动指定颜色刻度 scale_fill_manual(name = "Group", values = c("negative" = "red", "positive" = "blue"), labels = labels) + # 手动指定图案刻度,不需要图案的组设为NA scale_pattern_manual(name = "Group", values = c("negative" = "stripe", "positive" = NA), labels = labels) + # 合并图例,让fill和pattern共用一个,移除多余的图案图例 guides(pattern = guide_legend(override.aes = list(fill = c("red", "blue"))), fill = guide_legend(override.aes = list(pattern = c("stripe", NA)))) + expand_limits(x = world_map$long, y = world_map$lat) + theme_void()
关键改动说明
- 移除单独的
pattern列,将pattern直接映射到group变量,让颜色和图案绑定到同一分组 - 使用
scale_pattern_manual为需要添加条纹的分组指定stripe,另一组设为NA - 通过
guides参数,让fill和pattern的图例合并,互相覆盖对方的美学参数,确保图例项同时显示颜色和对应的图案 - 统一图例名称为"Group",避免出现两个独立图例
内容的提问来源于stack exchange,提问作者bixiou
相关产品推荐
相关产品推荐

