06科研绘图与多图组合

使用 ggpubr 快速添加统计标注,并通过 patchwork 组织多面板图形、标题和标签。

2026-03-06
Rggplot2ggpubrpatchworkPublication Figures
本章目录 · 9

科研图形经常需要在基础图层之外完成两类工作:把统计结果标在图上,以及把多张图组织成带编号的版面。ggpubr 提供常见科研图与统计标注的快捷接口,patchwork 则负责组合多个 ggplot 对象。

ggpubr 的快捷绘图函数

library(ggplot2)
library(ggpubr)

常用入口包括:

函数 用途
ggscatter() 散点图、拟合线和相关系数
ggboxplot() 分组箱线图
ggbarplot() 分组条形图与汇总值
stat_compare_means() 在 ggplot 图层中添加统计比较
ggarrange() 快速排列多个图形
theme_pubr() 简洁的出版主题

带回归线和相关系数的散点图:

ggscatter(
  mtcars,
  x = "mpg",
  y = "disp",
  add = "reg.line",
  conf.int = TRUE,
  cor.coef = TRUE
)

分组箱线图:

cars <- transform(mtcars, cyl = factor(cyl))

ggboxplot(
  cars,
  x = "cyl",
  y = "mpg",
  fill = "cyl",
  palette = "npg"
)

这些函数返回 ggplot 对象,因此仍可以继续叠加 labs()theme() 和其他图层。

添加统计比较

stat_compare_means() 可以添加全局检验和指定组间比较:

comparisons <- list(c("4", "6"), c("6", "8"))

ggboxplot(cars, x = "cyl", y = "mpg") +
  stat_compare_means(method = "anova") +
  stat_compare_means(
    comparisons = comparisons,
    method = "t.test",
    label = "p.signif"
  )

快捷标注不会替代统计设计。添加之前仍需明确:

  • 检验是否与研究问题和数据结构匹配;
  • 多组比较是否需要校正;
  • 配对、重复测量或分层结构是否被考虑;
  • 图上显示的是精确 p 值、星号还是效应量;
  • 标注位置是否会遮挡数据。

图层只负责展示传入的比较,不能判断比较是否合理。

应用主题并导出

theme_pubr() 可以作为普通 ggplot2 主题叠加,base_size 控制基础字号,border 控制是否保留完整边框:

ggplot(mtcars, aes(mpg, disp)) +
  geom_point() +
  theme_pubr(base_size = 14, border = TRUE)
p <- ggboxplot(
  cars,
  x = "cyl",
  y = "mpg",
  fill = "cyl",
  palette = "jco"
) +
  stat_compare_means(method = "anova", label.y = 35) +
  theme_pubr(base_size = 14, legend = "right") +
  labs(
    title = "MPG by cylinder count",
    x = "Cylinders",
    y = "Miles per gallon"
  )

ggsave(
  "mpg-analysis.png",
  p,
  width = 6,
  height = 4,
  dpi = 300
)

导出尺寸是设计的一部分。字体、线宽、点大小和统计标注应在最终宽高下检查,而不能只看绘图窗口中的缩放预览。

期刊要求 TIFF 时,可以直接选择相应扩展名:

ggsave(
  "mpg-analysis.tiff",
  p,
  width = 5,
  height = 4,
  dpi = 300
)

黑白输出可配合 scale_color_grey()scale_fill_grey();指定字体时,则继续叠加 theme(text = element_text(family = "Arial"))。字体是否可用仍取决于输出设备和运行环境。

使用 ggarrange 快速排列

p1 <- ggscatter(mtcars, x = "mpg", y = "disp")
p2 <- ggboxplot(cars, x = "cyl", y = "mpg")

ggarrange(
  p1,
  p2,
  ncol = 2,
  labels = c("A", "B")
)

当需求只是规则网格和面板标签时,ggarrange() 足够直接。需要嵌套布局或通过运算符描述结构时,可以使用 patchwork。

使用 patchwork 组合图形

library(patchwork)

p1 <- ggplot(mtcars, aes(mpg, disp)) +
  geom_point()

p2 <- ggplot(mtcars, aes(hp, wt)) +
  geom_point()

| 横向排列,/ 纵向排列:

p1 | p2
p1 / p2

括号可以明确嵌套结构:

(p1 | p2) / p1

+ 也可组合图形;在复杂表达式中,|/ 更直观地表达方向。

控制布局

plot_layout() 可以指定列数和相对尺寸:

(p1 + p2 + p1) +
  plot_layout(ncol = 2, heights = c(1, 2))

布局不是把图缩小后塞进空格。组合前应确认:

  • 各面板在目标尺寸下仍能读取;
  • 坐标轴与图例是否重复;
  • 需要比较的面板是否使用一致标度;
  • 面板宽高是否符合数据形状;
  • 标题和注释是否属于单图还是整组图。

添加整图标题与面板标签

(p1 | p2) +
  plot_annotation(
    title = "MTCars multi-panel plot",
    subtitle = "Relationships among performance measures",
    tag_levels = "A"
  )

tag_levels = "A" 自动生成 A、B 等面板标签,避免手动在每张图中写死编号。调整布局时,标签顺序会跟随图形顺序。

共享整体样式

patchwork 的 & 可以将同一个主题应用到组合中的所有图:

(p1 | p2) &
  theme_minimal(base_size = 11)

同样也可以统一使用 ggpubr 主题:

((p1 | p2) / p1) +
  plot_annotation(
    title = "Automobile analysis",
    tag_levels = "A"
  ) &
  theme_pubr(base_size = 12)

这样可以在组合阶段统一字体、背景和图例位置,同时保留各图自己的数据与标度。若各面板需要不同主题,则应在组合前分别设置。

选择组合工具

  • ggarrange():规则排布、快速标签、以 ggpubr 为主的工作流;
  • patchwork:运算符布局、嵌套结构和整组注释;
  • 更底层的 grid 工具:需要直接控制 grob 或混合非 ggplot 对象。

无论使用哪个工具,最终交付的是一个完整版面。统计标注、图例、面板标签和导出尺寸应作为同一设计共同检查。