求助:用ggplot绘制混合变量堆叠条形图(多调色板+分类图例)
我希望使用ggplot绘制堆叠条形图,横轴为变量,这些变量的响应类型不同:部分为Y/N二分类、部分为Old/Young二分类、还有部分为0-5的Likert量表。需为不同类型的变量分配不同的调色板,并添加能体现不同调色板/变量类型的图例。附上示例数据代码,恳请协助实现。
X1<-c("N","N","N","N","Y","N","Y","N","N","N","N","N","Y","N","N","Y","N","N","N","Y","N","Y","Y","N","N","Y","Y","Y","N","N","N","N","N","N","N","N","Y","N","Y","N","N","N","N","Y","N","N","Y","N","Y","Y","N","Y","N","N") X2 <-c("N","N","N","N","Y","N","Y","N","N","N","N","N","Y","N","N","Y","N","N","N","Y","N","Y","Y","N","N","Y","Y","Y","N","N","N","N","N","N","N","N","Y","N","Y","N","N","N","N","Y","N","N","Y","N","Y","Y","N","Y","N","N") X3<-c(1,1,0,1,2,0,0,0,0,0,1,1,1,2,0,1,2,1,1,0,0,0,4,1,0,0,0,0,1,0,2,0,0,2,1,1,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,1) X4 <-c("YouNg","Old","Old","YouNg","Old","Old","Old","YouNg","YouNg","YouNg","Old","Old","Old", "Old","Old","Old","Old","YouNg","Old","Old","Old","YouNg","YouNg","Old","Old","Old", "Old","Old","Old","Old","Old","Old","Old","YouNg","Old","YouNg","Old","YouNg","Old", "Old","YouNg","Old","YouNg","YouNg","Old","Old","Old","YouNg","Old","Old","Old","YouNg", "Old", "Old") Y <- data.frame(X1, X2, X3, X4)
解决方案
核心思路
- 将宽格式数据转换为长格式,适配ggplot的绘图逻辑
- 为每个变量标记类型,便于区分调色板
- 为不同类型变量自定义专属调色板,避免颜色混淆
- 通过图例分组和辅助标注,清晰展示变量类型与对应颜色的关系
完整代码实现
# 加载依赖包 library(ggplot2) library(dplyr) library(tidyr) library(stringr) # 用户提供的示例数据 X1<-c("N","N","N","N","Y","N","Y","N","N","N","N","N","Y","N","N","Y","N","N","N","Y","N","Y","Y","N","N","Y","Y","Y","N","N","N","N","N","N","N","N","Y","N","Y","N","N","N","N","Y","N","N","Y","N","Y","Y","N","Y","N","N") X2 <-c("N","N","N","N","Y","N","Y","N","N","N","N","N","Y","N","N","Y","N","N","N","Y","N","Y","Y","N","N","Y","Y","Y","N","N","N","N","N","N","N","N","Y","N","Y","N","N","N","N","Y","N","N","Y","N","Y","Y","N","Y","N","N") X3<-c(1,1,0,1,2,0,0,0,0,0,1,1,1,2,0,1,2,1,1,0,0,0,4,1,0,0,0,0,1,0,2,0,0,2,1,1,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,1) X4 <-c("YouNg","Old","Old","YouNg","Old","Old","Old","YouNg","YouNg","YouNg","Old","Old","Old", "Old","Old","Old","Old","YouNg","Old","Old","Old","YouNg","YouNg","Old","Old","Old", "Old","Old","Old","Old","Old","Old","Old","YouNg","Old","YouNg","Old","YouNg","Old", "Old","YouNg","Old","YouNg","YouNg","Old","Old","Old","YouNg","Old","Old","Old","YouNg", "Old", "Old") Y <- data.frame(X1, X2, X3, X4) # 1. 数据预处理:宽转长 + 标记变量类型 + 统一响应文本格式 Y_long <- Y %>% pivot_longer(cols = everything(), names_to = "variable", values_to = "response") %>% mutate( # 统一X4的大小写(YouNg转为Young) response = ifelse(variable == "X4", str_to_title(response), as.character(response)), # 标记变量所属类型 var_type = case_when( variable %in% c("X1", "X2") ~ "Y/N 二分类", variable == "X4" ~ "Old/Young 二分类", variable == "X3" ~ "0-5 Likert量表" ) ) %>% arrange(var_type, response) # 确保堆叠顺序一致 # 2. 自定义分类型调色板 palettes <- list( "Y/N 二分类" = c("N" = "#1f77b4", "Y" = "#ff7f0e"), "Old/Young 二分类" = c("Old" = "#2ca02c", "Young" = "#d62728"), "0-5 Likert量表" = c("0" = "#f8f9fa", "1" = "#e9ecef", "2" = "#dee2e6", "3" = "#ced4da", "4" = "#adb5bd", "5" = "#6c757d") ) combined_palette <- unlist(palettes) # 合并为ggplot可用的向量 # 3. 绘制堆叠条形图 ggplot(Y_long, aes(x = variable, fill = interaction(response, var_type, sep = " - "))) + geom_bar(position = "fill") + # 绘制百分比堆叠图 scale_fill_manual( values = combined_palette, name = "响应类别", labels = function(x) gsub("(.*) - (.*)", "\\1", x), # 拆分图例标签,只显示响应值 guide = guide_legend( ncol = 1, keyheight = unit(0.8, "cm"), override.aes = list(size = 0.5) ) ) + # 添加变量类型的顶部标注 annotate("text", x = 1.5, y = 1.05, label = "Y/N 二分类", size = 4, fontface = "bold") + annotate("text", x = 3, y = 1.05, label = "Old/Young 二分类", size = 4, fontface = "bold") + annotate("text", x = 4, y = 1.05, label = "0-5 Likert量表", size = 4, fontface = "bold") + # 调整坐标轴与主题 labs(y = "比例", x = "变量") + theme_minimal() + theme( legend.position = "right", axis.text.x = element_text(angle = 45, hjust = 1), plot.margin = margin(t = 20, r = 20, b = 20, l = 20) )
关键细节说明
- 数据转换:使用
pivot_longer将多列变量合并为"变量-响应"的长格式,同时统一X4的文本格式,避免因大小写导致的类别拆分。 - 调色板设计:为三类变量分别设置差异化色系:Y/N用蓝橙对比色、Old/Young用绿红对比色、Likert量表用灰度渐变,直观区分不同变量类型的响应。
- 图例优化:通过
interaction绑定响应与变量类型,再拆分标签只显示响应值,同时在图表顶部标注变量类型,解决不同类型变量的图例区分问题。 - 百分比堆叠:使用
position = "fill"将条形图转换为百分比比例,便于跨变量的类别分布对比。
内容的提问来源于stack exchange,提问作者EB3112
相关产品推荐
相关产品推荐

