如何用ggh4x的facet_nested_wrap实现顶层分面仅显一次并分两列
解决方案
针对你的两个需求,可通过调整ggh4x的分面布局与strip设置实现:
1. 分两列展示hap1和hap2
用facet_nested_grid替代facet_nested_wrap,将haplotype指定为列变量,自然按hap1和hap2分为两列。
2. 顶层分面仅显示一次
借助strip_nested的bleed参数,让列方向的haplotype分面标签跨对应行合并显示,避免每行重复。
修改后的完整代码
library(readr) library(ggh4x) library(ggplot2) library(RColorBrewer) df_joint <- readr::read_tsv("path/to/samples_model3p_nest.tsv") df_joint$strandness <- factor(df_joint$strandness, levels=c('+', '-')) ### 自定义分面strip custom_strip <- strip_nested( # 列方向(haplotype)的strip设置 col = strip_vanilla( background_x = elem_list_rect(fill = brewer.pal(12, "Set3")[c(7, 6)]), # 对应hap1、hap2的背景色 text_x = elem_list_text(face = "bold") ), # 行方向(id)的strip设置 row = strip_vanilla( background_y = elem_list_rect(fill = rep(brewer.pal(12, "Set3")[9], length(unique(df_joint$id)))), # 所有id用统一背景色 text_y = elem_list_text(face = "plain") ), bleed = TRUE # 确保顶层haplotype标签仅显示一次 ) ### 绘图部分 both <- ggplot(df_joint, aes(as.factor(kpattern), fill=strandness)) + geom_bar() + theme_bw() + theme( axis.text.x = element_blank(), axis.ticks.x = element_blank(), panel.grid.major = element_blank(), plot.title = element_text(face='bold', hjust=.5), legend.title = element_text(face='italic'), legend.position.inside = c(0.8, 0.05) ) + guides(fill = guide_legend(ncol=2, keywidth=1, position="inside")) + labs(x=expression(italic("k")*"-"*patterns~distribution)) + scale_fill_manual(values=c("+"="red", "-"="blue")) + coord_cartesian(ylim=c(0,125), expand=FALSE) # 应用嵌套网格分面 both + facet_nested_grid( cols = vars(haplotype), rows = vars(id), strip = custom_strip, ncol = 2 # 强制两列(因haplotype只有两个水平,此参数可省略) )
关键说明
facet_nested_grid将haplotype设为列变量,直接实现两列布局,每列对应一个单倍型。strip_nested的bleed=TRUE参数让列方向的顶层分面(haplotype)跨所有行合并显示,避免重复。- 保留了你原有的配色、主题与柱状图结构,仅调整分面逻辑以匹配需求。
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

