如何按组堆叠箱线图:同组并列、不同组上下排列
分组箱线图的正确实现方案
问题背景
现有一个包含12列的data.frame,按列名分为3组:
- 前4列:Gene_1组(列名以Gene_1开头)
- 第5-8列:Gene_2组(列名以Gene_2开头)
- 第9-12列:Gene_3组(列名以Gene_3开头)
所有列均为连续数值型数据,需求是:
- 同组内的4个箱线图并列展示
- 不同组的箱线图上下堆叠成3行
之前尝试的ggplot2代码导致所有箱线图并列显示,X轴混乱,需要修正实现方式。
数据示例(子集)
df <- structure(list(Gene_1_TL1= c(0.382992297410965, 0.460950464010239, 0.447804838418961, 0.447804838418961, 0.460950464010239, 0.447804838418961, 0.369836807250977, 0.447804838418961, 0.369836807250977, 0.447804838418961 ), Gene_1_TL2= c(0.460011065006256, 0.52004611492157, 0.253930300474167, 0.222006008028984, 0.302200853824615, 0.485153168439865, 0.20485857129097, 0.350892871618271, 0.331338971853256, 0.295754462480545), Gene_1_TL3= c(0.277256995439529, 0.425392180681229, 0.182383552193642, 0.253527283668518, 0.329186052083969, 0.305586904287338, 0.188975885510445, 0.238625407218933, 0.497761845588684, 0.342641144990921), Gene_1_TL4= c(0.565486133098602, 0.564990341663361, 0.164183273911476, 0.15946152806282, 0.234778091311455, 0.396436214447021, 0.172556579113007, 0.257463246583939, 0.43759897351265, 0.200696632266045), Gene_2_TL1= c(0.0779446139931679, 0.274154871702194, 0.0718425810337067, 0.0718425810337067, 0.274154871702194, 0.0718425810337067, 0.160841777920723, 0.0718425810337067, 0.160841777920723, 0.0718425810337067 ), Gene_2_TL2= c(0.0662130266427994, 0.258626192808151, 0.0601647943258286, 0.060332003980875, 0.141631454229355, 0.113691322505474, 0.0786028951406479, 0.0668068528175354, 0.171470999717712, 0.0754544585943222), Gene_2_TL3= c(0.144175127148628, 0.145591989159584, 0.0984272509813309, 0.0906868129968643, 0.28544145822525, 0.138114541769028, 0.091837003827095, 0.0904595032334328, 0.211963757872581, 0.163982316851616), Gene_2_TL4= c(0.118267595767975, 0.199180424213409, 0.0867970511317253, 0.0653180256485939, 0.203389659523964, 0.149213299155235, 0.126333728432655, 0.0975232273340225, 0.256154090166092, 0.146669581532478), Gene_3_TL1= c(0.287342727184296, 0.417357206344604, 0.255898356437683, 0.255898356437683, 0.417357206344604, 0.255898356437683, 0.471998482942581, 0.255898356437683, 0.471998482942581, 0.255898356437683 ), Gene_3_TL2= c(0.299634903669357, 0.418549239635468, 0.424916654825211, 0.432371437549591, 0.584436595439911, 0.296403467655182, 0.563782930374146, 0.3688924908638, 0.578023612499237, 0.278784334659576), Gene_3_TL3= c(0.314525783061981, 0.343217849731445, 0.315391361713409, 0.353350460529327, 0.562197327613831, 0.292534917593002, 0.616392850875854, 0.284660279750824, 0.532478809356689, 0.341239869594574), Gene_3_TL4= c(0.216887220740318, 0.283130913972855, 0.248720198869705, 0.421182304620743, 0.564142644405365, 0.204288363456726, 0.778401911258698, 0.272624760866165, 0.511143803596497, 0.186424404382706)), row.names = c("04d83340b8bd", "122T", "1c2a5ac94492", "1d209304d988", "212T", "24ab7fecc92e", "356T", "379fe8924c51", "39T", "3ec4d3fc8bd1"), class = "data.frame")
错误代码分析
之前的代码存在两个关键问题:
facet_grid(. ~ gsub("\\d", "", variable))使用列方向分面,导致所有组的箱线图横向并列,不符合上下堆叠的需求gsub("\\d", "", variable)的正则表达式错误,会把Gene_1变成Gene_,无法正确区分Gene_1/Gene_2/Gene_3三组
正确实现代码
library(reshape2) library(ggplot2) # 1. 融化数据 df_melted <- melt(df) # 2. 拆分列名,生成基因组和TL编号两个变量 df_melted$gene_group <- gsub("_TL\\d+", "", df_melted$variable) df_melted$tl <- gsub("Gene_\\d+_", "", df_melted$variable) # 3. 绘制分组箱线图 boxplot <- ggplot(df_melted, aes(x = tl, y = value)) + geom_boxplot(fill = "#619CFF") + # 按gene_group分行,上下堆叠 facet_grid(gene_group ~ ., scales = "free_y") + labs(x = "TL编号", y = "数值") + theme_bw() + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), axis.line = element_line(colour = "black"), strip.text.y = element_text(size = 12, face = "bold") ) print(boxplot)
代码说明
- 拆分列名:通过正则表达式分别提取
gene_group(Gene_1/Gene_2/Gene_3)和tl(TL1/TL2/TL3/TL4),让ggplot能明确区分分组和同组内的类别 - 分面设置:使用
facet_grid(gene_group ~ .)实现行方向分面,不同基因组的箱线图上下堆叠;scales = "free_y"允许每行的Y轴刻度独立,适配不同组的数据范围 - 样式调整:添加了填充色、坐标轴标签和分面标题样式,提升图表可读性
内容的提问来源于stack exchange,提问作者Programming Noob
相关产品推荐
相关产品推荐

