【R画图】环形热图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【R画图】环形热图相关的知识,希望对你有一定的参考价值。

参考技术A 热图(heatmap)在生信领域基本就是常规操作,基本技能,入门操作。能画热图的工具也有很多,我自己常用的R包是pheatmap。

最近经常看见环状的热图,所以就搜了一下资料学习一下,测试一下。

环状热图我也经常会在论文中看到,用法和热图相同,但更适合于需要展示较多基因(数据)时来使用。

===安装=====

install.packages("circlize")

install.packages("ComplexHeatmap")

library('ComplexHeatmap')

library('circlize')

===测试===

data<-read.table("expression.txt",header=T,row.names=1)

head(data)

//转化为矩阵并对其进行归一化

madt<-as.matrix(data)

madt2<-t(scale(t(madt)))

Heatmap(madt2)     //这就是默认参数,普通的热图

range(madt2)   //查看值的分布

mycol=colorRamp2(c(-1.7, 0.3, 2.3),c("blue", "white", "red")) //定义颜色范围

circos.heatmap(madt2,col=mycol)  //默认参数

注:

circos.clear()  //绘制完成后需要使用此函数完全清除布局

circos.par(gap.after=c(50))    //

调整圆环首尾间的距离,数值越大,距离越宽

circos.heatmap(madt2,col=mycol, dend.side="inside",rownames.side="outside",rownames.col="black",rownames.cex=0.9,rownames.font=1,cluster=TRUE)

注:dend.side:控制行聚类树的方向,inside为显示在圆环内圈,outside为显示在圆环外圈

#rownames.side:控制矩阵行名的方向,与dend.side相同;但注意二者不能在同一侧,必须一内一外

#cluster=TRUE为对行聚类,cluster=FALSE则不显示聚类

下面是换了inside和outside的结果:

===聚类树的调整和美化(需要用到两个别的包)===

install.packages("dendextend")     //改颜色

install.packages("dendsort")          //聚类树回调

library(dendextend)

library(dendsort)

circos.par(gap.after=c(50))

circos.heatmap(madt2,col=mycol,dend.side="inside",rownames.side="outside",track.height=0.38,rownames.col="black",rownames.cex=0.9,rownames.font=1,cluster=TRUE,dend.track.height=0.18,dend.callback=function(dend,m,si)color_branches(dend,k=15,col=1:15))

注:track.height:轨道的高度,数值越大圆环越粗  dend.track.height:调整行聚类树的高度  dend.callback:用于聚类树的回调,当需要对聚类树进行重新排序,或者添加颜色时使用

包含的三个参数:dend:当前扇区的树状图;m:当前扇区对应的子矩阵;si:当前扇区的名称   color_branches():修改聚类树颜色

circos.clear()

//添加图例标签等

lg=Legend(title="Exp",col_fun=mycol,direction= c("vertical"))

grid.draw(lg)

//添加列名

circos.track(track.index=get.current.track.index(),panel.fun=function(x,y)



if(CELL_META$sector.numeric.index==1)



cn=colnames(madt2)

n=length(cn)

circos.text(rep(CELL_META$cell.xlim[2],n)+convert_x(0.3,"mm"), //x坐标

4.1+(1:n)*0.7, //y坐标和间距

cn,cex=0.8,adj=c(0,1),facing="inside")



,bg.border=NA)

mycol2=colorRamp2(c(-1.7, 0.5, 2.3),c("#57ab81", "white", "#ff9600"))

也可以更改上面的颜色,从而改变热图的配色:

===分组热图绘制========

#circos.heatmap()内只能是一个矩阵,但如果矩阵数据存在分组,可以用split参数来指定分类变量

split = sample(letters[1:2], 40, replace = TRUE)

split = factor(split, levels = letters[1:2])

circos.clear()

circos.par(gap.after=c(22))

circos.heatmap(madt2,col=mycol,split=split,dend.side="inside",rownames.side="outside",track.height = 0.38,

rownames.col="black",rownames.cex=0.9,

rownames.font=1,

cluster=TRUE,

dend.track.height=0.18,

dend.callback=function(dend,m,si) 



color_branches(dend,k=15,col=1:15)



)

//假设有两个热图的矩阵数据

madt2<-t(scale(t(madt)))

madt3<-t(scale(t(madt)))

split2 = sample(letters[1:2], 40, replace = TRUE)

split2 = factor(split2, levels = letters[1:2])

circos.clear()

circos.par(gap.after=c(8))

circos.heatmap(madt2,col=mycol2,split=split2,dend.side="outside",

cluster=TRUE,

dend.track.height=0.2,

dend.callback=function(dend,m,si)

color_branches(dend,k=15,col=1:15)



)

circos.heatmap(madt3, col = mycol,rownames.side="inside",rownames.cex=0.8)

MATLAB | 绘图复刻 | 分组环形热图

有粉丝问我Ecology Letters, (2021) 24: 1018–1028 Soil carbon persistence governed by plant input and mineral
protection at regional and global scales
这篇文章中的Figure 2咋画,原图长这样:

复刻效果:

完整步骤

0 数据定义

按理说应该从xlsx中读取数据,但是为了大家不需要下载压缩包直接就能运行,这里直接把数据放在m文件:

clc;clear
Data1=[ 0.3    -0.13    0.2     0.7     0.72    0.72
          0.1    -0.02    0.1     0.29    0.37    0.35
          0.14    0.01    0.12    0.35    0.4     0.39
          0.06    0.08    0.12    0.05    0.17    0.14];
Data2=[ 0.78    0.71    0.79    0.71
          0.44    0.32    0.45    0.31
          0.45    0.26    0.47    0.23
          0.54    0.34    0.54    0.32];
Data3=[-0.66   -0.18   -0.67   -0.66   -0.67
         -0.38   -0.31   -0.28   -0.18   -0.29
         -0.18   -0.14   -0.13   -0.08   -0.3
         -0.15   -0.3     0       0      -0.05];
Data4=[ 0.32    0.41    0.63    0.35    0.71    0.17   -0.67   -0.61
         -0.12    0.02    0.22    0.12    0.39    0.07   -0.18   -0.27
         -0.2    -0.21    0      -0.11    0.39    0.13    0      -0.05
         -0.29   -0.19   -0.02    0.04    0.27    0.16    0.14   -0.1];
titleName='(a)Topsoil';
className='Climate(CL)','Plant(PL)','Mineral(MI)','Composition(CO)';

varNameRow1='Zero','MI','CO','PL';
varNameRow2='Zero','CL','MI','CO';
varNameRow3='Zero','CL','CO','PL';
varNameRow4='Zero','CL','MI','PL';

varNameCol1='MAT','MTCM','TCQ','MAP','PWETM','PWETQ';
varNameCol2='NDVI','LAI','EVI','Input';
varNameCol3='Fe_o+Al_o','Fe_p+Al_p','Fe_d+Al_d','Ca_exe','Mg_exe';
varNameCol4='Polysa','Phenol','Lignin','N','Lipid','PAH','MAH','HIX';

1 图窗、坐标区域、基础数据定义

颜色数据我直接从colorbar上提取了几个颜色,获取颜色rgb值方式很多,我写过一些文章中有提供颜色提取器,甚至qq,ppt也有颜色提取功能。

同时要求大于0.35和小于-0.35的颜色块用黑框框起来:

% 参数预定义 ===============================================================
% 文本所占比例
sepRatio=15/100; 

% 定义配色和颜色范围
CMap=[9,100,203
33,118,199
61,137,200
93,156,200
123,174,201
156,193,199
182,209,199
217,230,200
251,249,200
249,226,184
251,203,167
250,176,149
249,151,130
251,126,114
252,100,95
250,76,78
249,52,61]./255;
% CMap=slanCM(141);
CLim=[-1,1];

% 角度范围
theta1=pi;
theta2=-pi;
% 半径范围
R1=4.5;
R2=8;
R3=9;
R4=10;

% 着重强调值大于0.35或小于-0.35着重强调
thresholdValue=[-.35,.35];

% 计算间隙
ringRatio=zeros(1,length(Data));
for i=1:length(Data)
    ringRatio(i)=size(Datai,2);
end
txtRatio=sepRatio./length(Data);
ringRatio1=1./sum(ringRatio).*(1-sepRatio);
ringRatio2=ringRatio./sum(ringRatio).*(1-sepRatio);

% 图窗和坐标区域定义
fig=figure('Units','normalized','Position',[0,0,1,1]);
fig.Color=[1,1,1];
ax=axes(fig);hold on
ax.XLim=[-10,10];
ax.YLim=[-10,10];
ax.DataAspectRatio=[1,1,1];
ax.XColor='none';
ax.YColor='none';

2 环形热图绘制

% 绘图部分 =================================================================
% 绘制热图及热图上文字
x=linspace(CLim(1),CLim(2),size(CMap,1))';
y1=CMap(:,1);y2=CMap(:,2);y3=CMap(:,3);
colorFunc=@(X)[interp1(x,y1,X,'pchip'),interp1(x,y2,X,'pchip'),interp1(x,y3,X,'pchip')];
tS=linspace(0,1,50);
for k=1:length(Data)
    theta3=theta1+(theta2-theta1).*(k*txtRatio+sum(ringRatio2(1:(k-1))));
    tData=Datak;
    for i=1:size(Datak,1)
        for j=1:size(Datak,2)
            tT=theta3+[j-1,j].*ringRatio1.*(theta2-theta1);
            tTd=tT(2)-tT(1);
            tT=[tT(1)+tTd/30,tT(2)-tTd/30];
            tR=R2+(R1-R2).*[i-1,i]./size(Datak,1);
            tRd=tR(2)-tR(1);
            tR=[tR(1)+tRd/30,tR(2)-tRd/30];
            tT=[tT(1)+(tT(2)-tT(1)).*tS,tT(2)+(tT(1)-tT(2)).*tS];
            tR=[tR(1).*ones(1,50),tR(2).*ones(1,50)];
            if tData(i,j)>thresholdValue(2)||tData(i,j)<thresholdValue(1)
                fill(ax,tR.*cos(tT),tR.*sin(tT),colorFunc(tData(i,j)),'EdgeColor',[0,0,0],'LineWidth',1.2,'EdgeAlpha',.8)
            else
                fill(ax,tR.*cos(tT),tR.*sin(tT),colorFunc(tData(i,j)),'EdgeColor',[1,1,1],'LineWidth',1.2)
            end
        end
    end
    for i=1:size(Datak,1)
        for j=1:size(Datak,2)
            tT=theta3+[j-1,j].*ringRatio1.*(theta2-theta1);
            tR=R2+(R1-R2).*[i-1,i]./size(Datak,1);
            tR=mean(tR);
            tT=mean(tT);
            if tT<0&&tT>-pi
                text(ax,tR.*cos(tT),tR.*sin(tT),num2str(tData(i,j)),'Rotation',tT./pi.*180+90,...
                    'Color',[0,0,0],'HorizontalAlignment','center')
            else
                text(ax,tR.*cos(tT),tR.*sin(tT),num2str(tData(i,j)),'Rotation',tT./pi.*180-90,...
                    'Color',[0,0,0],'HorizontalAlignment','center')
            end
        end
    end
end
text(ax,0,0,titleName,'HorizontalAlignment','center','FontSize',18)

3 添加变量标签

% 绘制标签
% 添加文本1
for k=1:length(Data)
    tT=theta1+(theta2-theta1).*((k-.5)*txtRatio+sum(ringRatio2(1:(k-1))));
    for i=1:size(Datak,1)
        tR=R2+(R1-R2).*[i-1,i]./size(Datak,1);
        tR=mean(tR);
        tVarNameRow=varNameRowk;
        if tT<0&&tT>-pi
            text(ax,tR.*cos(tT),tR.*sin(tT),tVarNameRowi,'FontSize',14,...
                'Color',[0,0,0],'HorizontalAlignment','center','Rotation',tT./pi.*180+90)
        else
            text(ax,tR.*cos(tT),tR.*sin(tT),tVarNameRowi,'FontSize',14,...
                'Color',[0,0,0],'HorizontalAlignment','center','Rotation',tT./pi.*180-90)
        end
    end
end
% 添加文本2
for k=1:length(Data)
    theta3=theta1+(theta2-theta1).*(k*txtRatio+sum(ringRatio2(1:(k-1))));
    tR=(R2*3+R3*2)/5;
    tVarNameCol=varNameColk;
    for j=1:size(Datak,2)
        tT=theta3+[j-1,j].*ringRatio1.*(theta2-theta1);
        tT=mean<

以上是关于【R画图】环形热图的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB | 绘图复刻 | 分组环形热图

MATLAB | 绘图复刻 | 分组环形热图

MATLAB | 绘图复刻 | 带树状图的环形热图

MATLAB | 绘图复刻 | 带树状图的环形热图

R绘图pheatmap热图绘制——高阶篇

如何用R语言绘制热图