【R画图学习11.2】弦图---circlize

什么是弦图(Chord Diagram),其实也是圈图的一种,感觉就是圈图,并且看上去还是比较简单的圈图,就外围的track加上links。

弦图是一种展示数据之间相互关系的图形。弦图中的数据点以圆的形式呈放射状排列,并用线条来展示数据之间的联系。在弦图中,我们可以通过颜色和线条的粗细来展现不同类型联系和强度。这种联系有多种形式比如相关性,比如存在与否,比如迁入迁出等。

那么让我们先来看几个弦图的例子。

下面的弦图就展现了不同的OTU在不同环境的存在情况。比如,研究发现OTU1存在于酸性矿山排水(AMD)、矿山(Mine)、河流(Riverine)、火山(Volcanic)等多个环境,其中在酸性矿山排水中的存在最多(连线最宽)。而关注不同的环境可以发现酸性矿山排水中主要存在OTU1、OTU5、OTU6、OTU7、OTU8、OTU20等微生物。

使用弦图展示不同OTU在不同环境中的存在情况

包括我最近常用的来描述不同细胞类型互作的展示。

单细胞细胞互作


单细胞细胞互作

和基因组上面的展示一样,当数据点不是很多的时候,弦图能很直观地展现出不同数据点之间的关系。但是当数据点过多的时候,可能弦图看起来就有一些混乱了,所以还是取决于你想用图去表达什么结论。

关于测试数据,我们要使用的数据来自于“migest”这个包。所以我们先安装该包然后读取数据。

我们要用的绘图工具是来自“circlize”包的chordDiagram()函数,这个函数更像是我们上一篇介绍的circos.track和circos.link的复合体。

我们要准备的数据具体分为2部分,一部分是用于作图的具体移民数据,还有一部分是调整作图参数的文件。

library(tidyverse)

library(circlize)

library(migest)

d0 <- read_csv(system.file("imr", "reg_flow.csv", package = "migest"))

d0

# d0中包含了很多年份的人口迁移情况;主要关注三列!

# 原来的地方 --> 迁移的地方 --> 迁移的流量有多大

下面就是参数文件,也是migest里面自带的。

d1 <- read_csv(system.file("vidwp", "reg_plot.csv", package = "migest"))

d1主要包含一些配置信息:例如每个条带的颜色信息,以及条带的顺序信息!其实一般主要的就是这个。

我们下面开始试着画这个图。

chordDiagram(x = test)

下面进行一些参数的调整。

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

          )

调整程我们先要的颜色和顺序。比如是从Northern America,Africa,Europe。。。顺序一次显示,颜色也设置成相应的d1文件中的颜色。

我们也可以选择展示标签、刻度、方格。

annotationTrack=c("axis","grid")  去标签

annotationTrack=c("name","grid") 去刻度

annotationTrack=c("name","axis") 去方格

annotationTrack = "grid"  去除标签和刻度

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

            annotationTrack = c("name","grid"), #选择展示标签和刻度,这个就去除刻度

          )

下面就是去掉刻度的情况

当然还有很多其它参数:

df : 至少有两列的数据帧。前两列指定连接,第三列(可选)包含映射到链接宽度的数值以及颜色(如果将col指定为颜色映射)功能地块中的扇区将为并集(df$$1¥,df$$2¥)。

grid.border : 网格的边框。如果为空,则边框颜色与网格颜色相同

transparency : 链接颜色的透明度,0表示没有透明度,1表示完全透明透明度。如果透明度已在列或中设置行.列或者列.col,此参数将已忽略。NAalso忽略此参数。

col : 链接的颜色。它可以是与df中的连接相对应的向量,也可以是根据df中的值(第三列)生成颜色的函数,也可以是表示所有链接的颜色相同的单个值。可以使用colorRamp2生成一个函数,将值映射到颜色。

directional : 链接是否有方向。1表示方向从df中的第一列到第二列,-1表示相反方向,0表示无方向,2表示双向。该值可以是与df中的行数长度相同的向量。

xmax : x轴上的最大值,该值应为命名向量。

direction.type : 表示方向的类型。可以是“diffHeight”和“arrows”中的一个或两个值。如果该值包含“diffHeight”,则使用链接的不同高度来表示起始根具有较长高度的方向,以使人们感觉到有东西在发生。如果该值包含“arrows”,则用户可以使用以下命令自定义箭头争论。争论值可以是与df中的行数具有相同长度的向量。注意:如果要为某些链接同时设置diffheight和arrows,则需要将这两个选项嵌入一个字符串中,例如“高度+箭头".

diffHeight : 如果directive设置为TRUE,则两个“根”之间的高度差。如果该值设置为正值,则起始根比结束根短;如果该值设置为负值,则起始根比结束根长。该值可以是与df中的行数长度相同的向量。

link.target.prop : 如果弦图是方向图,对于每个源扇区,是否绘制显示目标扇区比例的条形图。

target.prop.height : 钢筋的高度link.target.prop链接已打开。

reduce : 如果某个网格的宽度与整个圆的宽度之比小于此值,则会在上删除该网格绘图集如果你想保持所有的小网格,它的值应该小于零。

self.link : 如果一个扇区中存在自链接,1表示链接将退化为“山”,宽度与此连接的值相对应。2表示起始根和结束根的宽度都与连接的值相对应。

preAllocateTracks : 在绘制弦图之前预先分配空音轨。它可以是一个数字,表示需要创建多少空磁道,也可以是一个包含空磁道设置的列表。有关详细信息,请参阅渐晕图。

annotationTrack : 应该绘制哪个注释轨迹?默认情况下,将创建包含扇区名称的轨迹和包含栅格的轨迹。

annotationTrackHeight : 轨迹高度与annotationTrack中的值相对应。

link.border : 链接的边框,单个标量或与df或数据帧的nrows长度相同的向量

link.lwd : 链接边界的宽度,单个标量或与df或数据帧的nrows长度相同的向量

link.lty : 链接边框样式,单个标量或与df或数据帧的nrows长度相同的向量

link.auto : 忽略。

link.sort : 是否根据每个扇区上链接的宽度对其进行排序。如果设置为“总体”,则所有链接都将按顺序排序,无论它们来自第一列还是第二列。

link.decreasing : 为了链接.排序

link.arr.length : 传给循环链接. 此参数的格式与链接.lwd.

link.arr.width : 传给箭头。此参数的格式与链接.lwd.

link.arr.type : 传给循环链接,设置与相同链接.lwd. 默认值为三角形。

link.arr.col : 颜色或放在皮带中心的单线连接。此参数的格式与链接.lwd.

link.arr.lwd : 位于皮带中心的单线连接的线宽。此参数的格式与链接.lwd.

link.arr.lty : 位于皮带中心的单线链环的线型。此参数的格式与链接.lwd.

link.largest.ontop : 控制添加链接的顺序,是否基于绝对值?

link.rank : 此参数已删除。

link.visible : 是否绘制链接。该值是逻辑值,如果设置为FALSE,则不会绘制相应的链接,但仍会占用空间。此参数的格式与链接.lwd

link.zindex : 为了添加到圆的链接,一个大的值意味着以后添加它。

link.overlap : 如果是方向弦图,那么在同一扇区中出现或结束的链路是否重叠?

scale : 将每个扇区缩放到相同的宽度

group : 它包含组标签,扇区名称用作向量中的名称。

big.gap : 数据框第一列扇区和第二列扇区之间的间距。

small.gap : 行之间的差距很小。


所以我们来精调一下这个图的显示:

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

            annotationTrack = c("name","grid"), #选择展示标签和刻度,这个就去除标签

            transparency = 0.25,# 线条的透明度,0表示完全不透明,被压住的颜色就看不见了;1表示完全透明

            annotationTrackHeight = c(0.03, 0.1),# 外面一圈的宽度:改变第一个值

            directional = 1, # 表示线条的方向,0代表没有方向,1代表正向,-1代表反向,2代表双向

            direction.type = c("diffHeight","arrows"), # 线条是否带有箭头

            # link.arr.type = "big.arrow", #箭头的类型

            link.arr.type ="triangle",

              diffHeight  =0.04#外圈和中间连线的间隔,正负来调控起始和结束之间的高度

          )

大部分单细胞通讯的展示,基本都是采用下面的和这个样式。

但是,从图中我们可以看出,有些label偏长的时候,显示的很不好看,所以需要修改一下比如过长需要分行展示,但是chordDiagram没办法实现和细修,这样子的情况下,我们就需要去AI里面自己调整。或者我们也可以不用默认显示的label,自己通过circlize包的circos.track来添加label和axis。

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

            annotationTrack = c("grid"), #选择展示标签和刻度,这个就去除标签和刻度

            transparency = 0.25,# 线条的透明度,0表示完全不透明,被压住的颜色就看不见了;1表示完全透明

            annotationTrackHeight = c(0.03, 0.1),# 外面一圈的宽度:改变第一个值

            directional = 1, # 表示线条的方向,0代表没有方向,1代表正向,-1代表反向,2代表双向

            direction.type = c("diffHeight","arrows"), # 线条是否带有箭头

            # link.arr.type = "big.arrow", #箭头的类型

            link.arr.type ="triangle",

              diffHeight  =0.04#外圈和中间连线的间隔,正负来调控起始和结束之间的高度

          )

我们也可以不添加label,而是放到legend里面去。

pdf("test1.pdf", width=9, height=5, pointsize=8)

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

            annotationTrack = c("grid","axis"), #选择展示扇形和刻度,而去除了标签

            transparency = 0.25,# 线条的透明度,0表示完全不透明,被压住的颜色就看不见了;1表示完全透明

            annotationTrackHeight = c(0.03, 0.1),# 外面一圈的宽度:改变第一个值

            directional = 1, # 表示线条的方向,0代表没有方向,1代表正向,-1代表反向,2代表双向

            direction.type = c("diffHeight","arrows"), # 线条是否带有箭头

            # link.arr.type = "big.arrow", #箭头的类型

            link.arr.type ="triangle",

              diffHeight  =0.04#外圈和中间连线的间隔,正负来调控起始和结束之间的高度

          )

legend("right",pch=20,legend=d1$region,col=d1$col1,bty="n",cex=1,pt.cex=3,border="black")

dev.off()

当然,如果我们非要让标签显示的好看点的话,就需要好好控制了,特别长的需要换行。从d1中的数据也可以看出,我们把特别长的分成了2部分,reg1和reg2。

pdf("test2.pdf", width=14, height=12)

chordDiagram(x = test,

            order = d1$region,  # 按照d1表中的顺序排;

            grid.col = d1$col1, # 按照d1表中的颜色设定;

            annotationTrack = c("grid"), #选择展示标签和刻度,这个就去除标签和刻度

            transparency = 0.25,# 线条的透明度,0表示完全不透明,被压住的颜色就看不见了;1表示完全透明

            annotationTrackHeight = c(0.03, 0.1),# 外面一圈的宽度:改变第一个值

            directional = 1, # 表示线条的方向,0代表没有方向,1代表正向,-1代表反向,2代表双向

            direction.type = c("diffHeight","arrows"), # 线条是否带有箭头

            # link.arr.type = "big.arrow", #箭头的类型

            link.arr.type ="triangle",

              diffHeight  =0.04#外圈和中间连线的间隔,正负来调控起始和结束之间的高度

          )

# 添加labels and axis,相当于我们添加了两次label,稍微长的,又添加了一次

circos.track(track.index = 1, bg.border = NA,

            panel.fun = function(x, y) {

              xlim = get.cell.meta.data("xlim")# 获取x轴的刻度范围:

              sector.index = get.cell.meta.data("sector.index")# 获取原本所在的扇形区域

              reg1 = d1 %>% filter(region == sector.index) %>% pull(reg1) # reg1:获取目标州名的第一部分;

              reg2 = d1 %>% filter(region == sector.index) %>% pull(reg2) # reg2:获取目标州名的第二部分(有些为NA);

              circos.text(x = mean(xlim), y = ifelse(is.na(reg2), 3.5, 5.5),labels = reg1, facing = "bending", cex =1.2)  # 添加洲名:这里添加了两次,非常好的操作!第一次执行判断:ifelse(is.na(reg2), 2, 3) 如果reg2不是NA,reg1就画的矮一点;反之reg1画的高一点;

              circos.text(x = mean(xlim), y = 3.5, labels = reg2,facing = "bending", cex = 1.2) # 第二次直接画reg2,放在矮点的位置;

              circos.axis(h = "top", labels.cex = 0.8, labels.niceFacing = FALSE,labels.pos.adjust = FALSE) # 绘制刻度线:

            })

dev.off()

你可能感兴趣的:(【R画图学习11.2】弦图---circlize)