瀑布图

作者

[编辑] 王诗翔

[贡献] ZCode (GLM) — AI 生成,独立 AI 复核

修改于

2026-10-29

🤖 AI Skill — Download the Bizard unified skill for your AI assistant ⬇️ Download Skill ZIP
🔌 MCP Server — Let AI agents (Claude Code, Cursor, …) query Bizard live: claude mcp add bizard -- npx @openbiox/bizard-mcp — or the free hosted instance (no install, faster from mainland China): claude mcp add --transport http bizard http://biotree.top:38123/bizard-mcp/mcp 📖 MCP Docs
📖 Cite Bizard — if Bizard helps your research, please cite: Li, K., Zheng, H., Huang, K., et al. (2026). Bizard: A Community-Driven Platform for Accelerating and Enhancing Biomedical Data Visualization. iMetaMed, e70038. 🔗 DOI / BibTeX

瀑布图(Waterfall plot)是肿瘤临床试验中展示每例患者最佳肿瘤应答的标准图形。每根柱代表一名患者,按靶病灶直径总和相对基线的最佳百分比变化排序,柱子通常按 RECIST 应答类别(CR、PR、SD、PD)着色 [1]。瀑布图直观回答“应答有多深?”,与 Kaplan-Meier 生存曲线(回答“患者活了多久?”)互为补充,并常与展示每例患者肿瘤大小纵向轨迹的蜘蛛图(spider plot)搭配出现。

注记

瀑布图可能在视觉上高估应答率,因为它只显示最佳变化,且不可测量的进展可能被低估 [2]。请将瀑布图与蜘蛛图配合使用,并以数字形式报告应答率。

示例

WaterfallPlot DEMO

环境配置

  • 系统要求:跨平台(Linux/MacOS/Windows)

  • 编程语言:R

  • 依赖包:dplyr;forcats;ggplot2;patchwork

# 加载包
library(dplyr)
library(forcats)
library(ggplot2)
library(patchwork)
sessioninfo::session_info("attached")
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.6.1 (2026-06-24)
 os       Ubuntu 24.04.5 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  C.UTF-8
 ctype    C.UTF-8
 tz       UTC
 date     2026-10-29
 pandoc   3.1.3 @ /usr/bin/ (via rmarkdown)
 quarto   1.10.19 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 ! package   * version    date (UTC) lib source
 P dplyr     * 1.2.1      2026-04-03 [?] RSPM
 P forcats   * 1.0.1      2025-09-25 [?] RSPM
 P ggplot2   * 4.0.3.9000 2026-10-26 [?] Github (tidyverse/ggplot2@b638d65)
 P patchwork * 1.3.2      2025-08-25 [?] RSPM

 [1] /home/runner/.cache/R/renv/library/Bizard-5140bdc6/linux-ubuntu-noble/R-4.6/x86_64-pc-linux-gnu
 [2] /home/runner/work/_temp/Library
 [3] /opt/R/4.6.1/lib/R/library

 * ── Packages attached to the search path.
 P ── Loaded and on-disk path mismatch.

──────────────────────────────────────────────────────────────────────────────

数据准备

所需输入是每例患者一行的数据,至少包含靶病灶的最佳百分比变化和 RECIST 类别。由于 R 没有内置临床试验的患者级数据集,我们模拟一个贴近 II 期临床试验的队列:40 例患者的最佳变化遵循中等活性方案的预期分布(RECIST 阈值:PR 要求缩小 ≥30%,PD 要求增长 ≥20%)[1]。分析真实数据时,将模拟部分替换为 read.csv("your_recist_data.csv") 即可——列结构完全相同。

set.seed(2026)
n <- 40

response <- sample(c("CR", "PR", "SD", "PD"), n,
                   prob = c(0.05, 0.40, 0.30, 0.25), replace = TRUE)
best_change <- round(case_when(
  response == "CR" ~ -runif(n, 95, 100),   # 完全缓解:几乎完全缩小
  response == "PR" ~ -runif(n, 30, 92),    # 部分缓解:缩小 30-90%
  response == "SD" ~ runif(n, -25, 18),    # 疾病稳定
  response == "PD" ~ runif(n, 22, 120)     # 疾病进展
), 1)

wf <- data.frame(
  patient     = paste0("P", sprintf("%02d", seq_len(n))),
  best_change = best_change,
  response    = response
)

head(wf)
  patient best_change response
1     P01        -5.9       SD
2     P02       -19.3       SD
3     P03       -78.5       PR
4     P04       -89.7       PR
5     P05        -6.9       SD
6     P06       -90.6       PR

再为配套的蜘蛛图模拟纵向轨迹:从基线到最佳变化的近似直线漂移叠加较小的周间噪声,进展者的病情在后期加速。

set.seed(2027)
weeks <- seq(0, 48, 6)

spider <- do.call(rbind, lapply(seq_len(nrow(wf)), function(i) {
  k <- length(weeks)
  endpoint <- wf$best_change[i]
  base <- approx(x = c(1, k), y = c(0, endpoint), xout = 1:k)$y
  noise <- runif(k, -4, 4)
  if (wf$response[i] == "PD") noise <- noise + seq(0, 12, length.out = k)  # 后期加速
  data.frame(patient = wf$patient[i], week = weeks,
             change = round(pmin(base + noise, 130), 1),
             response = wf$response[i])
}))

head(spider)
  patient week change response
1     P01    0   -2.6       SD
2     P01    6   -1.5       SD
3     P01   12   -3.5       SD
4     P01   18   -0.6       SD
5     P01   24   -4.6       SD
6     P01   30   -5.2       SD

可视化

1. 基础瀑布图

按最佳变化排序患者并翻转坐标轴,得到经典的发表级版式。

p1 <- wf %>%
  mutate(patient = fct_reorder(patient, best_change)) %>%
  ggplot(aes(patient, best_change)) +
  geom_col(fill = "#4393C3", width = 0.75) +
  coord_flip() +
  labs(x = NULL, y = "Best % change from baseline") +
  theme_bw()
p1
图 1: 每例患者最佳肿瘤变化的基础瀑布图。

2. 按 RECIST 着色并带参考线的瀑布图

按应答类别为柱子着色,并添加 RECIST 参考线:−30% 是部分缓解的边界,+20% 是进展的边界(正式定义中,PD 还要求直径总和绝对值增加至少 5 mm)。

recist_colors <- c(CR = "#1B7837", PR = "#66BD63", SD = "#FFB300", PD = "#C51B7D")

p2 <- wf %>%
  mutate(patient = fct_reorder(patient, best_change)) %>%
  ggplot(aes(patient, best_change, fill = response)) +
  geom_col(width = 0.75) +
  geom_hline(yintercept = c(-30, 20), linetype = "dashed", color = "grey35") +
  scale_fill_manual(values = recist_colors, name = "RECIST") +
  coord_flip() +
  labs(x = NULL, y = "Best % change from baseline") +
  theme_bw() +
  theme(legend.position = "top")
p2
图 2: 按 RECIST 应答着色并带 -30% 与 +20% 参考线的瀑布图。

两条虚线使应答率(低于 −30% 的柱子)与疾病控制率(低于 +20% 的所有柱子)一目了然。

3. 配套蜘蛛图

p3 <- spider %>%
  ggplot(aes(week, change, group = patient, color = response)) +
  geom_hline(yintercept = c(-30, 20), linetype = "dashed", color = "grey35") +
  geom_line(alpha = 0.75, linewidth = 0.6) +
  scale_color_manual(values = recist_colors, name = "RECIST") +
  labs(x = "Weeks on treatment", y = "% change from baseline") +
  theme_bw() +
  theme(legend.position = "top")
p3
图 3: 肿瘤变化的纵向蜘蛛图;瀑布图展示终点,蜘蛛图展示轨迹。

4. 组合图

p2 + p3 + plot_annotation(
  title = "Best tumor response and its longitudinal trajectories",
  tag_levels = "A"
)
图 4: 瀑布图(左)与蜘蛛图(右)用 patchwork 组合。

两图对照阅读:柱子给出应答深度,折线给出应答的形态——早期缩小者、晚期进展者和原发难治者只有通过蜘蛛图才能区分。

应用

瀑布图在临床肿瘤学论文和 FDA/EMA 申报材料中无处不在,用于总结某方案抗肿瘤活性;下方的”瀑布图 + 蜘蛛图”组合即为典型呈现形式。

WaterfallPlot Application

参考文献

[1] Eisenhauer EA, Therasse P, Bogaerts J, et al. New response evaluation criteria in solid tumours: revised RECIST guideline (version 1.1). Eur J Cancer. 2009;45(2):228-247. doi:10.1016/j.ejca.2008.10.026

[2] Kim MS, Prasad V. Assessment of accuracy of waterfall plot representations of response rates in cancer treatment published in medical journals. JAMA Netw Open. 2019;2(5):e193981. doi:10.1001/jamanetworkopen.2019.3981