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

使用ggplot2基于分段值绘制拷贝数增减散点图

解决方案:用R ggplot2实现拷贝数分段散点可视化

步骤1:准备环境与数据

首先加载所需工具包:

library(ggplot2)
library(dplyr)
library(tidyr)

我们需要染色体长度和着丝粒位置数据来区分染色体臂、计算X轴缩放位置,以下是hg19版本的参考数据(如果用hg38可替换对应数值):

# 1-22号染色体长度(hg19)
chr_length <- tibble(
  chrom = as.character(1:22),
  length = c(249250621, 243199373, 198022430, 191154276, 180915260, 171115067,
             159138663, 146364022, 141213431, 135534747, 135006516, 133851895,
             115169878, 107349540, 102531392, 90354753, 81195210, 78077248,
             59128983, 63025520, 48129895, 51304566)
)

# 1-22号染色体着丝粒位置(hg19,用于区分p/q臂)
centromeres <- tibble(
  chrom = as.character(1:22),
  cent_pos = c(125000000, 93300000, 91000000, 50400000, 48400000, 61000000,
               59900000, 45600000, 49000000, 40200000, 53700000, 35800000,
               17900000, 17600000, 19000000, 36600000, 24000000, 17200000,
               26500000, 27500000, 13200000, 14700000)
)

假设你的原始数据框名为cnv_data,先做数据预处理:

注意:如果你的原始数据列名是sampleID、chromosome,请将代码中对应的chrom替换为chromosome,确保列名匹配

cnv_processed <- cnv_data %>%
  # 仅保留1-22号常染色体
  filter(chrom %in% as.character(1:22)) %>%
  mutate(chrom = as.character(chrom)) %>%
  # 合并染色体长度、着丝粒数据
  left_join(chr_length, by = "chrom") %>%
  left_join(centromeres, by = "chrom") %>%
  # 判断分段属于p臂还是q臂
  mutate(arm = ifelse(end.pos <= cent_pos, "p", "q")) %>%
  # 计算每个染色体在X轴的起始偏移(累计前序染色体总长度)
  group_by(chrom) %>%
  mutate(chr_start = sum(chr_length$length[chr_length$chrom < unique(chrom)])) %>%
  ungroup() %>%
  # 用分段中点作为散点在X轴的位置
  mutate(x_pos = chr_start + (start.pos + end.pos)/2)

步骤2:绘制可视化图

先定义增益/损失的阈值(可根据需求自定义):

gain_threshold <- 0.2
loss_threshold <- -0.2

接着绘制主图,先画染色体臂背景色块,再叠加散点:

# 准备染色体背景数据(用于绘制X轴的臂区分色块)
chr_background <- chr_length %>%
  left_join(centromeres, by = "chrom") %>%
  mutate(chr_start = sum(chr_length$length[chr_length$chrom < chrom]),
         p_end = chr_start + cent_pos,
         q_start = p_end,
         q_end = chr_start + length) %>%
  select(chrom, chr_start, p_end, q_start, q_end) %>%
  pivot_longer(cols = c(chr_start:p_end, q_start:q_end),
               names_to = c("arm", ".value"),
               names_pattern = "(.*)_(start|end)")

# 生成最终可视化图
ggplot() +
  # 绘制染色体臂背景,区分p/q臂颜色
  geom_rect(data = chr_background,
            aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf, fill = arm),
            alpha = 0.2) +
  # 绘制CNV分段散点,按阈值标记增益/损失/中性
  geom_point(data = cnv_processed,
             aes(x = x_pos, y = seg.mean,
                 color = case_when(
                   seg.mean > gain_threshold ~ "Gain",
                   seg.mean < loss_threshold ~ "Loss",
                   TRUE ~ "Neutral"
                 )),
             size = 2, alpha = 0.8) +
  # 设置颜色映射
  scale_fill_manual(values = c("p" = "#e0e0e0", "q" = "#c0c0c0")) +
  scale_color_manual(values = c("Gain" = "#ff4444", "Loss" = "#3366ff", "Neutral" = "#666666")) +
  # 调整X轴:用染色体编号替换原始位置值,刻度对应染色体中点
  scale_x_continuous(breaks = chr_length$chr_start + chr_length$length/2,
                     labels = chr_length$chrom) +
  # 设置坐标轴与图例标签
  labs(x = "Chromosome", y = "Segment Mean", color = "CNV Status", fill = "Chromosome Arm") +
  # 优化主题样式
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 10),
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank()
  )

关键说明

  • X轴宽度完全匹配染色体实际长度,满足"按染色体尺寸设置厚度"的需求
  • 通过着丝粒位置自动区分p/q臂,背景色块直观展示臂分布
  • 散点颜色根据自定义阈值自动标记增益、损失和中性区域
  • 若切换基因组版本(如hg38),只需替换chr_length和centromeres中的数值即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:55:19