R语言ggplot2合并两个着色数据集时如何保留原有配色?
问题原因
ggplot2 规则里,同一美学维度(如color/fill/size)全局只能生效一个标度设置,重复添加scale_color_*系列函数时,后写的会直接覆盖前序设置,因此无法通过叠加两个scale_color_brewer()的方式给不同图层分配不同色系。
另外你原代码中在aes()外部直接传入color = 数据集$列名的写法存在数据错位风险,所有映射关系都应写在aes()内部。
实现方法
两种方案都能保留你要的「两个数据集分别用Blues、Reds色系,同数据集内一周7天按同色系深浅区分」的效果:
方案1:手动预生成配色(无额外依赖)
不需要安装第三方包,提前用ColorBrewer生成两个色系的对应颜色,合并为统一色板后用scale_color_manual()统一映射即可,注意要给两个数据集的Day分组加前缀避免重名冲突:
library(RColorBrewer) library(ggplot2) # 1. 预处理数据,给分组加数据集标识,避免两个数据集的Day重名 day_levels <- c("Mon","Tue","Wed","Thu","Fri","Sat","Sun") # 替换成你自己的Day因子水平顺序 WISub1$Day <- factor(WISub1$Day, levels = day_levels) PBSub2$Day <- factor(PBSub2$Day, levels = day_levels) WISub1$group_id <- paste0("WI_", WISub1$Day) PBSub2$group_id <- paste0("PB_", PBSub2$Day) # 2. 生成两个色系的配色,和分组名绑定 wi_cols <- brewer.pal(length(day_levels), "Blues") names(wi_cols) <- paste0("WI_", day_levels) pb_cols <- brewer.pal(length(day_levels), "Reds") names(pb_cols) <- paste0("PB_", day_levels) all_cols <- c(wi_cols, pb_cols) # 3. 绘图 ggplot() + geom_line(data = WISub1, aes(x = STH, y = pH, group = group_id, color = group_id), size = 1) + geom_line(data = PBSub2, aes(x = STH, y = pH, group = group_id, color = group_id), size = 1) + scale_color_manual(values = all_cols, name = "Group") + theme_dark() + ggtitle("TITLE") + xlab("Standing time (hours)") + scale_x_continuous(breaks = c(0,4,8,12,16,20,24)) + scale_y_continuous(limits = c(6,8))
方案2:用ggnewscale包实现多套色阶(代码更简洁)
ggnewscale包可以重置当前美学维度的标度,让后续图层使用全新的色阶设置,不需要手动改分组名、预生成配色:
library(ggplot2) library(ggnewscale) ggplot() + # 绘制第一个数据集,绑定Blues色阶 geom_line(data = WISub1, aes(x = STH, y = pH, group = Day, color = Day), size = 1) + scale_color_brewer(palette = "Blues", name = "WISub1 - Day") + # 重置color标度,后续图层不受前序色阶影响 new_scale_color() + # 绘制第二个数据集,绑定Reds色阶 geom_line(data = PBSub2, aes(x = STH, y = pH, group = Day, color = Day), size = 1) + scale_color_brewer(palette = "Reds", name = "PBSub2 - Day") + theme_dark() + ggtitle("TITLE") + xlab("Standing time (hours)") + scale_x_continuous(breaks = c(0,4,8,12,16,20,24)) + scale_y_continuous(limits = c(6,8))
如果需要调整图例顺序、合并图例,可以在方案1的基础上自定义
scale_color_manual的breaks参数实现,不需要额外改核心绘图逻辑。
内容的提问来源于stack exchange,提问作者Paul Wild
相关产品推荐
相关产品推荐

