当前位置: 首页 > news >正文

代码复现-甜甜圈富集分析

代码复现-甜甜圈富集分析

本文复现了Medina 等人在 Nature (2020) 文章中,一种类似“甜甜圈”形状的富集分析图。简单来说,这份 R 代码把复杂的统计结果转化成一个直观、信息量大的可视化图:中心告诉你“总体上调/下调基因情况”,外围告诉你“具体哪些通路参与,以及它们的上调/下调基因数”。这种图特别适合做功能富集分析的展示,因为它既有整体概览,也有分支细节,能帮助读者快速理解基因表达变化与生物学功能之间的对应关系。

这种图表的直观特色是:中间一个大甜甜圈展示总体上调/下调基因的分布,外围一圈一圈的小甜甜圈代表不同的功能通路或类别,每个小圈再细分成红色(上调基因数)和蓝色(下调基因数)。为了让视觉更清晰,代码里设计了两道“车道”,让小甜甜圈交错排列,同时根据每个类别包含基因数量的多少调整了小圈大小,避免看起来都一样大。代码还特别设置了数字上下分开显示(红字在上、蓝字在下),并且用连线把外围的小甜甜圈和中心大甜甜圈关联起来,让人一眼能看出这些类别都是从整体中分解出来的。

Medina CB, Mehrotra P, Arandjelovic S, Perry JSA, Guo Y, Morioka S, Barron B, Walk SF, Ghesquière B, Krupnick AS, Lorenz U, Ravichandran KS. Metabolites released from apoptotic cells act as tissue messengers. Nature. 2020 Apr;580(7801):130-135. doi: 10.1038/s41586-020-2121-3.

在这里插入图片描述

# =========================================================
# 甜甜圈富集分析(按总数缩放小圈大小,面积≈∝ up+down)
# 依赖:tidyverse, ggforce, scales
# =========================================================
library(tidyverse)
library(ggforce)
library(scales)# -------------------------
# 参数集中管理
# -------------------------
cfg <- list(R_pos = 8.5,                # 外圈整体半径lane_offset = 1.5,          # 两道车道错开r_outer_base = 1.50,        # 小圈外半径基准(仅做缩放幅度基准)inner_ratio = 0.70,         # 小圈厚度比例:r_in = inner_ratio * r_outnum_offset = 0.25,          # 圆内数字上下偏移(乘 r_out)center_r_out = 4.0,         # 中心大环外半径center_inner_ratio = 0.7,   # 中心大环厚度比例start_base = 0,             # 扇区起点:从正上方开始col_up = "#E41A1C",col_down = "#1F4ED8",r_out_range = c(0.8, 1.6)  # 小圈外半径相对范围(越大差异越明显)
)# -------------------------
# 数据(按需修改)
# -------------------------
dat <- tribble(~category,                                ~up, ~down,"Pro-inflammatory",                        31,   91,"Anti-inflammatory",                       68,   30,"OXPHOS",                                  12,    8,"Carbohydrate\nmetabolism",                53,   37,"DNA damage",                              53,   35,"Glycosylation",                           15,    5,"UPR/ER stress",                           22,   19,"Anti-apoptotic",                          79,   39,"Pro-apoptotic",                           41,   82,"Oxidative\nstress",                       29,   44,"Migration",                               97,  186,"Actin rearrangement/\ncell motility",     45,   70,"Adherence",                               25,   33,"Lipid/cholesterol/\nfatty acid metab.",   27,   56,"Vesicle transport",                       47,   90,"Autophagy",                               11,   62,"Cell size/\nvolume",                       9,   21
)# -------------------------
# 小函数:由 up/down 生成两段扇区
# -------------------------
mk_arcs <- function(up, down, x0, y0, r_in, r_out, start_base = -pi/2) {tot <- up + downfrac_up <- if (tot == 0) 0 else up / tottibble(part  = factor(c("Upregulated", "Downregulated"),levels = c("Upregulated", "Downregulated")),start = c(start_base, start_base + 2*pi*frac_up),end   = c(start_base + 2*pi*frac_up, start_base + 2*pi),x0 = x0, y0 = y0, r0 = r_in, r = r_out)
}# -------------------------
# 角度/车道与尺寸定位(半径∝√total → 面积≈∝total)
# -------------------------
n      <- nrow(dat)
angles <- seq(0, 2*pi, length.out = n + 1)[-(n + 1)]  # 12点起顺时针
lane   <- rep(c(1, -1), length.out = n)               # 车道交替dat2 <- dat %>%mutate(angle = angles,lane  = lane,total = up + down,# 半径缩放:把 √total 线性映射到 r_out_range,再乘基准r_out = cfg$r_outer_base * rescale(sqrt(total), to = cfg$r_out_range),r_in  = r_out * cfg$inner_ratio,# 仅外推(更大者略外推,减小重叠)R_i   = cfg$R_pos + cfg$lane_offset * lane + rescale(r_out, to = c(0, 0.35)),x0 = R_i * cos(angle),y0 = R_i * sin(angle),hjust_lab = if_else(cos(angle) >= 0, 0, 1),# 与中心环的连线起止点(随半径联动,避免穿透)link_r0 = cfg$center_r_out + 0.25,link_r1 = pmax(R_i - r_out - 0.25, cfg$center_r_out + 0.35),x_start = link_r0 * cos(angle), y_start = link_r0 * sin(angle),x_end   = link_r1 * cos(angle), y_end   = link_r1 * sin(angle))# 外圈全部小圈扇区
arcs <- pmap_dfr(dat2[, c("up", "down", "x0", "y0", "r_in", "r_out")],~ mk_arcs(..1, ..2, ..3, ..4, ..5, ..6, start_base = cfg$start_base)
) %>%mutate(id = rep(seq_len(n), each = 2)) %>%left_join(dat2 %>% mutate(id = row_number()) %>%select(id, category, angle, R_i, r_out),by = "id")# -------------------------
# 中心大甜甜圈(总 Up/Down)
# -------------------------
center_up   <- sum(dat$up)
center_down <- sum(dat$down)
center_tot  <- center_up + center_down
center_frac_up <- if (center_tot == 0) 0 else center_up / center_totcenter_ring <- tibble(part  = factor(c("Upregulated", "Downregulated"),levels = c("Upregulated", "Downregulated")),start = c(cfg$start_base, cfg$start_base + 2*pi*center_frac_up),end   = c(cfg$start_base + 2*pi*center_frac_up, cfg$start_base + 2*pi),x0 = 0, y0 = 0,r0 = cfg$center_inner_ratio * cfg$center_r_out,r  = cfg$center_r_out
)# -------------------------
# 绘图
# -------------------------
p <- ggplot() +# 1) 直线连线(底层)geom_segment(data = dat2,aes(x = x_start, y = y_start, xend = x_end, yend = y_end),linewidth = 0.6, color = "grey70", lineend = "round", alpha = 0.95) +# 2) 中心大环geom_arc_bar(data = center_ring,aes(x0 = x0, y0 = y0, r0 = r0, r = r, start = start, end = end, fill = part),color = "white", linewidth = 0.6) +# 3) 外圈小环geom_arc_bar(data = arcs,aes(x0 = x0, y0 = y0, r0 = r0, r = r, start = start, end = end, fill = part),color = "white", linewidth = 0.6) +# 4) 类别标签(随半径外扩)geom_text(data = dat2,aes(x = 1.05 * (R_i + r_out) * cos(angle),y = 1.05 * (R_i + r_out) * sin(angle),hjust = hjust_lab, label = category),size = 3.6, lineheight = 0.95) +# 5) 圆内红/蓝数字(上下调)geom_text(data = dat2,aes(x = x0, y = y0 + cfg$num_offset * r_out, label = up),size = 3.8, fontface = "bold", color = cfg$col_up) +geom_text(data = dat2,aes(x = x0, y = y0 - cfg$num_offset * r_out, label = down),size = 3.8, fontface = "bold", color = cfg$col_down) +# 6) 中心标题与总数annotate("text", x = 0, y = 0.8, label = "Significant genes",fontface = "bold", size = 4.3) +annotate("text", x = 0, y = -0.5,label = paste0("Up = ", center_up, "\nDown = ", center_down),size = 4, lineheight = 1.05, color = "gray20") +coord_fixed(xlim = c(-10, 10), ylim = c(-10, 10), clip = "off") +scale_fill_manual(values = c("Upregulated" = cfg$col_up,"Downregulated" = cfg$col_down)) +guides(fill = guide_legend(title = NULL, override.aes = list(color = NA))) +theme_void(base_size = 12) +theme(legend.position = c(0.99, 0.99),plot.margin = margin(40, 40, 40, 40))p

文章转载自:

http://nibNN7oD.sLpcL.cn
http://0eHOvdnG.sLpcL.cn
http://rgMag1iB.sLpcL.cn
http://8Gt3zaiJ.sLpcL.cn
http://OGdrPMD8.sLpcL.cn
http://IzrH07vR.sLpcL.cn
http://Er7Btu2w.sLpcL.cn
http://VTeLQt6Q.sLpcL.cn
http://FHwRe6mY.sLpcL.cn
http://2D03azTV.sLpcL.cn
http://97nl538Y.sLpcL.cn
http://odTmA2jP.sLpcL.cn
http://z2GCY5U9.sLpcL.cn
http://aY2hXeLG.sLpcL.cn
http://r9fwuO4s.sLpcL.cn
http://unX1N02U.sLpcL.cn
http://Smnmd3IL.sLpcL.cn
http://t7tsxRX0.sLpcL.cn
http://rmPDlCW1.sLpcL.cn
http://jfQLH5GB.sLpcL.cn
http://kHVVYWhr.sLpcL.cn
http://xDLDoYJw.sLpcL.cn
http://jycUeBoM.sLpcL.cn
http://XOesLi4L.sLpcL.cn
http://xECE2Dxv.sLpcL.cn
http://G5bTiV5B.sLpcL.cn
http://ZDdnaCAT.sLpcL.cn
http://fwDlQ08b.sLpcL.cn
http://TypuaalE.sLpcL.cn
http://2TZaaDAi.sLpcL.cn
http://www.dtcms.com/a/369940.html

相关文章:

  • PHP 发力 AI !PHP 官方 MCP SDK 正式发布
  • 从0死磕全栈第五天:React 使用zustand实现To-Do List项目
  • 从0死磕全栈第3天:React useState 实战,用 TS 手搓一个注册表单
  • MacOS 使用 luarocks+wrk+luajit
  • Rust在医疗系统中的应用:安全、性能与合规性实践(上)
  • 《云原生微服务治理进阶:隐性风险根除与全链路能力构建》
  • 006-Dephi 表达式 选择语句 循环语句其他语句
  • 深度学习:残差网络ResNet与迁移学习
  • SQL 实战指南:校园图书管理系统 SQL 设计(借阅 / 归还 / 库存查询实现)——超全项目实战练习
  • 输入2.2V~16V 最高输出20V2.5A DCDC升压芯片MT3608L
  • 人工智能学习:什么是seq2seq模型
  • 【基础-单选】singleton模式下首次进入的执行顺序是
  • 基于YOLO8的汽车碰撞事故检测系统【数据集+源码+文章】
  • 【c++进阶系列】:万字详解AVL树(附源码实现)
  • 【设计模式】 工厂方法模式
  • 总结-遇到
  • java分布式场景怎么实现一个高效的 读-写锁
  • 计算机毕设大数据方向:基于Spark+Hadoop的餐饮外卖平台数据分析系统【源码+文档+调试】
  • Java并发机制的底层实现原理
  • 数据结构:查找
  • PyQt5 多线程编程与排错技术文档
  • Linux 使用pip报错(error: externally-managed-environment )解决方案
  • Flask论坛与个人中心页面开发教程完整详细版
  • 【PostgreSQL】如何实现主从复制?
  • 进程与服务管理:systemd / sysvinit 服务管理、定时服务(cron / at)
  • Java全栈工程师面试实录:从基础到高并发场景的技术探索
  • 2025高教社国赛数学建模A题参考论文35页(含代码和模型)
  • 前缀和、子矩阵的和;差分、差分矩阵
  • 如何在 FastAPI 中巧妙覆盖依赖注入并拦截第三方服务调用?
  • LeetCode算法日记 - Day 34: 二进制求和、字符串相乘