R语言circlize包总结
卖萌控的博客
点击这里进入电脑版页面!体验更好
R语言circlize包总结
2022-6-30 萌小白


一个圆形布局包含扇形(sector)和轨道(track)两个部分.扇形和轨道交叉的地方称之为cell.circlize使用的是R的base图层写的,因此和R自带的画图系统一样,包含high-level函数和低级绘图函数.高级绘图函数可以直接绘图,而低级绘图则只能在创建track之后,才能在上面绘图.



circlize中的low level function包括以下几种,每一个其实都在R中存在对应的函数,因此,只要熟悉R基础绘图函数, 对下面这些都不会陌生,只是将在笛卡尔坐标转换为极坐标:




  1. circos.points: 添加点.


  2. circos.lines: 添加直线.


  3. circos.segments: 添加segment.


  4. circos.rect: 在cell中添加矩形,比如热图,其实就是用该函数来绘制的.


  5. circos.polygon: 添加多边形.


  6. circos.text: 添加文字.


  7. circos.axis and circos.yaxis:对x和y坐标轴进行设置.



circlize中与layout相关的函数如下:




  1. circos.initialize: 用来启动一个初始的circos layout,其实就是用来创建sector,只有创建sector之后,才能添加track,进而在cell中绘图.


  2. circos.track: 在sector中创建track.


  3. circos.update: 对某一个已经创建并绘图的cell进行更行.


  4. circos.par: 与par相当,对一些整体参数进行设置,比如绘制扇形时的起始角度和顺序等.


  5. circos.info: prints general parameters of current circular plot.


  6. circos.clear: 关闭现在的circos图形,从而不会影响下一个图形的绘制.



下面用一个简单的例子,来一步步说明如何使用circlize绘制circos图形.



构建数据并启动一个circos layout.



我们一共构建8个种类的数据,在circos的表现就是8个sector.



set.seed(999)



n = 1000



df = data.frame(factors = sample(letters[1:8],



n, replace = TRUE),



x = rnorm(n), y = runif(n))



library(circlize)



circos.par("track.height" = 0.1)



circos.initialize(factors = df$factors,



x = df$x)



track.height用来设置所有轨道的默认高度.整个circos的直径默认为为1,所以将其设置为0.1意味着每个轨道的高度是整个圆圈直径的10%.当然,在后面绘制单个track的时候,也可以通过函数中的track.height参数来对单个track进行设置.



circos.initialize函数中必须要设置的两个参数,factorsx或者xlim.它会根据factors的level(如果不是factor则使用unique(factors))来确定创建几个sector.x则会根据factor自动进行分组,然后根据每组的range自动设置每个sector的宽度(宽度代表的是x轴).



使用上述代码初始化一个circos plot之后,下面要做的就是按照一层层轨道往上添加东西了.



添加轨道之前,首先需要使用circos.track函数来创建轨道,然后才可以使用low-level的函数往里面添加各种元素.



创建第一个track并添加点和文字circos.track(factors = df$factors, y = df$y,



panel.fun = function(x, y) {



circos.text(x = get.cell.meta.data("xcenter"),



y = get.cell.meta.data("cell.ylim")[2] + uy(5, "mm"),



labels = get.cell.meta.data("sector.index"))



circos.axis(labels.cex = 0.6)



})



col <-



rep(c("skyblue", "red"), 4)



circos.trackPoints(factors = df$factors,



x = df$x, y = df$y,



col = col, pch = 16, cex = 0.5)



circos.text(x = -1, y = 0.5, labels = "text",



sector.index = "a", track.index = 1)



circos.track函数中的panel.fun函数用来在创建cell的时候,自定义执行一定的功能.比如可以和低级绘图函数结合,来自动对每一个cell中自动添加点等等信息.



get.cell.meta.data函数可以提供当前的cell的meta信息.有很多信息可以从`中提取,后面再详细讲解.



circos.trackPoints函数与circos.points函数不同的点就是,他可以接受factors参数,从而可以自动将x和y按照factor分组,自动在每个cell分别绘制点.因此,他的效果,相当于使用circos.track函数,然后结合panel.fun函数,在其中使用circos.points函数.因此,上面的函数也可以写成下面的函数,效果相同.



circos.track(factors = df$factors, x = df$x, y = df$y,



panel.fun = function(x, y) {



circos.text(x = get.cell.meta.data("xcenter"),



y = get.cell.meta.data("cell.ylim")[2] + uy(5, "mm"),



labels = get.cell.meta.data("sector.index"))



circos.axis(labels.cex = 0.6)



circos.points(x = x, y = y, col = col,



pch = 16, cex = 0.5)



})






使用circos.trackHist函数.这是一个high-level的函数.high-level函数意味着它自己可以直接创建新的track,然后直接绘图.



bgcol <-



rep(c("#EFEFEF", "#CCCCCC"), 4)



circos.trackHist(df$factors, df$x, bin.size = 0.2, bg.col = bgcol, col = NA)






可以看到,默认的话,track是一层一层从外往里进行添加.



添加第三个track.



注意在circos.track函数中,x坐标(x)和y坐标(y)是自动被factor所分类的,也就是说传递到内部函数panel.fun中的x和y都是当前cell(也就是分类)的x和y.



下面,在第三个track中,我们在每个cell中随机选取10个点,然后按照x排序,连接成线.



circos.track(factors = df$factors, x = df$x, y = df$y,



panel.fun = function(x, y) {



ind = sample(length(x), 10)



x2 = x[ind]



y2 = y[ind]



od = order(x2)



circos.lines(x = x2[od], y = y2[od])



})






如果需要对某个cell中用的内容进行重新绘制,可以使用circos.update函数进行更新.注意一定需要指明所需要更新的sector和track的index.



注意,更新某个cell之后,当前(current)的cell就是你更新的cell,所以如果你想要对整个cell进行修改,比如添加新的点等,可以不需要指明cell.



circos.update(sector.index = "d", track.index = 2,



bg.col = "#FF8080", bg.border = "black")



circos.points(x = -2:2, y = rep(0.5, 5), col = "white")



circos.text(x = get.cell.meta.data("xcenter"),



y = get.cell.meta.data("ycenter"),



labels = "updated", col = "white")






但是,如果接着添加track,仍然是在最里层的track的基础上,往里面接着添加.



添加第四个track.



我们接着添加track,这次我们添加一个热图,使用的是circos.rect函数.因为该函数并不是high-level函数,因此我们需要使用circos.track先创建track,然后在其内部的panel.fun函数中在使用circos.rect函数为每个cell创建热图.



circos.track(ylim = c(0, 1),



panel.fun = function(x, y) {



xlim = get.cell.meta.data("xlim")



ylim = get.cell.meta.data("ylim")



breaks = seq(xlim[1], xlim[2], by = 0.5)



n_breaks = length(breaks)



circos.rect(xleft = breaks[-n_breaks],



ybottom = rep(ylim[1], n_breaks - 1),



xright = breaks[-1],



ytop = rep(ylim[2], n_breaks - 1),



col = rand_color(n_breaks), border = NA)



})






可以看到,circos.rect函数内部的四个参数:xleft,ybottom,xrightytop可以是vector.



在内部添加连线(links)



我们添加连线或者缎带.也就是所谓的和弦图.连接可以是点对点,也可以点对区域,或者区域对区域.使用的是低级函数circos.link函数.



circos.link(sector.index1 = "a",



point1 = 0,



sector.index2 = "b",



point2 = 0, h = 0.4)



circos.link(sector.index1 = "c", point1 = c(-0.5, 0.5),



sector.index2 = "d", point2 = c(-0.5,0.5),



col = "skyblue",



border = "skyblue", h = 0.2)



circos.link(sector.index1 = "e", point1 = 0,



sector.index2 = "g", point2 = c(-1,1),



col = "green",



border = "black",



lwd = 2,



lty = 2)






最后,所有track都做完之后,需要重置你的graphic的参数等等,从而使你画下一个figure的时候,才不会搞混到一起.



circos.clearlayout(布局)



使用circlize进行画图的过程其实很简单:



初始化启动layout(创建了sector)->创建track->画图形->常见track->画图形-…-clear.



其中,对于画图来说,只要创建了该cell,就可以通过指定cell在任意时间进行画图.




  1. 初始化layout(circos.initialize函数).


  2. 创建track并画图.有三种方法可以创建track并画图.



sector和track


sector是一列(从外到里),而track是一行(一圈).sector在使用circos.initialize函数进行初始化的时候,就已经分配好了,一个sector代表着一类,因此,数据至少需要一组.



每个sector的宽度,与该组内的数据x的的range成正比.当然这是默认的,也可以通过手动设置xlim参数(circos.initialize)来指定每个sector的宽度.



xlim参数需要是一个两列的matrix,每一行对应着每一个sector的宽度的两个界限.因此,该matix的行数应该和sector的个数一致.



当然,你也可以设置xlim为两个元素的vector,这样,所有的sector的宽度就是一致的.



当初始化的时候,sector的顺序也已经被决定了.sector的顺序和你的数据中的分类的factor的因此水平时一致的,所以如果需要更改sector的顺序,请到原始数据中更改.



另外需要注意的时,在同一个sector中的不同track的cell,他们共享一个x轴.因此,当新建一个track的时候,我们没有必要设置xlim,只需要设置ylim就行了.



而对于一个track中的所有cell来说.他们共享一个ylim,因此像circos.track中的ylim参数,直接设置为两位的vector即可.



circos.track(factors, y = y)



circos.track(factors, ylim = c(0, 1))



circos.track(factors, x = x, y = y)



当创建新的track的时候,如果不想创建所有sector的track,可以在circos.track的factor参数只提供想要设置track的名字即可.



创建sector的时候,默认角度为0(水平).方向为顺时针,如果希望修改,可以通过设置:



circos.par("clock.wise" = TRUE,



start.degree = 90)总体参数



总体参数可以通过circos.par参数进行设置.



创建绘图区域



只有创建了绘图区域之后,才能够使用low-level函数进行绘图.一般,使用circos.track函数来进行绘制track.



panel.fun函数



该函数都是和circos.track函数配合使用.



panel.fun中使用low-level绘图函数,不需要指明sector.indextrack.index.



panel.fun内部,可以使用get.cell.meta.data函数来获得当前cell的信息.



可以使用其获得的cell信息包括:




比如,可以使用下面的代码,在每个cell的中间,加上该cell的index.



circos.track(ylim = ylim,



panel.fun = function(x, y) {



sector.index = get.cell.meta.data("sector.index")



xcenter = get.cell.meta.data("xcenter")



ycenter = get.cell.meta.data("ycenter")



circos.text(xcenter, ycenter, sector.index)



})



CELL_METAget.cell.meta.data是等价的,比如,CELL_META$sector.index就等于get.cell.meta.data("sector.index").



但是该函数只能在panel.fun内部使用,用来获得当前cell的信息,而get.cell.meta.data则可以在指明sector和track index的前提下,在panel.fun外部使用.



使用circlize包画一个弯曲的热图.例子来源于Zuguang Gu博士的circlize包的官网.感兴趣的可以直接点击阅读原文查看.



library( 'circlize') ## ========================================



## circlize version 0.4.6



## CRAN page: https://cran.r-project.org/package=circlize



## Github page: https://github.com/jokergoo/circlize



## Documentation: http://jokergoo.github.io/circlize_book/book/



##



## If you use it in published research, please cite:



## Gu, Z. circlize implements and enhances circular visualization



## in R. Bioinformatics 2014.



## ======================================== ##首先需要构建数据



set.seed( 999)



mat <-



matrix(rnorm( 100* 10), nrow = 10, ncol = 100)



##构建颜色转变函数,数值将按照线性转变为对应的颜色.



col_fun = colorRamp2(breaks = c(- 2, 0, 2),



colors = c( "skyblue", "white", "red"))



##因为我们只有一个热图,因此我们只需要一个sector(扇形)即可,所以factor只需要一个.



factors = "a"



##需要对数据进行聚类,从而得到其dendrogram对象,用于后续的绘图



dend <-



as.dendrogram(hclust(dist(t(mat))))



###对整体函数做一些设置



circos.par(cell.padding = c( 0, 0, 0, 0),



start.degree = 90)



##初始化一个circos,注意xlim



circos.initialize(factors, xlim = c( 0, 100))



##使用circos.track创建第一个track,并将热图使用circos.rect函数绘制在该轨道中



circos.track(ylim = c( 0, 10),



bg.border = NA,



track.height = 0.6,



panel.fun = function(x, y) {



mat2 = mat[, order.dendrogram(dend)]



col_mat = col_fun(mat2)



nr = nrow(mat2)



nc = ncol(mat2)



for(i in1:nr) {



circos.rect(xleft = 1:nc - 1, ybottom = rep(nr - i, nc),



xright = 1:nc, ytop = rep(nr - i + 1, nc),



border = "white",



col = col_mat[i, ])



}



for(i in1:nc){



circos.text(x = c( 1: 100) - 0.5,



y = 10,



labels = c( 1: 100),



facing = "clockwise", niceFacing = TRUE,



cex = 1,



adj = c( 0, 0.5)



)



}



})



##然后使用circos.dendrogram将circos.dendrogram画在内部



##首先获得dendrogram对象的最高值



max_height <-



max(attr(dend, "height"))



circos.track(ylim = c( 0, max_height),



bg.border = NA,



track.height = 0.3,



panel.fun = function(x, y) {



circos.dendrogram(dend = dend,



max_height = max_height)



})






circos.clear



如果想要让其不是一个闭合的热图,可以考虑创建两个数据,其中一个数据为空数据,不在cell里面画图即可.



代码如下:



library( 'circlize')



##首先需要构建数据



set.seed( 999)



mat <-



matrix(rnorm( 50* 10), nrow = 10, ncol = 50)



##构建颜色转变函数,数值将按照线性转变为对应的颜色.



col_fun <-



colorRamp2(breaks = c(- 2, 0, 2),



colors = c( "skyblue", "white", "red"))



factors <-



factor(c(rep( "a", 10), rep( "b", 50)), levels = c( "a", "b"))



##需要对数据进行聚类,从而得到其dendrogram对象,用于后续的绘图



dend <-



as.dendrogram(hclust(dist(t(mat))))



##将数据分为三类,并标为不同的颜色



library(tidyverse) ## Warning: package 'tidyverse' was
built under R version 3.6.1 ## -- Attaching packages
--------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.0 v purrr 0.3.2



## v tibble 2.1.3 v dplyr 0.8.3



## v tidyr 0.8.3 v stringr 1.4.0



## v readr 1.3.1 v forcats 0.4.0 ## Warning: package 'tibble' was
built under R version 3.6.1 ## Warning: package 'dplyr' was built under R
version 3.6.1 ## -- Conflicts
------------------------------------------------------
tidyverse_conflicts --



## x dplyr::filter masks stats::filter



## x dplyr::lag masks stats::lag library(dendextend) ## Warning: package 'dendextend' was built under R version 3.6.1 ##



## ---------------------



## Welcome to dendextend version 1.12.0



## Type citation('dendextend') for how to cite the package.



##



## Type browseVignettes(package = 'dendextend') for the package vignette.



## The github page is: https://github.com/talgalili/dendextend/



##



## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues



## Or contact: <[email protected]>



##



## To suppress this message use: suppressPackageStartupMessages(library(dendextend))



## --------------------- ##



## Attaching package: 'dendextend' ## The following object is masked from 'package:stats':



##



## cutree dend <-



dend %>%



set( "branches_k_color", k = 3)



###对整体函数做一些设置



circos.par(cell.padding = c( 0, 0, 0, 0),



start.degree = 120)



##初始化一个circos,注意xlim



circos.initialize(factors, xlim = cbind(c( 0, 0), table(factors)))



##创建一个空track



circos.track(ylim = c( 0, 10),



bg.border = NA,



track.height = 0.6)



mat2 = mat[, order.dendrogram(dend)]



col_mat = col_fun(mat2)



nr = nrow(mat2)



nc = ncol(mat2)



for(i in1:nr) {



circos.rect(



xleft = 1:nc - 1,



ybottom = rep(nr - i, nc),



xright = 1:nc,



ytop = rep(nr - i + 1, nc),



border = "white",



sector.index = "b",



track.index = 1,



col = col_mat[i,]



)



}



##添加文字



for(i in1:nc) {



circos.text(



x = c( 1: 50) - 0.5,



y = 10,



labels = paste( "Var", c( 1: 50), sep = ""),



facing = "clockwise",



niceFacing = TRUE,



cex = 0.8,



adj = c( 0, 0.8),



sector.index = "b",



track.index = 1



)



}



##添加y坐标



circos.yaxis(side = "left", at = c( 1: 10),



labels = paste( "Sample", 1: 10, sep = ""),



tick = FALSE, sector.index = "b",



labels.font = 0.8,



col = "white")



##首先获得dendrogram对象的最高值



max_height <-



max(attr(dend, "height"))



##创建新的空track



circos.track(



ylim = c( 0, max_height),



bg.border = NA,



track.height = 0.3



)



circos.dendrogram(dend = dend,



max_height = max_height)



circos.clear



##添加legend



library(ComplexHeatmap) ## Loading required package: grid ## ========================================



## ComplexHeatmap version 2.0.0



## Bioconductor page: http://bioconductor.org/packages/ComplexHeatmap/



## Github page: https://github.com/jokergoo/ComplexHeatmap



## Documentation: http://jokergoo.github.io/ComplexHeatmap-reference



##



## If you use it in published research, please cite:



## Gu, Z. Complex heatmaps reveal patterns and correlations in multidimensional



## genomic data. Bioinformatics 2016.



## ======================================== lgd <-



Legend(at = c(- 2, - 1, 0, 1, 2), col_fun = col_fun,



title_position = "topcenter",



title = "Intensity")



draw(lgd, y = unit( 100, "mm"),



just = c( "top", "center"))





Github
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容