You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot中设置嵌套分面,让变异类型分面跨全图宽度

解决ggh4x嵌套分面宽度适配与工具对应问题

问题描述

我使用DeepVariant和PanGenie两种工具分析了SNPs、INDELs和SVs变异:DeepVariant仅评估SNPs和INDELs,PanGenie更适配SVs。当前用ggplot2结合ggh4x绘制的分面图中,各变异类型分面未占满整个图宽,希望设置嵌套分面,让SNPs/INDELs及SVs分面拉伸至全图宽度,同时将DeepVariant和PanGenie作为左侧嵌套分面对应各自评估的变异类型。

原代码

library(grid)
library(ggh4x)
library(readxl)
library(scales)
library(ggdark)
library(ggpubr)
library(gtable)
library(ggplot2)
library(forcats)
library(reshape2)
library(ggchicklet) #round column
library(RColorBrewer)

excel <- read_excel("/media/mat/Extreme SSD/TheUniversityOfFerrara/3°Year/pangenie_giraffe-dv_orth_val.xlsx") # load spreadsheet

df <- data.frame(excel) # convert excel to dataframe

df$variant_type <- factor(df$variant_type, levels=c('SNPs', 'INDELs', 'SVs')) # order of variants to be displayed
df$metric <- factor(df$metric, levels=c('recall', 'precision', 'F1')) # order of metrics to be shown

df_2 <- with(df, df[order(variant_type, caller, graph, metric),]) # collapses fields with the same entry

### Personalized stripes
ridiculous_strips <- strip_themed(
  ## Horizontal strips
  background_x = elem_list_rect(fill=c("#f9ab00", "#ffaaaa")),
  text_x = elem_list_text(colour=c("black", "black"), face=c("bold", "bold")),
  by_layer_x = FALSE,
  
  ## Vertical strips
  background_y = elem_list_rect(fill = c("slategray3", "slategray3", "slategray3")),
  by_layer_y = FALSE
)

### PLOT orthogonal validation of variants callers and graphs used
variants_eval <- ggplot(df_2, aes(x=metric, y=value, fill=graph)) + geom_point(shape=21, alpha=.6, size=3)
ggplot(df_2, aes(x=metric, y=value, fill=graph)) + geom_point(shape=21, alpha=.6, size=3) +
  ggh4x::facet_grid2(variant_type ~ caller, scales='free', switch='y', independent='y', strip=ridiculous_strips) + scale_fill_manual(values=rev(brewer.pal(11, "RdBu")[c(1, 11)])) +
  guides(fill=guide_legend(title='assembly', title.position='top', title.hjust=.5, title.theme=element_text(face='italic'))) + ggtitle("variant_calling — effect of alignment tool and graph used") +
  theme_bw() + theme(plot.title=element_text(face='bold.italic', hjust=.5), legend.position='bottom') -> callers_graphs
callers_graphs

修改后的代码

library(grid)
library(ggh4x)
library(readxl)
library(scales)
library(ggdark)
library(ggpubr)
library(gtable)
library(ggplot2)
library(forcats)
library(reshape2)
library(ggchicklet) #round column
library(RColorBrewer)

excel <- read_excel("/media/mat/Extreme SSD/TheUniversityOfFerrara/3°Year/pangenie_giraffe-dv_orth_val.xlsx") # load spreadsheet

df <- data.frame(excel) # convert excel to dataframe

# 定义变异类型顺序
df$variant_type <- factor(df$variant_type, levels=c('SNPs', 'INDELs', 'SVs'))
# 定义指标顺序
df$metric <- factor(df$metric, levels=c('recall', 'precision', 'F1'))

# 添加变异分组变量:将SNPs/INDELs归为一组,SVs单独一组
df$variant_group <- ifelse(df$variant_type %in% c("SNPs", "INDELs"), 
                           "Small Variants (SNPs/INDELs)", 
                           "Structural Variants (SVs)")
df$variant_group <- factor(df$variant_group, 
                           levels = c("Small Variants (SNPs/INDELs)", "Structural Variants (SVs)"))

# 过滤无效数据:移除DeepVariant对应的SVs数据(因为DeepVariant不评估SVs)
df_2 <- df[!(df$caller == "DeepVariant" & df$variant_type == "SVs"), ]
# 排序数据
df_2 <- df_2[order(df_2$variant_group, df_2$variant_type, df_2$caller, df_2$graph, df_2$metric), ]

### 适配嵌套分面的自定义主题
ridiculous_strips <- strip_themed(
  # 外层横向分面(变异分组)
  background_x = elem_list_rect(fill = c("#f9ab00", "#ffaaaa")),
  text_x = elem_list_text(colour = "black", face = "bold"),
  # 内层横向分面(具体变异类型)
  background_x2 = elem_list_rect(fill = c("#f0e68c", "#dda0dd", "#98fb98")),
  text_x2 = elem_list_text(colour = "black", face = "italic"),
  by_layer_x = FALSE,
  
  # 纵向分面(工具)
  background_y = elem_list_rect(fill = c("slategray3", "slategray3")),
  text_y = elem_list_text(colour = "black", face = "bold"),
  by_layer_y = FALSE
)

### 绘制嵌套分面图
callers_graphs <- ggplot(df_2, aes(x=metric, y=value, fill=graph)) + 
  geom_point(shape=21, alpha=.6, size=3) +
  # 嵌套分面:行是工具,列是变异分组+具体变异类型;开启x轴自由宽度占满全图
  ggh4x::facet_grid2(rows = vars(caller), 
                     cols = vars(variant_group, variant_type), 
                     scales = "free", 
                     switch = "y", 
                     independent = "xy",
                     space = "free_x",
                     strip = ridiculous_strips) +
  scale_fill_manual(values=rev(brewer.pal(11, "RdBu")[c(1, 11)])) +
  guides(fill=guide_legend(title='assembly', title.position='top', title.hjust=.5, title.theme=element_text(face='italic'))) + 
  ggtitle("variant_calling — effect of alignment tool and graph used") +
  theme_bw() + 
  theme(
    plot.title=element_text(face='bold.italic', hjust=.5), 
    legend.position='bottom',
    # 调整分面标签间距与方向
    strip.placement = "outside",
    strip.text.y.left = element_text(angle = 0)
  )

callers_graphs

关键改动说明

  1. 添加变异分组变量:创建variant_group将SNPs/INDELs和SVs分为两组,为嵌套分面提供层级基础,确保同组变异类型的分面能共同占满全图宽度。
  2. 过滤无效数据:移除DeepVariant对应的SVs数据,避免出现无意义的空分面。
  3. 调整分面参数:使用facet_grid2的cols = vars(variant_group, variant_type)设置嵌套列分面,space = "free_x"让每个变异分组的分面自动拉伸至全图宽度;independent = "xy"确保各分面的坐标轴独立适配数据。
  4. 优化分面主题:为嵌套分面的外层(分组)和内层(具体变异类型)分别设置不同的背景色和文本样式,提升可读性。

内容的提问来源于stack exchange,提问作者Matteo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 21:47:56