BioF3 FigCode · SCI 绘图代码集

Risk 三联图(Risk Score Triple Plot)

导出日期:2026年6月27日

分类:生存分析 | 依赖包:ggplot2、patchwork、tidyr

解决的生物学问题

我的 prognostic signature 在样本水平上如何分布?高风险组是否真的死亡更多?

应用场景

输入数据格式

数据框:risk_score, OS_time, OS_status + signature 基因表达矩阵

关键参数

快速开始

1. 直接在线运行

打开 FigCode 在线绘图,点击本工具卡片的"在线绘图"按钮即可用内置示例数据出图,零环境配置。

2. 本地复现

下载脚本和示例数据,本地 RStudio 运行:

# 下载
curl -O https://<your-site>/figcode/scripts/risk-triple.R
curl -O https://<your-site>/figcode/data/risk-triple.csv

3. 安装依赖

# CRAN 包
install.packages(c("ggplot2", "patchwork", "tidyr"))

# Bioconductor 包(如需)
# BiocManager::install(c())

完整代码

library(ggplot2)
library(patchwork)

# --- Demo data ---
set.seed(42)
n <- 200
n_sig <- 8
risk <- sort(rnorm(n))
df <- data.frame(
  idx        = 1:n,
  risk_score = risk,
  OS_time    = pmax(rexp(n, 0.05) - 0.5 * risk, 0.3),
  OS_status  = rbinom(n, 1, plogis(risk * 1.2 - 0.5))
)
df$group <- ifelse(df$risk_score > median(df$risk_score), "High", "Low")
cutoff_idx <- which(df$risk_score > median(df$risk_score))[1]

# Signature gene matrix (rows = genes, cols = patients in same order)
expr_mat <- matrix(rnorm(n_sig * n, 0, 0.6), nrow = n_sig)
# Make first 4 positively correlated, last 4 negatively
expr_mat[1:4, ] <- expr_mat[1:4, ] + 0.6 * matrix(rep(risk, 4), nrow = 4, byrow = TRUE)
expr_mat[5:8, ] <- expr_mat[5:8, ] - 0.6 * matrix(rep(risk, 4), nrow = 4, byrow = TRUE)
rownames(expr_mat) <- paste0("Gene", 1:n_sig)

# --- Panel 1: risk score ---
p1 <- ggplot(df, aes(idx, risk_score, color = group)) +
  geom_point(size = 1.2) +
  geom_vline(xintercept = cutoff_idx, linetype = "dashed", color = "grey50") +
  scale_color_manual(values = c(Low = "#2563eb", High = "#dc2626")) +
  labs(x = NULL, y = "Risk score") +
  theme_classic() + theme(axis.text.x = element_blank())

# --- Panel 2: survival status ---
p2 <- ggplot(df, aes(idx, OS_time, color = factor(OS_status))) +
  geom_point(size = 1.2) +
  geom_vline(xintercept = cutoff_idx, linetype = "dashed", color = "grey50") +
  scale_color_manual(values = c("0" = "#94a3b8", "1" = "#dc2626"),
                     labels = c("Alive","Dead"), name = "Status") +
  labs(x = NULL, y = "Survival time") +
  theme_classic() + theme(axis.text.x = element_blank())

# --- Panel 3: signature gene heatmap ---
expr_long <- as.data.frame(t(scale(t(expr_mat))))
expr_long$gene <- rownames(expr_long)
expr_long <- tidyr::pivot_longer(expr_long, -gene, names_to = "patient", values_to = "z")
expr_long$idx <- as.integer(sub("^V", "", expr_long$patient))

p3 <- ggplot(expr_long, aes(idx, gene, fill = z)) +
  geom_tile() +
  scale_fill_gradient2(low = "#2563eb", mid = "white", high = "#dc2626") +
  labs(x = "Patients (sorted by risk score)", y = NULL, fill = "z-score") +
  theme_classic() +
  theme(axis.text.y = element_text(size = 8))

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

替换为自己的数据

脚本中以 # --- Demo data --- 标注的段落是示例数据生成代码。替换为自己的数据时,保持列名一致即可:

延伸阅读