作为一名长期从事生物信息学可视化的研究者,我最近在复现Nature论文中的图表时遇到一个典型挑战——如何在没有原始数据的情况下,准确还原作者的数据呈现方式。今天要分享的是AlphaGenome与Borzoi模型性能比较的小提琴图复现过程。
这个项目的核心价值在于:
原图(Nature 649卷1206-1218页)包含以下关键视觉元素:
坐标系统:
数据表示:
统计标注:
这张图巧妙展示了:
提示:在生物信息学可视化中,同时呈现原始数据分布和统计摘要至关重要,这也是Nature级别图表的基本要求。
根据论文补充材料,原始数据具有以下特征:
| 特征 | AlphaGenome | Borzoi |
|---|---|---|
| 数据点范围 | 0.35-0.68 | 0.32-0.65 |
| 均值趋势 | 随距离缓慢下降 | 下降更明显 |
| 离散程度 | 标准差约0.05 | 标准差约0.07 |
使用R生成符合上述特征的模拟数据:
r复制set.seed(123)
dist_thresholds <- c(50, 100, 200, 300, 500, 2000, 10000)
n_samples <- sample(111:613, length(dist_thresholds), replace=TRUE)
simulate_data <- function(thresh, n, baseline, sd) {
trend <- 0.00002 * (10000 - thresh)
rnorm(n, mean=baseline + trend, sd=sd)
}
alpha_data <- unlist(lapply(seq_along(dist_thresholds), function(i) {
simulate_data(dist_thresholds[i], n_samples[i], 0.55, 0.05)
}))
borzoi_data <- unlist(lapply(seq_along(dist_thresholds), function(i) {
simulate_data(dist_thresholds[i], n_samples[i], 0.52, 0.07)
}))
整理为tidy格式数据框:
r复制library(tidyverse)
df <- data.frame(
Distance = rep(rep(dist_thresholds, n_samples), 2),
Method = rep(c("AlphaGenome", "Borzoi"), each=sum(n_samples)),
auPRC = c(alpha_data, borzoi_data)
) %>%
group_by(Distance, Method) %>%
mutate(n = n()) %>%
ungroup()
使用ggplot2构建基础图层:
r复制library(ggplot2)
library(ggbeeswarm)
base_plot <- ggplot(df, aes(x=factor(Distance), y=auPRC, color=Method)) +
geom_quasirandom(
aes(group=interaction(Distance, Method)),
dodge.width=0.8,
alpha=0.6,
size=1.5
) +
scale_color_manual(values=c("#1f77b4", "#2ca02c")) +
theme_minimal(base_size=14)
添加统计摘要和标注:
r复制final_plot <- base_plot +
stat_summary(
fun.data=mean_cl_normal,
geom="pointrange",
size=0.8,
position=position_dodge(width=0.8)
) +
geom_text(
aes(y=0.28, label=paste0("n=",n)),
position=position_dodge(width=0.8),
color="black",
size=3.5
) +
labs(
x="Distance threshold (bp)",
y="auPRC",
title="Performance comparison across distance thresholds",
subtitle="Points show individual benchmark results, error bars represent 95% CI"
) +
theme(
legend.position="top",
panel.grid.major.x=element_blank()
)
| 参数 | 作用 | 推荐值 | 注意事项 |
|---|---|---|---|
| dodge.width | 方法间间距 | 0.7-0.9 | 避免重叠同时保持紧凑 |
| alpha | 点透明度 | 0.5-0.7 | 平衡重叠识别和视觉突出 |
| beeswarm width | 点云宽度 | 0.3-0.4 | 控制水平扩散程度 |
| pointrange size | 误差线粗细 | 0.7-1.0 | 确保清晰可见但不突兀 |
数据-墨水比优化:
多重比较标注:
r复制# 添加统计检验示例
library(ggsignif)
final_plot +
geom_signif(
comparisons=list(c("AlphaGenome", "Borzoi")),
test="t.test",
map_signif_level=TRUE,
y_position=0.7
)
问题1:点云过度重叠
position_jitter和geom_quasirandomr复制geom_quasirandom(
method="smiley",
varwidth=TRUE,
bandwidth=0.5
)
问题2:小样本量可视化失真
r复制geom_violin(scale="count", trim=FALSE)
问题3:多面板协调
r复制library(patchwork)
(plot1 + plot2) +
plot_layout(guides="collect") &
scale_y_continuous(limits=c(0.3, 0.7))
r复制library(tidyverse)
library(ggbeeswarm)
library(ggsignif)
# 数据生成
set.seed(123)
dist_thresholds <- c(50, 100, 200, 300, 500, 2000, 10000)
n_samples <- sample(111:613, length(dist_thresholds), replace=TRUE)
simulate_data <- function(thresh, n, baseline, sd) {
trend <- 0.00002 * (10000 - thresh)
rnorm(n, mean=baseline + trend, sd=sd)
}
df <- data.frame(
Distance = rep(rep(dist_thresholds, n_samples), 2),
Method = rep(c("AlphaGenome", "Borzoi"), each=sum(n_samples)),
auPRC = c(
unlist(lapply(seq_along(dist_thresholds), function(i) {
simulate_data(dist_thresholds[i], n_samples[i], 0.55, 0.05)
})),
unlist(lapply(seq_along(dist_thresholds), function(i) {
simulate_data(dist_thresholds[i], n_samples[i], 0.52, 0.07)
}))
)
) %>%
group_by(Distance, Method) %>%
mutate(n = n()) %>%
ungroup()
# 可视化
ggplot(df, aes(x=factor(Distance), y=auPRC, color=Method)) +
geom_quasirandom(
aes(group=interaction(Distance, Method)),
dodge.width=0.8,
alpha=0.6,
size=1.5,
method="smiley"
) +
stat_summary(
fun.data=mean_cl_normal,
geom="pointrange",
size=0.8,
position=position_dodge(width=0.8)
) +
geom_text(
aes(y=0.28, label=paste0("n=",n)),
position=position_dodge(width=0.8),
color="black",
size=3.5
) +
geom_signif(
comparisons=list(c("AlphaGenome", "Borzoi")),
test="t.test",
map_signif_level=TRUE,
y_position=0.68,
tip_length=0.01
) +
scale_color_manual(values=c("#1f77b4", "#2ca02c")) +
labs(
x="Distance threshold (bp)",
y="auPRC",
color="Method",
title="Performance comparison across distance thresholds",
caption="Simulated data based on Nature 649, 1206–1218 (2026)"
) +
theme_minimal(base_size=14) +
theme(
legend.position="top",
panel.grid.major.x=element_blank(),
plot.title=element_text(face="bold")
)
当获得真实数据时,只需替换数据生成部分:
准备CSV数据应包含列:
数据导入:
r复制real_data <- read_csv("your_data.csv") %>%
group_by(Distance, Method) %>%
mutate(n = n())
可视化代码保持不变,只需更改数据源:
r复制ggplot(real_data, aes(...)) + ...
该方法适用于:
我在最近一个ChIP-seq分析项目中,使用类似方法比较了三种peak calling工具的性能差异,通过这种可视化清晰地展示了各工具在不同信号强度区间的相对优劣。