火山图(Volcano Plot)是一种常用于基因表达或差异分析中的散点图,通过同时展示统计显著性和效应大小来快速筛选出显著变化的基因或其他特征。横轴通常表示log2倍数变化(log2 fold change),代表基因表达的上调或下调;纵轴表示p值的负对数(-log10 p-value),反映显著性。通过这种图表,研究者可以快速识别在实验条件下显著上调或下调的基因群体。图中通常使用不同颜色来区分上调、下调和不显著变化的基因。
0x01 准备数据
我们需要一组数据,包括基因名称、log2 fold change 和 p-value。我来模拟一组这样的数据。
# 生成随机数据
set.seed(123) # 设置种子以便结果可重复
genes <- paste("Gene", 1:1000) # 基因名称
logFC <- rnorm(1000, mean = 0, sd = 2) # log2 fold change,均值为0,标准差为2的正态分布
pvalue <- runif(1000, min = 0, max = 1) # p值,0到1之间的均匀分布
# 创建数据框
data <- data.frame(genes = genes, logFC = logFC, pvalue = pvalue)
0x02 处理数据
火山图中,我们要展示显著差异的基因。一般我们会设置两个阈值:
- log2 fold change 的绝对值要大于某个阈值,比如 1。
- p-value 要小于某个阈值,比如 0.05。
# 添加一列来标记显著性
data$significant <- ifelse(abs(data$logFC) > 1 & data$pvalue < 0.05, "Significant", "Not Significant")
0x03 安装并加载所需要的R包
# 如果没有安装ggplot2包,使用以下代码进行安装
# install.packages("ggplot2")
# 加载ggplot2包
library(ggplot2)
0x04 绘制火山图
# 绘制火山图
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = significant)) +
geom_point(alpha = 0.6, size = 1.5) + # 绘制散点,alpha控制透明度,size控制点的大小
scale_color_manual(values = c("grey", "red")) + # 自定义颜色,显著基因用红色
theme_minimal() + # 使用简单的主题风格
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") + # 添加标题和轴标签
theme(plot.title = element_text(hjust = 0.5)) # 将标题居中
解释:
- 1
aes(x = logFC, y = -log10(pvalue), color = significant)
:指定横轴为log2 fold change,纵轴为-log10 p-value,点的颜色由显著性决定。 - 2
geom_point()
:绘制散点。 - 3
scale_color_manual()
:自定义颜色,灰色表示不显著,红色表示显著。 - 4
theme_minimal()
:使用简单的背景主题。 - 5
labs()
:用于给图形添加标题和轴标签。 - 6
theme()
:调整图形的样式,比如让标题居中。
0x05 进一步优化图形
一、添加阈值线
你可以根据需要进一步调整图形,比如让显著的点变得更大、更亮,或者添加垂直线和水平线表示阈值。
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = significant)) +
geom_point(alpha = 0.6, size = 1.5) +
scale_color_manual(values = c("grey", "red")) +
theme_minimal() +
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "blue") + # 添加竖线,表示logFC的阈值
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "blue") # 添加横线,表示p-value的阈值
二、三种颜色的表达
如果你想让上调基因和下调基因分别用不同颜色表达,可以根据 logFC 的正负值进一步对基因进行分类,比如上调基因、下调基因和不显著基因。我们可以使用不同颜色表示这三种情况。
# 根据logFC和p-value进一步分类
data$expression <- ifelse(data$logFC > 1 & data$pvalue < 0.05, "Upregulated",
ifelse(data$logFC < -1 & data$pvalue < 0.05, "Downregulated", "Not Significant"))
# 查看数据框的前几行,确认分类是否正确
head(data)
这里,我们将log2 fold change大于1且p-value小于0.05的基因标记为"Upregulated"(上调基因),log2 fold change小于-1且p-value小于0.05的基因标记为"Downregulated"(下调基因),其余基因标记为"Not Significant"(不显著基因)。
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = expression)) +
geom_point(alpha = 0.6, size = 1.5) + # 绘制散点,透明度和点的大小
scale_color_manual(values = c("blue", "grey", "red")) + # 自定义颜色:下调为蓝色,不显著为灰色,上调为红色
theme_minimal() + # 简洁主题
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") + # 添加标题和轴标签
theme(plot.title = element_text(hjust = 0.5)) + # 标题居中
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "black") + # 添加阈值竖线
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black") # 添加阈值横线
三、标记显著基因
除了使用颜色区分上调、下调和不显著基因,你还可以标记显著的基因名称,特别是那些 log2 fold change 和 p-value 极端的基因。这有助于识别那些在分析中最为重要的基因。
你可以使用 geom_text_repel()
函数(来自 ggrepel
包)来避免文本重叠,增加标记的可读性。首先需要安装和加载 ggrepel
包:
# 安装 ggrepel 包
# install.packages("ggrepel")
# 加载 ggrepel 包
library(ggrepel)
# 只标记显著的上调和下调基因
significant_genes <- data[data$expression != "Not Significant", ]
# 绘制带基因标记的火山图
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = expression)) +
geom_point(alpha = 0.6, size = 1.5) +
scale_color_manual(values = c("blue", "grey", "red")) +
theme_minimal() +
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "black") +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black") +
#避免标签重叠的函数,可以让基因名称显得更加清晰。
geom_text_repel(data = significant_genes, aes(label = genes),
size = 3, box.padding = 0.3, point.padding = 0.3)
四、调整点的透明度大小
有时候,点的数量较多时,会导致图形看起来过于拥挤,或者你希望突出显示一些显著的基因。你可以通过调整透明度 (alpha
) 和大小 (size
) 来改善图形的可读性。
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = expression)) +
geom_point(aes(size = -log10(pvalue), alpha = abs(logFC))) + # 点的大小和透明度。
#size = -log10(pvalue):显著性越高的点越大。
#alpha = abs(logFC):log2 fold change 越大,点越不透明。
scale_color_manual(values = c("blue", "grey", "red")) +
theme_minimal() +
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "black") +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black")
五、分面图
如果你有多个不同的实验条件,想要比较它们的火山图,你可以使用 facet_wrap()
或 facet_grid()
来绘制分面图。例如,假设你有不同的条件(Condition A, Condition B),可以这样操作:
首先,我们为数据添加条件信息:
# 为数据添加一个模拟条件列
data$condition <- sample(c("Condition A", "Condition B"), nrow(data), replace = TRUE)
然后使用 facet_wrap()
绘制每个条件的火山图:
ggplot(data, aes(x = logFC, y = -log10(pvalue), color = expression)) +
geom_point(alpha = 0.6, size = 1.5) +
scale_color_manual(values = c("blue", "grey", "red")) +
theme_minimal() +
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "black") +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black") +
facet_wrap(~ condition) # 按条件分面显示
六、交互式图形
如果你希望生成交互式火山图,可以使用 plotly
包。它允许你在图形中移动鼠标查看每个点的详细信息。
首先,安装并加载 plotly
包:
# 安装 plotly 包
# install.packages("plotly")
# 加载 plotly 包
library(plotly)
然后将 ggplot
图形转换为交互式图形:
p <- ggplot(data, aes(x = logFC, y = -log10(pvalue), color = expression)) +
geom_point(alpha = 0.6, size = 1.5) +
scale_color_manual(values = c("blue", "grey", "red")) +
theme_minimal() +
labs(title = "Volcano Plot", x = "Log2 Fold Change", y = "-Log10 P-value") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "black") +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black")
# 转换为交互式图形
ggplotly(p)
效果:生成的火山图可以用鼠标悬停查看每个基因的详细信息(如logFC和p-value)。
七、其他图形调整
坐标轴缩放:如果数据点集中在某些区域,你可以使用 coord_cartesian()
来缩放感兴趣的部分,或者通过 xlim()
和 ylim()
限制坐标轴范围。
改变点的形状:可以通过 shape
参数自定义点的形状,例如区分不同的实验条件。
主题自定义:可以使用 theme()
对图表的每个部分进行自定义,如字体、标题位置、背景颜色等。例如,调整字体大小和样式:
theme(axis.title = element_text(size = 14, face = "bold"),
axis.text = element_text(size = 12),
plot.title = element_text(size = 16, face = "bold"))