大家好!在生物信息学、组学数据分析中,火山图(Volcano Plot)绝对是出镜率最高的可视化图表之一。它能够非常直观地展示两组样本间显著变化的基因、蛋白或代谢物,是挖掘关键分子的得力助手。
今天,我们就用R语言中的
包,手把手教你从一份差异分析结果表开始,绘制出一张发表级的炫酷火山图!无论你是新手还是老手,都能有所收获。
ggplot2
一、什么是火山图?
简单来说,火山图是一张散点图,其中:
X轴:通常表示差异倍数(log2 Fold Change),衡量变化幅度的大小。越偏离0,变化越大。
Y轴:通常表示显著性水平(-log10(adj.P.Val)),衡量结果的可信度。值越大,越显著。
图中的点:每一个点代表一个基因/蛋白/代谢物。
显著区域:图表上方两侧的点,就是既显著又变化幅度大的目标分子,也是我们关注的焦点,因其形似喷发的火山而得名。
二、准备工作:安装并加载R包
我们将使用
进行绘图,
ggplot2
进行数据整理,
dplyr
来智能标记点标签防止重叠。
ggrepel
r
# 如果未安装包,请先运行下一行 # install.packages(c("ggplot2", "dplyr", "ggrepel")) library(ggplot2) # 绘图核心 library(dplyr) # 数据操作 library(ggrepel) # 防止标签重叠
三、模拟一份差异分析数据
在实际分析中,你的数据可能来自DESeq2、edgeR等工具。这里我们首先模拟一份包含1000个基因的数据框。
# 设置随机种子,保证结果可重复 set.seed(123) # 生成模拟数据 diff_data <- data.frame( gene = paste0("Gene", 1:1000), log2FC = rnorm(1000, mean = 0, sd = 2), # 随机生成log2FC,大部分在0附近 P.Value = runif(1000, min = 0, max = 1) # 随机生成p值 ) # 计算调整后p值(这里用BH方法简单模拟)和负对数p值 diff_data$adj.P.Val <- p.adjust(diff_data$P.Value, method = "BH") diff_data$neg_logP <- -log10(diff_data$adj.P.Val) # 查看数据前6行 head(diff_data)
四、定义显著性阈值并添加分组信息
通常,我们以
(即差异倍数两倍以上)且
|log2FC| >= 1
作为显著性的标准。
adj.P.Val < 0.05
# 定义显著性阈值 fc_threshold <- 1 pval_threshold <- 0.05 # 使用dplyr的mutate和case_when为每个基因添加分组标签 diff_data <- diff_data %>% mutate( group = case_when( log2FC >= fc_threshold & adj.P.Val < pval_threshold ~ "Up", # 显著上调 log2FC <= -fc_threshold & adj.P.Val < pval_threshold ~ "Down", # 显著下调 TRUE ~ "Non-Sig" # 不显著 ) ) # 查看各组有多少个基因 table(diff_data$group)
五、核心绘图代码:一步步构建火山图
现在,让我们用
来绘制基础的火山图。
ggplot2
# 1. 基础图层:映射x轴,y轴,并根据分组着色 p <- ggplot(data = diff_data, aes(x = log2FC, y = neg_logP, color = group)) + # 2. 添加散点图图层 geom_point(size = 1.5, alpha = 0.6) + # alpha调整透明度,避免点太密看不清 # 3. 手动设置颜色 scale_color_manual( values = c("Up" = "#E64B35", "Down" = "#3182BD", "Non-Sig" = "#636363"), name = "Status" # 图例标题 ) + # 4. 添加阈值线 # 添加垂直的log2FC阈值线(虚线) geom_vline(xintercept = c(-fc_threshold, fc_threshold), linetype = "dashed", color = "black") + # 添加水平的P值阈值线(虚线),注意y轴是-log10(padj),所以线画在 -log10(0.05) 的位置 geom_hline(yintercept = -log10(pval_threshold), linetype = "dashed", color = "black") + # 5. 修改主题,使其更简洁美观(经典无网格线背景) theme_bw() + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank(), legend.position = c(0.85, 0.9), # 调整图例位置 legend.background = element_rect(fill = "transparent") # 图背景透明 ) + # 6. 设置坐标轴标题 labs( x = expression("log"[2]*" Fold Change"), y = expression("-log"[10]*" (adj.P.Val)"), title = "Volcano Plot" ) # 显示图形 print(p)
运行以上代码,你应该已经得到了一张标准的火山图!
六、高级美化:标记显著基因
一张优秀的火山图,总要标记出几个最显著的基因名字。我们用
来智能标注。
geom_text_repel
# 从显著上/下调的基因中,各选择5个最显著的进行标注 sig_genes <- diff_data %>% filter(group != "Non-Sig") %>% # 筛选显著基因 arrange(adj.P.Val) %>% # 按p值排序 group_by(group) %>% # 按上下调分组 slice_head(n = 5) # 每组取前5个 # 在之前的图p上添加标注图层 p_final <- p + geom_text_repel( data = sig_genes, # 只用显著基因的数据 aes(label = gene), # 标注gene列 size = 3, # 字体大小 box.padding = 0.5, # 标注框的填充,ggrepel的参数,用于防止重叠 max.overlaps = 20, # 最大重叠尝试次数 show.legend = FALSE # 不显示文本的图例 ) # 显示最终图形 print(p_final)
七、代码解读与常见问题
数据映射(Aesthetics):
函数是ggplot的灵魂,它定义了数据如何映射到图形属性(颜色、大小、坐标等)。
aes()
几何对象(Geometries):
添加点,
geom_point
/
geom_hline
添加线,
geom_vline
添加智能标签。
geom_text_repel
标度(Scales):
让我们可以手动指定颜色,非常适合定义分组颜色。
scale_color_manual
主题(Theme):
和后续的
theme_bw()
修改让我们能精细控制图的非数据元素(背景、网格线、图例等)。
theme()
标签重叠:
包是解决标签重叠问题的终极武器,强烈推荐!
ggrepel
常见问题:
Q:我的数据没有
列,只有
adj.P.Val
怎么办?
P.Value
A:可以直接用
作为Y轴,但更推荐使用校正后的p值,多重检验假阳性很高。
-log10(P.Value)
Q:如何修改阈值?
A:直接修改代码开头的
和
fc_threshold
变量即可。
pval_threshold
Q:图片怎么保存?
A:在RStudio中点击Export -> Save as Image。或者用代码:
ggsave("My_Volcano_Plot.png", p_final, width = 8, height = 6, dpi = 300)
八、结语
至此,你已经掌握了用R语言绘制 publication-ready 火山图的全部技巧!从数据预处理、核心绘图到高级美化,这套流程足以应对绝大部分场景。
赶紧把你自己的数据(通常包含
/
log2FC
/
P.Value
的CSV或TXT文件)用
gene symbol
读入R,替换掉我们模拟的数据,来生成一张属于你自己的火山图吧!
read.csv()
如果你有任何问题,欢迎在评论区留言讨论!