前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >高颜值复杂热图绘制小技巧

高颜值复杂热图绘制小技巧

作者头像
生信技能树
发布于 2025-01-19 12:06:08
发布于 2025-01-19 12:06:08
9700
代码可运行
举报
文章被收录于专栏:生信技能树生信技能树
运行总次数:0
代码可运行

今天学习一篇高分杂志中的复杂热图绘制,文献标题为:《KRAS mutant rectal cancer cells interact with surrounding fibroblasts to deplete the extracellular matrix》,于 2021 年 10 月发表在 Mol Oncol 杂志上:

复杂热图介绍

这幅图展示了 两分组(KRAS-mt vs KRAS-wt)差异分析结果中 21个上调基因 与 14 个下调 差异基因在不同样本中的基因表达水平模式,热图上方 展示了 样本的许多临床性状特征 如 Stage分期,年龄,性别,CMS 分子分期等。热图如下:

图注

To gain further insight into the biological role of KRAS mutations in LARC, we investigated differences in gene expression between KRAS-mt and KRAS-wt tumors. A set of 35 genes were differentially expressed, including 21 upregulated genes and 14 downregulated genes in KRAS-mt specimens (Fig. 1D and Table S3).

数据背景

这幅热图对应的数据在 GEO 中:https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE170999

差异分析结果在 附件Table S3. Differentially Expressed Genes in KRAS-mt vs KRAS-wt Patients from the LARC-TIMING Cohort.

差异分析参数:

Differential analysis of mRNA expression was conducted using the ‘DESeq2’ package in R [26]. Significant differences were required to exhibit |log2FoldChange| > 1 and FDR < 0.05.

样本临床信息在Table S1. Clinicopathological Features of LARC-TIMING Patients

由于不管怎么设置差异基因筛选阈值都得不到图中的那个上下调基因数,这里直接 使用 kimi 从图片中获取了 21个上调基因 以及 14个下调基因,方法如下:

在 kimi (https://kimi.moonshot.cn/)对话框输入如下信息,并黏贴图片,就可以得到基因向量 直接复制到代码中

图片绘制

1、得到基因表达矩阵

GEO 数据我们已经非常熟悉了,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rm(list=ls)
## 加载Rlibrary(AnnoProbe)
library(GEOquery)
library(ggplot2)
library(ggstatsplot)
library(patchwork)
library(reshape2)
library(stringr)
library(limma)
library(tidyverse)
getOption('timeout')
options(timeout=10000)

## 1.获取并且检查表达量矩阵
## ~~~gse编号需修改~~~
gse_number <- "GSE170999"
dir.create(gse_number)
setwd(gse_number)
getwd()
list.files() 

#gset <- geoChina(gse_number)
gset <- getGEO(gse_number, destdir = '.', getGPL = T)
gset[[1]]
a <- gset[[1]]

## 2.样本分组
## 挑选一些感兴趣的临床表型。
pd <- pData(a)
colnames(pd)
pd$title
pd$characteristics_ch1
table(pd$characteristics_ch1)

## ~~~分组信息编号需修改~~~
group_list <- pd[, c("geo_accession","title","kras_mutant or wild_type:ch1")]
head(group_list)

## 3.提取探针水平表达矩阵
dat <- exprs(a) # a现在是一个对象,取a这个对象通过看说明书知道要用exprs这个函数
dim(dat)        # 看一下dat这个矩阵的维度
dat[1:4,1:4]    # 查看dat这个矩阵的14行和14列,逗号前为行,逗号后为列


## ~~~查看数据是否需要log~~~
range(dat)

## 4.探针转换为基因symbol
## 查看注释平台gpl 获取芯片注释信息
gpl_anno <- fData(a)
colnames(gpl_anno)

id2name <- gpl_anno[,c("ID" ,"Gene Symbol")]
colnames(id2name) <- c("ID","GENE_SYMBOL")
# 1.过滤掉空的探针
id2name <- na.omit(id2name)
id2name <- id2name[which(id2name$GENE_SYMBOL!=""), ]
# 2.过滤探针一对多
id2name <- id2name[!grepl("\\///",id2name$GENE_SYMBOL), ]
head(id2name)
# 3.多对一取均值
# 合并探针ID 与基因,表达谱对应关系
# 提取表达矩阵
dat <- dat %>% 
  as.data.frame() %>% 
  rownames_to_column("ID")

exp <- merge(id2name, dat, by.x="ID", by.y="ID")

# 多对一取均值
exp <- avereps(exp[,-c(1,2)],ID = exp$GENE_SYMBOL) %>% 
  as.data.frame()

dat <- as.matrix(exp[,pd$geo_accession])
dim(dat)
fivenum(dat['CRP',])
fivenum(dat['GAPDH',])
dat[1:5, 1:6]
save(gse_number, dat, group_list, pd, file = 'step1_output.Rdata')

2、读取样本临床信息

使用 excel 读取进来,并进行一些预处理,如 连续值的 Age 变为分组的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
library(readxl)

# 临床信息
table_s1 <- readxl::read_xlsx("mol212960-sup-0005-tables1-s8.xlsx", sheet = "Table S1") 
head(table_s1)
head(group_list)
group_list$SampleID <- str_split(group_list$title, pattern = "r, ", n=2, simplify = T)[,2]
clinical <- merge(group_list, table_s1, by="SampleID")
head(clinical)
rownames(clinical) <- clinical$geo_accession

## 处理 KRAS_mutation
grep(">|_|Q61|A146P",clinical$KRAS_details, value = T)
grep("G12|G13",clinical$KRAS_details, value = T, invert = F)
grep("wt",clinical$KRAS_details, value = T)

clinical$KRAS_mutation <- clinical$KRAS_details
clinical$KRAS_mutation[ grep(">|_|Q61|A146P",clinical$KRAS_details) ] <- "Other"
clinical$KRAS_mutation[ grep("G12|G13",clinical$KRAS_details) ] <- "KRAS G12/13"
table(clinical$KRAS_mutation)

# 处理 AJCC stage
table(clinical$PreCRT_AJCC_classification)
clinical$Stage <- ifelse(clinical$PreCRT_AJCC_classification==2, "Stage II", "Stage III")
table(clinical$Stage)

# 处理 Age 
clinical$Age <- "[40,60]"
clinical$Age[ clinical$Age.Dx < 40 ] <- "< 40"
clinical$Age[ clinical$Age.Dx > 60 ] <- "> 60"
table(clinical$Age)
table(clinical$Gender)
table(clinical$Rectal_location)
table(clinical$CMS_class)
table(clinical$KRAS_status)

# 选择图中的临床性状
clinical <- clinical[, c("Stage", "Age", "Gender","Rectal_location","CMS_class","KRAS_mutation","KRAS_status")]

head(clinical)

clinical结果如下:

3、拿到差异基因的表达矩阵

直接用 kimi 拿到图片中的基因:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 21个上调
genes <- c("SDR16C5", "TFF1", "FCGBP", "SAMD5", "KRT6B", "RHOBTB3", "AGR3", "CTSE", "REG4", "S100P", 
           "SLC14A1", "CYP3A5", "LYZ", "KLK10", "SULT1C2", "IL33", "MUC2", "TRIM29", "MLPH", "HOXB6", "HOXB8")
exp_up <- dat[genes, ]

# 14个下调
genes <- c("PPBP", "COL1A1", "CXCL5", "GNG4", "FN1", "P2RX5", "POSTN", "MXRA5", "SPARC", "SPP1", 
           "COL1A2", "COL12A1", "TMEM200A", "THBS2")
exp_down <- dat[genes, ]

# 合并在一起
exp <- rbind(exp_up, exp_down)

# 对表达矩阵 进行行聚类
exp_scale <- t(scale(t(exp)))
exp_scale[exp_scale>4] <- 4
exp_scale[exp_scale< -4] <- -4

4、使用 complexheatmap绘图

complexheatmap 功能使用起来比较复杂,这里简单介绍一下各种参数。

首先进行列注释条构建,使用的函数为 HeatmapAnnotation

  • df 参数 输入一个矩阵,行名 与 表达矩阵列名对应;
  • simple_anno_size 参数可以设置 列注释条的高度;
  • col 可以设置 每一个 注释条里面的 颜色,是一个list对象。获取文章中的颜色配置 可以 使用 Snipaste 工具,非常方便;
  • gp参数 设置 注释条的边框颜色;
  • gap = unit(2, "mm")):控制每两个相邻注释之间的空间。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 列注释条
annotation_col <- data.frame(clinical)
row.names(annotation_col) <- colnames(exp)
head(annotation_col)

df <- annotation_col[, -7]

# 列注释条
ha = HeatmapAnnotation(
  df = df,
  annotation_name_side="right",
  simple_anno_size = unit(0.3, "cm"), # 设置注释条高度
  col = list(Stage = c("Stage II" = "black", "Stage III" = "grey"),
             Age = c("< 40" = "white", "[40,60]" = "#75b1da", "> 60" = "#1a3a87"),
             Gender = c("F" = "#e6b8d7", "M" = "#7fccdf"),
             Rectal_location = c("Lower(<4)" = "#fdeae1", "Middle(4-8)" = "#ec6143", "Upper(>8)" = "#a51410","Not Available"="#c8c5c5"),
             CMS_class =c("CMS1"="#dc020d","CMS2"="#4ba733","CMS3"="#357cb9","CMS4"="#9e4795"),
             KRAS_mutation=c("wt"="white","KRAS G12/13"="#be111f","Other"="#fcd16f")
             ),
  annotation_legend_param = list(
    Stage = list(direction = "horizontal",ncol = 1),
    Age = list(direction = "horizontal",ncol = 1),
    Gender = list(direction = "horizontal",ncol = 1),
    Rectal_location = list(direction = "horizontal",ncol = 1),
    CMS_class = list(direction = "horizontal",ncol = 1),
    KRAS_mutation = list(direction = "horizontal",ncol = 1)),
  gp = gpar(col = "black"),
  gap = unit(2, "mm") # 控制每两个相邻注释之间的空间
)

进行绘图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
p <- Heatmap(exp_scale, # 表达矩阵        
             col = colorRampPalette(c("#524b9a","white","#e63118"))(100),#颜色定义 
             name = "Gene Expression\n(Z-score)", # 设置表达矩阵的图例标题
             heatmap_legend_param = list(direction = "horizontal",nrow = 1),
             show_row_names = T,     # 展示行名
             show_column_names = F,  # 不显示列名
             show_row_dend = F,
             show_column_dend = F,
             top_annotation = ha,       # 顶部分组信息  
             column_title_side = c("top"),
             column_split = annotation_col$KRAS_status, # 用group 信息将热图分开,以 group 聚类
             row_split = annotation_row$gene_class,
             column_title = T 
             )   
p

# 保存
pdf(file = "diff_heatmap.pdf", height = 9, width = 12)
draw(p, heatmap_legend_side = "bottom", annotation_legend_side = "bottom",merge_legend = TRUE)
dev.off()

结果如下:

最后,超多参数 推荐大家去官网阅读学习:https://jokergoo.github.io/ComplexHeatmap-reference/book/index.html

如果你有好看的图,可以 留言区给出你的图片来源,我们尽可能的复现出来,学会更多的高颜值绘图技巧!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信技能树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
"RDLC"报表-参数传递及主从报表
今天继续学习RDLC报表的“参数传递”及“主从报表” 一、先创建DataSet,如下图: 二、创建一个报表rptDEPT.rdlc,显示部门T_DPET的数据 三、嵌入Default.aspx中,写在
菩提树下的杨过
2018/01/23
3.1K0
"RDLC"报表-参数传递及主从报表
ReportViewer不连接数据库,自定义DataSet导出到报表
最近在看报表这一块,在网上找到的大都是连接数据库的,对于自定义的DataTable数据没有详细的连接说明,经过一番寻找,总结一下大概方法,大神请直接无视
冰封一夏
2019/09/11
1.2K0
ReportViewer不连接数据库,自定义DataSet导出到报表
"RDLC报表"速成指南
RDLC报表是微软自家的报表,已经集成在vs2010中,相对水晶报表更轻量级,更重要的是:可直接在web项目中使用。 使用步骤: 一、创建DataSet 右击->Add New Item-> Data
菩提树下的杨过
2018/01/23
3.7K0
"RDLC报表"速成指南
rdlc
https://stackoverflow.com/questions/4652347/dynamically-binding-of-dataset-to-rdlc-reports
landv
2020/02/11
7350
RDLC(Reportview)报表直接打印,支持所有浏览器,客户可在linux下浏览使用
最近在做一个打印清单的,但是rdlc报表自带的工具栏中的打印按钮只有在ie内核下的浏览器才可以使用(其他的就会 隐藏),这导致了使用火狐和谷歌浏览器还有使用linux系统的客户打印成了问题,于是就自己百度搜,谷歌搜,然后就解决了,下面放上源码
冰封一夏
2019/09/11
2.2K0
动态生成RDLC报表
1、从DataGrid提取(包括最新的增删改)数据,自动生成对应的RDLC报表文件(以流的形式驻存在内存中),用ReportViewer类来展示、打印、排版、预览、分页
NaughtyCat
2020/10/09
8.6K0
动态生成RDLC报表
RDLC报表多条件分组
一个报表如果要先按A分组,然后再按B分组,再按C分组...这种多条件分组情况下,RDLC报表处理起来并不方便。 只能另辟蹊径,想些歪招了: 比如有一张员工表,里面有公司编码COMPANYCODE,部门号DEPTNO,员工号EMPNO,员工姓名EMPNAME 需要在报表上,先按公司分组,相同公司的再按部门分组 看看下面的处理代码 DataTable dt = new DataTable(); dt.Columns.Add("EMPNO", typeof(stri
菩提树下的杨过
2018/01/24
1.5K0
RDLC报表多条件分组
C#实例:datagridview单元格合并
这是替C#微信交流群群友做的一个小实例,目的就是在datagridview选择对应行以后,点击button后获取对应行的ip,并执行相应的操作,其实我觉得这样的话button没必要非放置到datagridview里面的!但是为了满足群友的需求,还是这么做了。
zls365
2020/08/19
5.2K0
C#实例:datagridview单元格合并
动态生成TreeView方法(一)
一般情况下生成TreeView我们用的是用递归不建议用递归数据量大了会慢, 小弟今天用SortedList集合实现一下没有技术含量,一看代码大家就会明白。个人也比较喜欢这种方法,数据量大了执行速度也可
lpxxn
2018/01/31
1.4K0
动态生成TreeView方法(一)
ChartControl控件绘制折线图
在GridControl控件中点击Run Designer,添加三列数据并分别设置FieldName(与数据库中对应)
别团等shy哥发育
2023/02/27
8780
ChartControl控件绘制折线图
【愚公系列】2023年11月 Winform控件专题 Chart控件详解
Winform控件是Windows Forms中的用户界面元素,它们可以用于创建Windows应用程序的各种视觉和交互组件,例如按钮、标签、文本框、下拉列表框、复选框、单选框、进度条等。开发人员可以使用Winform控件来构建用户界面并响应用户的操作行为,从而创建功能强大的桌面应用程序。
愚公搬代码
2023/11/30
3.4K0
C#代码示例:在WinForm中创建并绑定一个DataTable
在我的一篇文章中,我解释了如何在没有数据库的情况下以web形式绑定gridview。这里,我将解释如何在没有数据库的windows窗体中绑定datagrid。
程序你好
2018/07/23
4.1K0
C# excel文件导入导出
在C#交流群里,看到很多小伙伴在excel数据导入导出到C#界面上存在疑惑,所以今天专门做了这个主题,希望大家有所收获!
zls365
2020/08/19
3.9K0
C# excel文件导入导出
动态生成TreeView方法(二)
这次是用递归的方法实现 ,我想大家都知道怎么做吧,就不 多说了, 还是不建议用递归,数据量大了会映响速度,动态生成TreeView方法(一)是我比较喜欢的方法 看一下效果图 前台代码: <%@ Pag
lpxxn
2018/01/31
1.4K0
动态生成TreeView方法(二)
如何在CRM系统中集成ActiveReports最终报表设计器
有时候,将ActiveReports设计器集成到业务系统中,为用户提供一些自定义的数据表,用户不需要了解如何底层的逻辑关系和后台代码,只需要选择几张关联的数据表,我们会根据用户的选择生成可供用户直接使
葡萄城控件
2018/01/10
1.3K0
如何在CRM系统中集成ActiveReports最终报表设计器
List,DataTable实现行转列的通用方案
本文通过行转列引出System.Linq.Dynamic,并介绍了过滤功能,其实它的用处还有很多,等待大家发掘。
用户1168362
2018/01/05
2.1K0
List,DataTable实现行转列的通用方案
合并两个结构完全相同的DataTable
两个结构一模一样的DataTable如何合并? 例子:使用Winform进行演示,表2的数据为固定的,表1的数据可以动态添加,通过合并按钮合并表1和表2的数据到表3 1.规定公共的DataTable结
用户1055830
2018/01/18
2.1K0
合并两个结构完全相同的DataTable
【愚公系列】2023年11月 Winform控件专题 DataGridView控件详解
Winform控件是Windows Forms中的用户界面元素,它们可以用于创建Windows应用程序的各种视觉和交互组件,例如按钮、标签、文本框、下拉列表框、复选框、单选框、进度条等。开发人员可以使用Winform控件来构建用户界面并响应用户的操作行为,从而创建功能强大的桌面应用程序。
愚公搬代码
2023/11/30
2.7K0
.NET连接SAP系统专题:C#调用RFC代码(三)
    本文就说明在C#中如何编写代码来调用SAP中的RFC函数获取数据。(Winform32)
SAP梦心
2022/05/10
1.8K0
.NET连接SAP系统专题:C#调用RFC代码(三)
Linq 和DefaultView两种方法去掉DataTable 里的重复行
在做项目的时候经常会遇到DataTable 里的数据重复,或者合并两个DataTable后有数据重复 一般我们是想把重复的删除掉,还有其它的方式实现比如用Linq和DataTable的DefaultV
lpxxn
2018/01/31
1.6K0
Linq 和DefaultView两种方法去掉DataTable 里的重复行
推荐阅读
相关推荐
"RDLC"报表-参数传递及主从报表
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 复杂热图介绍
  • 数据背景
  • 图片绘制
    • 1、得到基因表达矩阵
    • 2、读取样本临床信息
    • 3、拿到差异基因的表达矩阵
    • 4、使用 complexheatmap绘图
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档