

为了避免各位错过最新的推文教程,强烈建议大家将“科研后花园”设置为“星标”!


在转录组、蛋白质组等差异表达分析中,火山图(Volcano Plot)几乎是标配。但常规火山图往往将上调和下调基因的显著性堆叠在同一侧,视觉上容易混淆。
今天,我为大家带来一种 “双组分斜对角” 的火山图绘制方法。它的核心思路是:让上调基因的 -log10(pvalue) 向上显示,下调基因的 -log10(pvalue) 向下显示,从而在 y 轴方向上把“上”和“下”彻底分开。这样,一眼就能看出哪些基因上调显著、哪些下调显著,效果非常直观。
一、什么是“双组分斜对角”火山图?
常规火山图的横轴是 log2FC(正=上调,负=下调),纵轴是 -log10(pvalue)(越大越显著)。这种图存在一个小问题:上调和下调基因的显著点都集中在 y 轴正方向,如果上调基因数量远多于下调基因,视觉重心会明显偏移。
而“双组分”方案的核心变动在于:
上调基因:
y = -log10(pvalue)(正值,向上)下调基因:
y = log10(pvalue)(负值,向下)
这样:
上调基因显著 → 图的上方
下调基因显著 → 图的下方
不显著基因 → 聚集在 y=0 附近
整个图形呈现斜对角对称,信息辨识度极高。
二、数据准备与预处理
2.1 加载数据
你的数据文件 data.txt 必须包含以下三列:
log2FoldChange:差异倍数(对数)pvalue:显著性 P 值gene:基因名称(用于标注)
# 读取数据df <- read.table(file="data.txt",sep="\t",header=T,check.names=FALSE)

2.2 定义分组与标签
#数据分类df$group<-as.factor(ifelse(df$log2FoldChange>= 0 ,'up','down'))#标签df$label<-ifelse(df$pvalue<0.05&abs(df$log2FoldChange)>=4,"Y","N")df$label2<-ifelse(df$label == 'Y', as.character(df$gene), '')
这里采用了两个严格的过滤条件:
pvalue < 0.05:统计显著性abs(log2FoldChange) >= 4:生物学意义大(倍数变化 ≥ 16 倍)
你可以根据实际研究需求调整阈值。
2.3 计算双组分 y 轴值(关键步骤)
df$log10 <- ifelse(df$group == "down", log10(df$pvalue), -log10(df$pvalue))上调基因(
up):y = -log10(pvalue)→ 正值下调基因(
down):y = log10(pvalue)→ 负值
这样就把上下调基因的显著性在 y 轴方向物理分开了。
三、绘图模板详解
3.1 基础图层:散点 + 辅助线
ggplot(df, aes(log2FoldChange, log10)) +geom_vline(xintercept = 0, lty = 2, color = 'grey', lwd = 0.5) +geom_hline(yintercept = 0, lty = 1, color = 'black', lwd = 0.5) +geom_point(aes(color = log2FoldChange), size = 2)

垂直和水平线:区分上调和下调基因
散点颜色映射到
log2FoldChange,形成从蓝到白的连续渐变
3.2 高亮显著基因(标记为“Y”的点)
geom_point(data = df[df$label == "Y", ],aes(log2FoldChange, log10, fill = group),size = 2, shape = 21, color = "black", show.legend = FALSE)

只对
label == "Y"的基因(即显著且高倍变化的点)进行二次绘制使用
shape = 21(带边框的圆),边框为黑色,填充色根据group(up/down)区分这样显著基因会“浮”在普通点之上,视觉更突出
3.3 颜色方案:双向渐变色
scale_color_gradient2(high = "#b20f26", mid = "white", low = "#2c4398") +scale_fill_manual(values = c("up" = "#b20f26", "down" = "#2c4398"))
scale_color_gradient2:所有点根据log2FoldChange从蓝(负)到红(正)渐变
scale_fill_manual:显著点的填充色固定(红色=上调,蓝色=下调)
3.4 基因名称标注(避免重叠)
geom_text_repel(aes(label = label2),max.overlaps = 10000,nudge_x = 0.5,nudge_y = 0.5,size = 3,segment.curvature = -1e-10,arrow = arrow(length = unit(0.015, "npc")),direction = "x",hjust = "left")
geom_text_repel自动调整标签位置,避免相互遮盖每个显著基因都添加箭头指向对应的点,便于阅读
max.overlaps = 10000确保所有标签都能显示(若标签过多,可降低此值)
3.5 y 轴刻度处理
scale_y_continuous(limits = c(-4.6, 6.2),breaks = seq(-4.5, 6, 1.5),labels = c("4.5", "3", "1.5", "0", "1.5", "3", "4.5", "6"))
这里是一个“取巧”的做法:
实际 y 值范围为负(下调)到正(上调)
但刻度标签全部显示为正数(绝对值),配合副标题说明即可
这样做的好处是:上下调基因的显著程度可以直接用绝对值大小比较,而不必纠结正负号。
四、最终图形效果

运行完整代码后,你将得到一张:
左右斜对角对称的蝴蝶状火山图
上调基因分布在右上方,下调基因分布在左下方
显著基因被高亮并带有基因名称标签
颜色从蓝(低 log2FC)到白(中间)到红(高 log2FC)渐变
五、完整代码(可直接运行)
setwd('你的工作路径')library(ggplot2)library(ggrepel)df <- read.table("data.txt", header = TRUE, sep = "\t", check.names = FALSE)df$group <- as.factor(ifelse(df$log2FoldChange >= 0, 'up', 'down'))df$label <- ifelse(df$pvalue < 0.05 & abs(df$log2FoldChange) >= 4, "Y", "N")df$label2 <- ifelse(df$label == 'Y', as.character(df$gene), '')df$log10 <- ifelse(df$group == "down", log10(df$pvalue), -log10(df$pvalue))df %>%ggplot(aes(log2FoldChange, log10)) +geom_vline(xintercept = 0, lty = 2, color = 'grey', lwd = 0.5) +geom_hline(yintercept = 0, lty = 1, color = 'black', lwd = 0.5) +geom_point(aes(color = log2FoldChange), size = 2) +geom_point(data = df[df$label == "Y", ],aes(log2FoldChange, log10, fill = group),size = 2, shape = 21, color = "black", show.legend = FALSE) +theme_bw() +theme(panel.grid = element_blank(),axis.text = element_text(color = '#333c41', size = 10),legend.text = element_text(color = '#333c41', size = 10),axis.title = element_text(size = 12)) +labs(title = "volcanoplot",x = 'log2 fold change',y = '-log10 pvalue',fill = "log2FC") +scale_color_gradient2(high = "#b20f26", mid = "white", low = "#2c4398") +scale_fill_manual(values = c("up" = "#b20f26", "down" = "#2c4398")) +geom_text_repel(aes(label = label2),max.overlaps = 10000,nudge_x = 0.5,nudge_y = 0.5,size = 3,segment.curvature = -1e-10,arrow = arrow(length = unit(0.015, "npc")),direction = "x",hjust = "left") +scale_y_continuous(limits = c(-4.6, 6.2),breaks = seq(-4.5, 6, 1.5),labels = c("4.5", "3", "1.5", "0", "1.5", "3", "4.5", "6"))
六、总结
双组分斜对角火山图的核心优势在于:
上下调基因物理分离,不再混在 y 轴同一侧
显著基因一目了然,通过颜色、形状、标签三重强化
完全基于 ggplot2,所有细节均可自由调整
如果你正在做差异表达分析,不妨试试这个方案,让审稿人一眼就能看懂你的基因调控方向。
公众号:科研后花园原创教程,转载请注明出处
PS: 以上内容是小编个人学习代码笔记分享,仅供参考学习,欢迎大家一起交流学习。







「R绘图模板」Mantel test 进阶玩法2:多组变量与物种关系可视化(附R代码)!!!

「R绘图模板」Mantel test 进阶玩法:多组学整合分析可视化(附R代码)!!!

「R绘图模板」正三角相关性热图+聚类树:一张图看懂变量间的“朋友圈”!!!

「R绘图模板」存在-缺失热图:一张图看懂数据的“有”和“无”!!!

「R绘图模板」中性群落模型:解密微生物群落构建的“随机密码”!!!

「R绘图模板」RDA&dbRDA&CCA可视化!!!

「R绘图模板」Communications Earth & Environment | 组合图系列—曼哈顿图+Venn图展示富集OTU情况!!!

「R绘图模板」Science Advances | 组合图-并列柱状图+饼图+折线图!!!

「R绘图模板」J. Agric. Food Chem. | 分面组合图-字母标记显著性柱状图+传统显著性标记箱线图!!!

「R绘图模板」主成分分析(PCA)+各类型边缘图!!!

「R绘图模板」Field Crops Res. | 组合图系列—三元图+条形图展示微生物丰度信息!!!

「R绘图模板」Nat. Commun | 复杂tree注释—分支颜色+多层离散热图+分组条形图!!!

「R绘图模板」多色系热图+分组气泡图!!!

「R绘图模板」配对连线图+均值点及连线+显著性+嵌套分组!!!



























夜雨聆风