distinct group by一起用_用ggplot2来画带有对角线的热图。
最近有人在群里提问,下面的热图该怎么画。
这张热图,在每一个格子里面用对角线一分为二,呈现了两类信息。图片来自于这篇文章的图1D。
通常,遇到这种需求,我都会直接检索,看看有没有现成的R包可用。可以提取检索词检索一下,这里主要信息应该是"对角线 热图 R语言",
查阅字典后,关键词就变成了英文,“diagonal heatmap r”。在浏览器中检索后得到以下结果。
然后有人给出了使用base plot画图的方案
d=data.frame(p1=rep(LETTERS[1:2],times=2,each=2), p2=rep(LETTERS[4:5],times=4), value=c(.2,.4,.56,.32,.7,.16,.12,.71), group=rep(c("A1","B1"),each=4))
x=as.numeric(d$p1)y=as.numeric(d$p2)
plot(1,xlim=c(1,length(unique(x))+1),ylim=c(1,length(unique(y))+1), type="n",bty="n",xaxt="n",yaxt="n",xlab="",ylab="")
for(i in 1:nrow(d)) { if(d$group[i]=="A1") polygon(x[i]+c(0,1,1),y[i]+c(0,0,1),col=gray(d$value[i])) if(d$group[i]=="B1") polygon(x[i]+c(0,1,0),y[i]+c(0,1,1),col=gray(d$value[i]))}
axis(1,at=sort(unique(x))+.5,labels=levels(d$p1),lty=0)axis(2,at=sort(unique(y))+.5,labels=levels(d$p2),lty=0)
复制到R语言后运行得到如下结果
这意味着,只要用基本功扎实,复现原图是没有问题的。
但是,我不会base plot,我只会用ggplot2, 检索了一圈也没有现成的解决方案,所以我就准备自己画。
自己画我就开始拆分这张图,一个热图的格子由上下两个三角形构成,我可以先画上三角形,再画下三角形,然后给他们分别配色就可以。
三角形可以通过geom_polygon
来画。
## 下三角数据cone1 = data.frame(x = c(1,2,2), y = c(1,1,2))library(dplyr)library(ggplot2)## 下三角画图cone1 %>% ggplot(aes(x=x, y=y)) + geom_polygon(fill="#213c18")
上三角也是一样的
## 上三角数据cone2 = data.frame(x = c(1,1,2), y = c(1,2,2)) ## 上三角画图cone2 %>% ggplot(aes(x=x, y=y)) + geom_polygon(fill = "#668c6f")
通过叠加图层,我们可以把两个三角形放在一起,这就是热图的一个小格子
cone1 %>% ggplot(aes(x=x, y=y)) + geom_polygon(fill="#213c18")+ geom_polygon(data=cone2, fill = "#668c6f")
解决了基本的元素,我就可以批量产生数据。
下面写了一个函数,批量算出指定行列的三角形数据。
trianle function(a,b,type="up"){ ## 单个下三角数据的函数 trianle_down function(a,b){ data.frame(x=c(0,1,1)+a, y= c(0,0,1)+b, group=paste0(a,"_",b), stringsAsFactors = F) } ## 单个上三角数据的函数 trianle_up function(a,b){ data.frame(x=c(0,0,1)+a, y= c(0,1,1)+b, group=paste0(a,"_",b), stringsAsFactors = F) } ### 批量产生上三角的数据 if(type=="up"){ data do.call(rbind,lapply(1:b, function(i){ do.call(rbind,lapply(1:a,trianle_up,i)) })) } ### 批量产生下三角的数据 if(type=="down"){ data do.call(rbind,lapply(1:b, function(i){ do.call(rbind,lapply(1:a,trianle_down,i)) })) } return(data)}
因为我们的测试数据是33行,20列,所以用这个函数来产生对应个数的三角形
updata 33,20,"up")downdata 33,20,"down")
updata的数据是这样的,每一个框线里面都是一个三角形的数据
可以作图来测试一下上三角形
library(ggplot2)updata %>% ggplot(aes(x=x, y=y)) + geom_polygon(aes(group=group,fill=group))+ theme(legend.position = "none")
下三角也是一样的
downdata %>% ggplot(aes(x=x, y=y)) + geom_polygon(aes(group=group,fill=group))+ theme(legend.position = "none")
现在我比较安心了,只要调整原始数据的格式,然后把他跟三角形的数据匹配起来就行。匹配就依靠group那一列
读入第一个数据, 行是基因,列是癌症类型
dd table::fread("easy_input_amp.txt",data.table = F)
接下来宽数据变长
library(dplyr)library(tidyr)data1 % ## 数据变长 pivot_longer(-1, names_to = "type", values_to = "exp") %>% rename(gene=V1)
现在的数据是这个样子的
如果想要改变未来热图基因的顺序,可以使用因子的水平来控制
data1$gene $gene, levels = c("ALKBH5","FTO", "HNRNPA2B1","HNRNPC", "IGF2BP1", "IGF2BP2","IGF2BP3","RBMX","YTHDC1","YTHDC2","YTHDF1","YTHDF2","YTHDF3", "METTL14","METTL3","RBM15","RBM15B","VIRMA","WTAP","ZC3H13"), ordered = F)
接下来就是给这个数据增加能够和三角形group匹配的列,
这一步的操作有trick,比如,因子转为数值,是需要先变成字符串再变成字符的,但是我们这里直接as.numeric
可以获取他的levels数值
data1 % mutate(a=as.numeric(as.factor(type)), b=as.numeric(gene)) %>% mutate(group = paste0(a,"_",b)) %>% as.data.frame() %>% inner_join(updata,by="group")
最终获取了完整的作图数据
有了数据,作图就很简单了
library(ggplot2)data1 %>% ggplot(aes(x=x, y=y)) + geom_polygon(aes(group=group,fill=exp))+ theme(legend.position = "none")
第二个数据也是同样的处理
dd "easy_input_del.txt",data.table = F)data2 % pivot_longer(-1, names_to = "type", values_to = "del") %>% rename(gene=V1)
data2$gene levels = c("ALKBH5","FTO", "HNRNPA2B1","HNRNPC", "IGF2BP1", "IGF2BP2","IGF2BP3","RBMX","YTHDC1","YTHDC2","YTHDF1","YTHDF2","YTHDF3", "METTL14","METTL3","RBM15","RBM15B","VIRMA","WTAP","ZC3H13"), ordered = F)data2 % mutate(a=as.numeric(as.factor(type)), b=as.numeric(as.factor(gene))) %>% mutate(group = paste0(a,"_",b)) %>% as.data.frame() %>% inner_join(downdata,by="group")
data2 %>% ggplot(aes(x=x, y=y)) + geom_polygon(aes(group=group,fill=del))+ theme(legend.position = "none")
现在只要把两个图叠加在一起就行了,但是这里面有个问题。这两个图是分别用两个不同的变量来控制颜色的。
但是如果画在一起,ggplot2是不允许的,但是我记得Y叔发过的大部分帖子,我记得他曾经解决过这种情况,就去翻了一下。
答案在这个帖子里面
连续型和离散型数据一起画热图,外加分开配色和图例
这是我们常见的使用gheatmap做图的代码,为了实现不同数据类型的热图放在一起,让我们祭出
ggnewscale
包,只需要用new_scall_fill()
,就可以把后面的fill映射和前面的分离开,然后我们就可以愉快地,再加一条gheatmap再画一个热图。
这样我的问题就完美解决了。
安装和加载 R包
options("repos"=c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))if(!require("ggnewscale")) install.packages("ggnewscale",update = F,ask = F)library(ggnewscale)
分别抽离出基因名称和亚型名称,用来加在图上
## x轴文字xlabels % filter(y==1) %>% distinct(type,.keep_all = T) %>% arrange(x) %>% pull(type)## y轴文字ylabels % filter(x==1) %>% distinct(gene,.keep_all = T) %>% arrange(y) %>% pull(gene) %>% as.character()
指定三个颜色,来自小丫画图的144号作品
red "#AB221F"blue "#3878C1"nake "#FFFADD"
画图开始
p1 <- ggplot(data1,aes(x=x, y=y)) + ## 画出上三角geom_polygon(data = data1,aes(x=x, y=y, group=group,fill=exp),color="black") + ## 上三角用表达值来配色scale_fill_gradientn(colours = c(nake,red)) + ## 神技能,清空aesnew_scale_fill() + ## 画出下三角geom_polygon(data = data2,aes(x=x, y=y, group=group,fill=del),color="black") + ## 下三角用表达值来配色scale_fill_gradientn(colours = c(nake,blue))+ ## 调整x轴scale_x_continuous(limits = c(1, NA), expand = c(0,0),breaks = c(1:33)+0.5,labels=xlabels) + ## 调整y轴scale_y_continuous(limits = c(1, NA), expand = c(0,0),breaks = c(1:20)+0.5,labels=ylabels) + ## 定主题theme(axis.title.x=element_blank(),axis.title.y=element_blank(),axis.text.x = element_text(angle = 90, hjust = 1))+ ## legend置于底部theme(legend.position="bottom")+theme(plot.margin = margin(0.5,0.01,0.5,0.01, "cm"))p1
现在来画侧边的标识,也是自己设计四边形的数据就行了
data <- data.frame(x = rep(c(1,1,2,2),3),y = c(1,3,3,1,3,14,14,3,14,21,21,14),type= rep(c("Eraser","Reader","Writer"),each=4))p2 <- ggplot(data,aes(x=x, y=y)) +geom_polygon(aes(x=x, y=y, group=type,fill=type),color="black",alpha = 0.5)+scale_fill_manual(values = c(red,nake,blue))+ ## 打标签geom_text(data=data.frame(x=1.5,y=c(2,8.5,17.5)),aes(label=c("Eraser","Reader","Writer")),angle = 90,size=4)+scale_x_continuous(limits = c(1, NA), expand = c(0,0))+scale_y_continuous(limits = c(1, NA), expand = c(0,0)) +theme(axis.title=element_blank(),axis.text = element_blank(),axis.ticks = element_blank())+theme(legend.position="none")+theme(plot.margin = margin(0.5,0.1,0.5,0.01, "cm"))p2
现在我们用cowplot
把他们拼接起来
library(cowplot)plot_grid(p1,p2,align = "h", axis = "tb",nrow = 1, rel_widths = c(33, 1))
如果用Y叔的新欢就更加简单
cowplot乃旧爱,patchwork是新欢
options("repos"=c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))if(!require("patchwork")) install.packages("patchwork",update = F,ask = F)library(patchwork)p1 + p2 + plot_layout(widths = c(33, 1))
虽然解决了问题,但是我觉得还是不够优雅,我还在学习图层中。Y叔有一篇帖子是让我夜不能寐的
扪心自问,meme几何?
这一年多来,很多次都想去回答这里面的问题,但是次次无功而返。好在近期洲更给了初步的回答,
答: 扪心自问,meme几何?
洲更说他对于图层顿悟了,就跟我问Y叔,他给出的答案是一样的,顿悟。但是我还没有,我还在找寻属于我自己的答案。学习图层,对我个人而言并不是为了画图,我就那么点数据,以后的知识以及足够去呈现了,我只是想从高手的视角去看待作图这件事,就跟Y叔给我启发最大的话那样:
图就是数据,数据就是图。
distinct group by一起用_用ggplot2来画带有对角线的热图。相关推荐
- pheatmap, gplots heatmap.2和ggplot2 geom_tile实现数据聚类和热图plot
主要步骤 pheatmap 数据处理成矩阵形式,给行名列名 用pheatmap画热图(pheatmap函数内部用hclustfun 进行聚类) ggplot2 数据处理成矩阵形式,给行名列名 hclu ...
- r语言聚类分析_技术贴 | R语言pheatmap聚类分析和热图
点击蓝字↑↑↑"微生态",轻松关注不迷路 本文由阿童木根据实践经验而整理,希望对大家有帮助. 原创微文,欢迎转发转载. 导读 pheatmap默认会对输入矩阵数据的行和列同时进行聚 ...
- R语言ggplot2 | 绘制随机森林重要性+相关性热图
- 相关性分析热点图_高分文章中物种与代谢物相关性热图是怎么画的?
测序行业的蓬勃发展,带来微生物组学日新月异的变化.目前,单一组学的文章不断"贬值",前沿研究的目光从单一组学逐步拓展至多组学对贯穿分析,即结合多个组学的分析角度,从多个层面阐述生物 ...
- r语言ggplot2一夜多图_R语言ggplot2画四方形的热图展示相关系数的简单小例子
R语言里画热图通常会使用pheatmap这个包.如果想使用ggplot2这个包画热图的话需要借助geom_tile()这个函数.今天的内容就以相关系数的数据为例介绍一下ggplot2画热图的一个简单小 ...
- python 相关性检验怎么计算p值_生信工具 | 相关性热图还能玩出什么花样?
关于相关性,表示数据之间的相互依赖关系.但需要注意,数据具有相关性不一定意味着具有因果关系. 相关性在组学数据挖掘中应用非常广,如样本的重复检验.基因的共表达分析.微生物群落的共发生网络分析等. 相关 ...
- 数据可视化——R语言ggplot2包绘制相关矩阵为热图
数据可视化--R语言ggplot2包绘制相关矩阵为热图 概述:R语言软件和数据可视化--ggplot2快速绘制相关矩阵为热图.本文翻译了一篇英文博客,博客原文链接:http://www.sthda.c ...
- ggplot2简单使用_用ggplot2预测足球比分
ggplot2简单使用 胡闹 (Horsing Around) In one of my earlier posts, I mentioned that the scores in a footbal ...
- 库存生产-实用sql知识:如何在保证去重分组的情况下获取组内最新数据(可按时间排序),distinct +group by +嵌套结果 的联合妙用
这是花了一个小时实践出来的! 网上有特别多的distinct +group by 的比较区别的,几乎没有几篇文章说他们的联合妙用. 步入正题,先说我发现妙用的基于实际问题: 库存与入库单的一个关系业务 ...
最新文章
- WinForm开发,窗体显示和窗体传值相关知识总结
- shellcode中变形bindshell的实现
- 如何花钱让2000元的月收入工资价值最大化?
- 《剑指offer》c++版本 18.删除链表的结点
- FastJSON 简介及其Map/JSON/String 互转(转载)
- dbcp连接池配置详解_JDBC第四篇【数据库连接池、DbUtils框架、分页】(修订版)
- foreach之引用的使用
- (33)FPGA原语设计(BUFGCE)
- 查看现有运行的linux服务器有多少内存条
- div 中的i标签如何点击事件_前端优化:语义标签进化史
- JS—图片压缩上传(单张) 1
- 百度谭中意:我和开源20年
- 微信小程序学习(跟着b站的黑马程序员视频所学)
- 服务器IIS配置添加下载扩展名
- linux free空闲内存用尽,Linux中显示空闲内存空间的free命令的基本用法,linuxfree...
- 【第86期】CPU 空闲时在干嘛?
- 李福攀:Kata安全容器在蚂蚁集团的应用实践
- 【第三方互联】11、创建支付宝(Alipay)互联应用
- Mac安装Jadx反编译工具
- 同时使用scanf()函数和getchar()函数无法输入字符串的问题
热门文章
- php下的jsonp使用实例
- 关于VerifyRenderingInServerForm方法的思考(转)
- SQL Server 2005中设置Reporting Services发布web报表的匿名访问
- 修改百度搜索结果的标题
- studio python 格式快捷键_ubuntu下visual studio 怎么使一段python代码代码格式化
- java的string访问某个元素_架构师必懂的——RBAC基于角色的访问权限设计
- 新冠疫苗接种宣传海报PSD素材模板
- UI设计灵感|信息录入表单页,告别枯燥!
- Photoshop画笔|设计师必备
- matplotlib 横坐标只显示整数_面试题系列 (168) matplotlib条形图绘制