如何在ggplot离散y轴类别间添加自定义p值括号
问题
我拥有如下数据集:
plot2=structure(list(partition = c("2", "2b", "2c"), partition_name = structure(1:3, levels = c("Cardiac_significant_enh partition PRS Original OR", "Cardiac_significant_enh partition PRS OR × enh_ES", "Cardiac_significant_enh partition PRS OR × enh_TS_tpm" ), class = c("ordered", "factor")), Num_SNP = c(3157, 3157, 3157 ), CoD_per_SNP = c(62.1186923796969, 61.1820673263678, 60.9483894486912 ), R2 = c(0.0196108711842703, 0.0193151786549343, 0.0192414065489518 ), LCL = c(0.010974448167152, 0.0135183879280951, 0.0112302824404708 ), UCL = c(0.0282472942013886, 0.0251119693817734, 0.0272525306574328 ), R2type = c("Lee", "Lee", "Lee"), xlabel = structure(c(3L, 1L, 2L), levels = c("Cardiac significant enh\npartition PRS OR × enh ES (SNP\nN=3157)", "Cardiac significant enh\npartition PRS OR × enh TS tpm\n(SNP N=3157)", "Cardiac significant enh\npartition PRS Original OR (SNP\nN=3157)" ), class = "factor")), row.names = 4:6, class = "data.frame")
并通过以下代码绘制了ggplot图表:
ggplot(data = plot2, aes( y=reorder(plot2$xlabel, desc(partition)), x=plot2$R2*100, xmin = plot2$LCL*100, xmax=plot2$UCL*100, colour=plot2$R2type,group=plot2$R2type # label=round(R2*100,2) )) + geom_pointrange( position=pos, size=1, lwd=1) + scale_color_manual(values=MetBrewer::met.brewer("Johnson", 2), expression(paste(R^2)))+ ggrepel::geom_label_repel( aes( y=reorder(xlabel, desc(partition)), x=R2*100, colour=R2type,group=R2type, label=round(R2*100,2) ), position = pos, size = rel(4), show.legend = F,min.segment.length = 0, point.padding = NA, box.padding = 0.5)+ #nudge_y = -0.2, scale_x_continuous(limits = c(0, NA), expand = expansion(mult = c(0, .15))) + scale_y_discrete(expand = expansion(add = .7)) + #.6 is default - add a little spacing to the sides xlab("") + ylab(paste0("HCM diagnosis ~"))+theme_bw() + theme( legend.position = "none", text=element_text(lineheight = 0.8, angle = 0, size = 21, color = "gray8") )
当前图表的分类变量位于y轴,我希望使用ggpubr包的geom_bracket()函数在离散y轴的不同类别间添加自定义p值括号,但该函数默认仅支持对离散x轴的类别进行比较。我需要实现能够选择特定两两比较(例如第一行与第三行类别)并添加自定义p值括号的效果。
解决方案
geom_bracket()本质是通过坐标定位绘制括号,针对y轴离散类别的场景,只需手动映射离散y值对应的数值位置,再指定括号的水平位置即可实现需求。
步骤1:确认离散y轴的数值映射
ggplot中离散y轴的类别默认按从下到上的顺序对应数值1、2、3...。结合你的代码reorder(xlabel, desc(partition)),最终y轴从上到下的类别及对应数值为:
- "Cardiac significant enh\npartition PRS Original OR (SNP\nN=3157)" → 数值3
- "Cardiac significant enh\npartition PRS OR × enh ES (SNP\nN=3157)" → 数值2
- "Cardiac significant enh\npartition PRS OR × enh TS tpm\n(SNP N=3157)" → 数值1
若要比较第一行(最上方,数值3)和第三行(最下方,数值1),直接使用这两个数值作为括号的y起始/结束位置即可。
步骤2:修改代码添加自定义括号
在原有ggplot代码基础上,添加geom_bracket()层,指定括号的水平位置、y轴对应数值和自定义p值标签:
完整修改后的代码如下:
library(ggplot2) library(ggrepel) library(ggpubr) library(MetBrewer) # 补充原代码未定义的position参数 pos <- position_dodge(width = 0.5) ggplot(data = plot2, aes( y = reorder(xlabel, desc(partition)), x = R2*100, xmin = LCL*100, xmax = UCL*100, colour = R2type, group = R2type )) + geom_pointrange(position = pos, size = 1, lwd = 1) + scale_color_manual(values = MetBrewer::met.brewer("Johnson", 2), name = expression(paste(R^2)))+ ggrepel::geom_label_repel( aes( x = R2*100, label = round(R2*100,2) ), position = pos, size = rel(4), show.legend = F, min.segment.length = 0, point.padding = NA, box.padding = 0.5)+ scale_x_continuous(limits = c(0, 3.5), expand = expansion(mult = c(0, .15))) + scale_y_discrete(expand = expansion(add = .7)) + xlab("") + ylab(paste0("HCM diagnosis ~"))+theme_bw() + # 添加自定义p值括号 geom_bracket( x = 3.2, # 括号水平位置,避开数据点范围 y.position = c(3, 1), # 要比较的两个y类别对应数值 label = "p = 0.85", # 自定义p值 tip.length = 0.02, # 括号尖端长度 size = 1, # 括号线条粗细 color = "gray8" ) + theme( legend.position = "none", text = element_text(lineheight = 0.8, angle = 0, size = 21, color = "gray8") )
关键说明
- 若要比较其他类别,只需调整
y.position的数值(比如比较前两个类别用c(3,2))。 x参数需设置在x轴数据范围之外(原数据UCL*100最大约2.82,设为3.2可避免重叠),可根据需求灵活调整。- 如需添加多组括号,重复调用
geom_bracket(),每组设置对应的y.position和label即可。
内容的提问来源于stack exchange,提问作者Emos
相关产品推荐
相关产品推荐

