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

ggplot火山图技术问询:图例字号不一致、标签及连线优化

火山图ggplot问题解决方案

1. 修复两张图的图例字号差异

问题根源是两张图的图例标题换行长度不一致,ggplot自动调整图例布局导致字号视觉上有差异。解决方式是固定图例标题的宽度和字号,同时统一标题的换行逻辑:

在theme()中新增legend.title的配置,强制统一标题字号与宽度,示例代码片段:

theme(
  # 原有配置保留
  legend.position = c(0.15, 0.80), 
  legend.key.height = unit(0.3, "cm"), 
  legend.key.width = unit(1, "cm"), 
  axis.text.x = element_text(size = 20), 
  axis.text.y = element_text(size = 20), 
  axis.title.x = element_text(size = 20), 
  axis.title.y = element_text(size = 20), 
  legend.text = element_text(size = 8),
  # 新增:固定图例标题字号与宽度
  legend.title = element_text(size = 10, width = unit(4, "cm"))
)

同时建议统一两张图的图例标题换行格式(比如都用\n手动换行,保持换行后的长度一致),避免布局自动调整。

2. 调整图例顺序:Downregulated(蓝)左,Upregulated(粉)右

需要先把diffs列转换为有序因子,指定水平顺序为Downregulated→Not significant→Upregulated,这样图例就会按该顺序排列:

# 重新定义因子水平顺序
resLFC$diffs <- factor(resLFC$diffs, levels = c("Downregulated", "Not significant", "Upregulated"))

后续scale_color_manual中的颜色会自动对应这个顺序,蓝色标签就会在左侧,粉色标签在右侧。

3. 让点与标签的连线更规整

可以通过优化geom_label_repel的参数实现,推荐几种方法:

方法1:按基因表达趋势定向偏移

根据log2FoldChange的正负,分别设置标签的偏移方向,让连线更有序:

geom_label_repel(
  nudge_x = ifelse(resLFC$log2FoldChange > 0, 5, -5), # 上调基因右移,下调基因左移
  nudge_y = 5, # 统一上移避免遮挡
  force = 20, # 调整力值,避免标签过度分散
  max.iter = 200000,
  max.segment.length = 1, # 适当增加线段长度,让连线更自然
  max.overlaps = 10000,
  segment.color = "gray50", # 统一连线颜色
  segment.size = 0.5, # 调整连线粗细
  seed = 123 # 固定随机种子,确保每次绘图布局一致
)

方法2:分批次绘制上调/下调基因标签

分别处理上调和下调的显著基因,精准控制标签位置与连线样式:

# 绘制下调基因标签(左移)
geom_label_repel(
  data = subset(resLFC, log2FoldChange < -1 & padj < 1e-4),
  nudge_x = -10,
  segment.color = "dodgerblue1",
  seed = 123
) +
# 绘制上调基因标签(右移)
geom_label_repel(
  data = subset(resLFC, log2FoldChange > 1 & padj < 1e-4),
  nudge_x = 10,
  segment.color = "deeppink1",
  seed = 123
)

完整优化代码示例

# 统一因子水平顺序
resLFC$diffs <- factor(resLFC$diffs, levels = c("Downregulated", "Not significant", "Upregulated"))

# 定义通用主题,减少重复代码
common_theme <- theme(
  legend.position = c(0.15, 0.80), 
  legend.key.height = unit(0.3, "cm"), 
  legend.key.width = unit(1, "cm"), 
  axis.text.x = element_text(size = 20), 
  axis.text.y = element_text(size = 20), 
  axis.title.x = element_text(size = 20), 
  axis.title.y = element_text(size = 20), 
  legend.text = element_text(size = 8),
  legend.title = element_text(size = 10, width = unit(4, "cm"))
)

# 第一张图
ggplot(data = resLFC, aes(x = log2FoldChange, y = -log10(padj), col = diffs, label = delabel)) +
  coord_cartesian(xlim = c(-30,30), ylim = c(-10,80)) +
  geom_vline(xintercept = c(-1, 1), col = "blue", linetype = "dashed") +
  geom_hline(yintercept = 4, col = "red", linetype = "dashed") +
  geom_point() +
  scale_color_manual(values = c("dodgerblue1", "gray", "deeppink1")) +
  labs(
    color = "test 2 vs test 1\nin testtt testttt",
    x = expression("log"[2]*"FC"), 
    y = expression("-log"[10]*"p-value")
  ) +
  geom_label_repel(
    nudge_x = ifelse(resLFC$log2FoldChange > 0, 5, -5),
    nudge_y = 5,
    force = 20,
    max.iter = 200000,
    max.segment.length = 1,
    max.overlaps = 10000,
    segment.color = "gray50",
    segment.size = 0.5,
    seed = 123
  ) +
  common_theme

# 第二张图
ggplot(data = resLFC, aes(x = log2FoldChange, y = -log10(padj), col = diffs, label = delabel)) +
  coord_cartesian(xlim = c(-30,30), ylim = c(-10,80)) +
  geom_vline(xintercept = c(-1, 1), col = "blue", linetype = "dashed") +
  geom_hline(yintercept = 4, col = "red", linetype = "dashed") +
  geom_point() +
  scale_color_manual(values = c("dodgerblue1", "gray", "deeppink1")) +
  labs(
    color = "test 2 vs test 1\nin test test",
    x = expression("log"[2]*"FC"), 
    y = expression("-log"[10]*"p-value")
  ) +
  geom_label_repel(
    nudge_x = ifelse(resLFC$log2FoldChange > 0, 5, -5),
    nudge_y = 5,
    force = 20,
    max.iter = 200000,
    max.segment.length = 1,
    max.overlaps = 10000,
    segment.color = "gray50",
    segment.size = 0.5,
    seed = 123
  ) +
  common_theme

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:38:09