如何为ggplot蝴蝶图的不同Arm设置差异化配色方案
实现分Arm独立配色+多图例的ggplot蝴蝶图
核心解决思路是用ggnewscale包来创建多个独立的填充图例,同时为每个Arm的类别分配专属色系。以下是完整实现步骤和代码:
1. 准备样本数据(模拟你的数据结构)
library(tidyverse) library(ggnewscale) # 模拟样本数据 set.seed(123) df <- tibble( Arm = rep(c("Arm 1", "Arm 2"), each = 3), Category = rep(c("Category 1", "Category 2", "Category 3"), 2), Value = c(-sample(1:10, 3), sample(1:10, 3)) # Arm1取负对应左半边,Arm2取正对应右半边 )
2. 分Arm设置专属配色
给每个Arm的类别定义不同深浅的专属色系:
# Arm1蓝色系配色 arm1_cols <- c("#cce5ff", "#99c2ff", "#66a8ff") names(arm1_cols) <- unique(df$Category[df$Arm == "Arm 1"]) # Arm2红色系配色 arm2_cols <- c("#ffcccc", "#ff9999", "#ff6666") names(arm2_cols) <- unique(df$Category[df$Arm == "Arm 2"])
3. 绘制带双图例的蝴蝶图
关键是用ggnewscale::new_scale_fill()重置填充标尺,实现多图例:
ggplot(df, aes(x = Value, y = Category)) + # 绘制Arm1的条形(左半边) geom_col(data = filter(df, Arm == "Arm 1"), aes(fill = Category), width = 0.7) + # 设置Arm1的填充色和图例 scale_fill_manual(name = "Arm 1", values = arm1_cols) + # 重置填充标尺,为Arm2准备独立图例 new_scale_fill() + # 绘制Arm2的条形(右半边) geom_col(data = filter(df, Arm == "Arm 2"), aes(fill = Category), width = 0.7) + # 设置Arm2的填充色和图例 scale_fill_manual(name = "Arm 2", values = arm2_cols) + # 调整坐标轴和主题,优化蝴蝶图展示 scale_x_continuous(breaks = seq(-10, 10, 5), labels = abs(seq(-10, 10, 5))) + # 把负轴标签转成正数,更符合蝴蝶图阅读习惯 labs(x = "Count", y = "") + theme_minimal() + theme(legend.position = "bottom", legend.box = "horizontal")
关键说明
ggnewscale是实现多填充图例的核心,它允许在同一张图中添加多个独立的填充标尺,完美匹配你"每个Arm对应一个图例"的需求。- 配色可以灵活调整,比如用
RColorBrewer的brewer.pal()生成更专业的色系:Arm1用brewer.pal(3, "Blues"),Arm2用brewer.pal(3, "Reds")。 - 如果你的原始数据中Arm1的数值不是负数,记得提前用
mutate(Value = ifelse(Arm == "Arm 1", -Value, Value))处理,确保左右分栏的蝴蝶图效果。
内容的提问来源于stack exchange,提问作者user2272972
相关产品推荐
相关产品推荐

