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

高分Panel复现系列|三元突变比例图:从三组比例到三角坐标映射

三元图适合展示一个事件在三个类别之间的组成倾向。这里每个点代表一个基因或突变事件,位置由 Low Grade Glioma、Primary GBM 和 Secondary GBM 三组比例共同决定。


图片来源

项目内容
文章Mutational Landscape of Secondary Glioblastoma Guides MET-Targeted Trial in Brain Tumor
期刊/年份Cell, 2018
图号Figure 1B
DOI/链接https://doi.org/10.1016/j.cell.2018.09.038

这张图用三元坐标把不同基因改变在低级别胶质瘤、原发 GBM、继发 GBM 中的相对富集方向放到同一个三角形里,非常适合做“三组组成比例”的可视化复现。


图片解读

这是一张 ternary plot,三元比例图。

三角形三个顶点分别代表三个类别:

顶点含义
顶部Low Grade Glioma
左下角Primary GBM
右下角Secondary GBM

每个点代表一个基因改变或分子事件。点越靠近某个顶点,说明它在该类别中的比例越高。点的大小可以映射事件强度、频率或重要性;点的颜色可以映射其中一个类别的比例,例如 Secondary GBM 占比。


输入数据

输入数据需要是长表,每一行代表一个基因或事件,三组比例相加最好为 100。

列名含义
alteration基因或事件名称
low_grade_gliomaLow Grade Glioma 中的比例
primary_gbmPrimary GBM 中的比例
secondary_gbmSecondary GBM 中的比例
score点大小映射值
label_dx标签横向微调
label_dy标签纵向微调
library(tidyverse)dat<-read_csv("input_data.csv",show_col_types=FALSE)
需要示例数据的后台添加小编领取,调整好数据结构,以下代码可以直接复制粘贴运行。


第一步:把三组比例转换成三角坐标

三元图本质上是把三个比例映射到一个等边三角形中。这里不依赖额外三元图包,直接用坐标变换完成。

tri_h<-sqrt(3)/2to_xy<-function(low_grade_glioma,primary_gbm,secondary_gbm){total<-low_grade_glioma+primary_gbm+secondary_gbm tibble(x=(secondary_gbm+0.5*low_grade_glioma)/total,y=tri_h*low_grade_glioma/total)}point_df<-bind_cols(dat,to_xy(dat$low_grade_glioma,dat$primary_gbm,dat$secondary_gbm))|>mutate(lab_x=x+label_dx,lab_y=y+label_dy)

第二步:绘制三角边框和内部网格

三元图的阅读依赖网格线。这里分别绘制三个方向的 20、40、60、80 辅助线。

triangle<-tibble(x=c(0,1,0.5,0),y=c(0,0,tri_h,0))make_seg<-function(type,value,start,end){tibble(type=type,value=value,x=start$x,y=start$y,xend=end$x,yend=end$y)}grid_df<-purrr::map_dfr(seq(20,80,by=20),function(v){bind_rows(make_seg("low",v,to_xy(v,100-v,0),to_xy(v,0,100-v)),make_seg("primary",v,to_xy(100-v,v,0),to_xy(0,v,100-v)),make_seg("secondary",v,to_xy(100-v,0,v),to_xy(0,100-v,v)))})

第三步:添加刻度、顶点标签和方向箭头

顶点标签用不同颜色强调三个类别,方向箭头用于提示三组比例变化趋势。

tick_low<-tibble(value=seq(20,80,by=20))tick_low<-bind_cols(tick_low,to_xy(tick_low$value,100-tick_low$value,0))|>mutate(label=as.character(value),angle=-60,x=x-0.045,y=y)tick_primary<-tibble(value=seq(20,100,by=20))tick_primary<-bind_cols(tick_primary,to_xy(0,tick_primary$value,100-tick_primary$value))|>mutate(label=as.character(value),angle=55,x=x-0.018,y=y-0.040)tick_secondary<-tibble(value=seq(20,100,by=20))tick_secondary<-bind_cols(tick_secondary,to_xy(0,100-tick_secondary$value,tick_secondary$value))|>mutate(label=as.character(value),angle=0,x=x,y=y-0.043)axis_lab<-tribble(~label,~x,~y,~col,~hjust,"Low Grade Glioma",0.50,tri_h+.045,"blue",0.5,"Primary\nGBM",-0.085,-0.055,"magenta",0.5,"Secondary\nGBM",1.085,-0.055,"red",0.5)arrow_df<-tribble(~x,~y,~xend,~yend,~col,-0.11,0.46,-0.23,0.30,"#bb33ff",0.50,-0.11,0.72,-0.11,"#e0007a",1.10,0.30,0.94,0.47,"#4050ff",1.10,0.30,1.21,0.17,"#d81b60")

第四步:叠加突变点和基因标签

点的位置由三组比例决定,点大小用score控制,颜色用secondary_gbm控制。标签可以通过label_dxlabel_dy做局部微调。

p<-ggplot()+geom_segment(data=grid_df,aes(x,y,xend=xend,yend=yend),color="#e6e6e6",linewidth=0.25)+geom_path(data=triangle,aes(x,y),linewidth=0.42,color="black")+geom_text(data=bind_rows(tick_low,tick_primary,tick_secondary),aes(x,y,label=label,angle=angle),size=1.80,color="#3a3a3a")+geom_curve(data=arrow_df,aes(x,y,xend=xend,yend=yend,color=col),curvature=0,linewidth=0.60,arrow=arrow(length=unit(0.055,"inches")),show.legend=FALSE)+geom_point(data=point_df,aes(x,y,size=score,fill=secondary_gbm),shape=21,color="black",stroke=0.32,alpha=0.96)+geom_segment(data=point_df,aes(x,y,xend=lab_x,yend=lab_y),color="#333333",linewidth=0.16,alpha=0.55)+geom_text(data=point_df,aes(lab_x,lab_y,label=alteration),size=2.05,fontface="italic",color="#202020")+geom_text(data=axis_lab,aes(x,y,label=label,color=col,hjust=hjust),size=2.15,lineheight=0.90,show.legend=FALSE)+scale_fill_gradientn(colours=c("#f1d8f8","#7a237d","#cf0017"),limits=c(0,100))+scale_size(range=c(1.30,4.55),guide="none")+scale_color_identity()+coord_equal(xlim=c(-0.23,1.23),ylim=c(-0.13,tri_h+0.08),clip="off")+theme_void()+theme(legend.position="none",plot.background=element_rect(fill="white",color=NA),plot.margin=margin(10,14,12,14))

第五步:导出图片

ggsave("ternary_glioma_alteration.png",p,width=3.7,height=3.05,dpi=420,bg="white")ggsave("ternary_glioma_alteration.pdf",p,width=3.7,height=3.05,bg="white")

完整代码

library(tidyverse)library(scales)dat<-read_csv("input_data.csv",show_col_types=FALSE)tri_h<-sqrt(3)/2to_xy<-function(low_grade_glioma,primary_gbm,secondary_gbm){total<-low_grade_glioma+primary_gbm+secondary_gbm tibble(x=(secondary_gbm+0.5*low_grade_glioma)/total,y=tri_h*low_grade_glioma/total)}point_df<-bind_cols(dat,to_xy(dat$low_grade_glioma,dat$primary_gbm,dat$secondary_gbm))|>mutate(lab_x=x+label_dx,lab_y=y+label_dy)triangle<-tibble(x=c(0,1,0.5,0),y=c(0,0,tri_h,0))make_seg<-function(type,value,start,end){tibble(type=type,value=value,x=start$x,y=start$y,xend=end$x,yend=end$y)}grid_df<-purrr::map_dfr(seq(20,80,by=20),function(v){bind_rows(make_seg("low",v,to_xy(v,100-v,0),to_xy(v,0,100-v)),make_seg("primary",v,to_xy(100-v,v,0),to_xy(0,v,100-v)),make_seg("secondary",v,to_xy(100-v,0,v),to_xy(0,100-v,v)))})tick_low<-tibble(value=seq(20,80,by=20))tick_low<-bind_cols(tick_low,to_xy(tick_low$value,100-tick_low$value,0))|>mutate(label=as.character(value),angle=-60,x=x-0.045,y=y)tick_primary<-tibble(value=seq(20,100,by=20))tick_primary<-bind_cols(tick_primary,to_xy(0,tick_primary$value,100-tick_primary$value))|>mutate(label=as.character(value),angle=55,x=x-0.018,y=y-0.040)tick_secondary<-tibble(value=seq(20,100,by=20))tick_secondary<-bind_cols(tick_secondary,to_xy(0,100-tick_secondary$value,tick_secondary$value))|>mutate(label=as.character(value),angle=0,x=x,y=y-0.043)axis_lab<-tribble(~label,~x,~y,~col,~hjust,"Low Grade Glioma",0.50,tri_h+.045,"blue",0.5,"Primary\nGBM",-0.085,-0.055,"magenta",0.5,"Secondary\nGBM",1.085,-0.055,"red",0.5)arrow_df<-tribble(~x,~y,~xend,~yend,~col,-0.11,0.46,-0.23,0.30,"#bb33ff",0.50,-0.11,0.72,-0.11,"#e0007a",1.10,0.30,0.94,0.47,"#4050ff",1.10,0.30,1.21,0.17,"#d81b60")p<-ggplot()+geom_segment(data=grid_df,aes(x,y,xend=xend,yend=yend),color="#e6e6e6",linewidth=0.25)+geom_path(data=triangle,aes(x,y),linewidth=0.42,color="black")+geom_text(data=bind_rows(tick_low,tick_primary,tick_secondary),aes(x,y,label=label,angle=angle),size=1.80,color="#3a3a3a")+geom_curve(data=arrow_df,aes(x,y,xend=xend,yend=yend,color=col),curvature=0,linewidth=0.60,arrow=arrow(length=unit(0.055,"inches")),show.legend=FALSE)+geom_point(data=point_df,aes(x,y,size=score,fill=secondary_gbm),shape=21,color="black",stroke=0.32,alpha=0.96)+geom_segment(data=point_df,aes(x,y,xend=lab_x,yend=lab_y),color="#333333",linewidth=0.16,alpha=0.55)+geom_text(data=point_df,aes(lab_x,lab_y,label=alteration),size=2.05,fontface="italic",color="#202020")+geom_text(data=axis_lab,aes(x,y,label=label,color=col,hjust=hjust),size=2.15,lineheight=0.90,show.legend=FALSE)+scale_fill_gradientn(colours=c("#f1d8f8","#7a237d","#cf0017"),limits=c(0,100))+scale_size(range=c(1.30,4.55),guide="none")+scale_color_identity()+coord_equal(xlim=c(-0.23,1.23),ylim=c(-0.13,tri_h+0.08),clip="off")+theme_void()+theme(legend.position="none",plot.background=element_rect(fill="white",color=NA),plot.margin=margin(10,14,12,14))ggsave("ternary_glioma_alteration.png",p,width=3.7,height=3.05,dpi=420,bg="white")ggsave("ternary_glioma_alteration.pdf",p,width=3.7,height=3.05,bg="white")

复现结果


参考链接

  • DOI: https://doi.org/10.1016/j.cell.2018.09.038
  • 文章链接: https://www.cell.com/cell/fulltext/S0092-8674(18)31250-9
http://www.gsyq.cn/news/1616072.html

相关文章:

  • 2026年食品行业PLM系统实施路径:从需求梳理到平台落地的关键步骤
  • 薄膜沉积CVD/PVD/ALD怎么选:一文看懂适用场景
  • 【Java】Java永久代:从诞生到终结的演进史
  • 该原标题存在营销诱导词,不符合要求,若按照关键词“重罪辩护”生成趋势洞察型标题,可改为:2026年重罪辩护行业趋势洞察:策略与挑战并存
  • 2026最新AI论文工具全解析,从新手到高手的进阶必备攻略
  • YimMenu终极指南:GTA5免费增强菜单与安全防护完全教程
  • Tool 定义进阶:异步处理、流式输出、进度反馈与错误码规范的生产级标准
  • 数据结构 五
  • ROG幻16Air Type-C外接显示器休眠唤醒雪花屏问题分析与解决
  • 济南天桥区上门电脑维修
  • 物理时空的数字降维:企微API智能硬件IoT边缘枢纽的MQTT多路复用、离线重放整形与时钟校验架构
  • 【2026最新版】全网最全网络攻防教程(0基础到进阶、漏洞挖掘、CTF比赛、就业等等)
  • 技术拆解:电子护照芯片数据为何绝对可信、无法篡改?
  • B站评论采集实践:如何快速获取评论数据并接入AI分析平台
  • Windows10上安装MySQL操作步骤
  • ABAP :新语法 - REF
  • 当灯光“躲”进陪伴机器人:智能照明的隐藏式进化与异业合作新浪潮
  • 从零到一:在STM32上跑通TinyML的完整实践指南
  • 哔哩下载姬完整指南:告别网络焦虑,轻松掌控B站视频资源
  • 工业4-20mA电流环设计:DAC161S997与PIC32实战解析
  • HarmonyOS7 缓存不是越多越好:图片、数据、视图多层缓存策略这样定
  • VSCode JSON 样式
  • 2026年6月份化工储存用玻璃钢储罐,源头生产企业该如何筛选
  • 亿俐缇国际物流(YLT GLOBAL)——中东双清包税门到门物流服务的优势与特点
  • Spring Cloud Alibaba 生产级实战:16 个模块覆盖全栈微服务
  • 亲测有效:瑜伽缓解腰痛的南湖实践分享
  • 预约小程序怎么搭建?全球5款工具实测:餐宝盈/BBWEYY/比文云/Brizy/PageXL(2026年7月更新),含零代码SAAS、AI编程、源码定制交付
  • STC3115+PIC18F97J94电池监控系统设计与优化
  • 四个看不见的成本漏洞,系统一个一个帮你堵上
  • HarmonyOS7 购物车看着简单最容易翻车:增删改、全选、价格计算一篇讲透