(转帖)-circos-circlize-3

原文地址:https://mp.weixin.qq.com/s/-npB5r3W-WVkt7x4tLN_MA

目前基因组的图形很多使用circos来做图,你可以在网站

http://circos.ca/

看到,是个基因组研究绘图强大工具,大家应该熟练掌握。当然,这个是基于perl语言来绘制的,很多对perl不熟悉不了解的还要从头学习,累。目前也可以在R中实现,circlize包完全可以实现,下面我们简单看看吧。

常用参数:

•circos.points:单元格内绘制点

•circos.lines:单元格内画线

•circos.rect:绘制矩形

•circos.polygon:多边形

•circos.text: 添加文本

•circos.axis:坐标轴

•circos.link:单元格之间建立联系(circlize  包特有)

上面这些点线和常规作图区别不大,只是在前面加了circos.

(转帖)-circos-circlize-3_第1张图片

但是如果利用上述参数在单元格内绘制点线的话,需要借助for循环,太麻烦,还很慢。

我们可以利用circlize提供的低级绘图参数:

•circos.trackPoints: ‘循环’绘制点

•circos.trackLines: ‘循环’绘制线

•circos.trackText:‘循环’绘制文本一些常用的布局函数:

•circos.trackPlotRegion:创建新的轨道

•circos.updatePlotRegion:  更新绘制的已有的单元格

•circos.par:  作图参数(和par类似)

•circos.info:  打印当前绘图信息

•circos.clear:  重置

下面我们拿一个例子快速浏览一下:

layout(mat=matrix(1:6,ncol=2,byrow = T))

#构建数据

set.seed(1)

n = 1000

a = data.frame(factor = sample(letters[1:8], n, replace = TRUE),

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

#载入包

library(circlize)

#设置整体作图参数

par(mar = c(1, 1, 1, 1), lwd = 0.1, cex = 0.7)

#调整轨道高度

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

#初始化

circos.initialize(factors = a$factor, x = a$x)

#创建新的轨道

circos.trackPlotRegion(factors = a$factor, y = a$y,

panel.fun = function(x, y) {

circos.axis()

})

#设置颜色

col = rep(c("#FF0000", "#00FF00"), 4)

#在轨道上绘制点

circos.trackPoints(a$factor, a$x, a$y, col = col, pch = 16, cex = 0.5)

#添加文本标签

circos.text(-1, 0.5, "left", sector.index = "a", track.index = 1)

circos.text(1, 0.5, "right", sector.index = "a")

#设置轨道背景色

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

#添加高级绘图函数

circos.trackHist(a$factor, a$x, bg.col = bgcol, col = NA)

#在创建新的轨道

circos.trackPlotRegion(factors = a$factor, x = a$x, y = a$y,

panel.fun = function(x, y) {

grey = c("#FFFFFF", "#CCCCCC", "#999999")

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

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

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

circos.text(mean(xlim), mean(ylim), sector.index)

circos.points(x[1:10], y[1:10], col = "red", pch = 16, cex = 0.6)

circos.points(x[11:20], y[11:20], col = "blue", cex = 0.6)

})

#修改已经绘制的图形(扇形d,轨道2)

circos.updatePlotRegion(sector.index = "d", track.index = 2)

circos.points(x = -2:2, y = rep(0, 5))

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

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

circos.text(mean(xlim), mean(ylim), "updated")

#创建新的轨道,绘制线

circos.trackPlotRegion(factors = a$factor, y = a$y)

circos.trackLines(a$factor[1:100], a$x[1:100], a$y[1:100], type = "h")

#绘制单元格之间的连接(点到点,点到区间,区间到区间)

circos.link("a", 0, "b", 0, h = 0.4)

circos.link("c", c(-0.5, 0.5), "d", c(-0.5,0.5), col = "red",

border = "blue", h = 0.2)

circos.link("e", 0, "g", c(-1,1), col = "green", border = "black", lwd = 2, lty = 2)

circos.clear()

一般来说,绘制圆形图需要几个步骤:初始化图形(initialize)——添加轨道(create track)——添加图形(add graphics)——添加轨道——添加图形……——重置(circos.clear)

1、初始化图形:一般利用函数circos.initialize去初始化,所需数据必须包括因子变量和X

2、创建轨道:函数circos.trackPlotRegion可以完成,在新创建的轨道上绘制图形,一般有三种方法:

a:circos.points, circos.lines等低级绘图参数,需要借助于for循环

b:circis.trackPoints,circos.trackLines等,我们不推荐使用,主要是不能绘制复杂的图形!

c:在circos.trackPlotRegion中使用panel.fun函数(需要两个参数x,y),推荐大家使用!

我们展示上述三种方法(在已有的轨道上绘制图形):

第一种方法:

circos.initialize(factors, xlim)

circos.trackPlotRegion(factors, ylim)

for(sector.indexin all.sector.index) {

circos.points(x1, y1, sector.index)

circos.lines(x2, y2, sector.index)

}

第二种方法:

circos.initialize(factors, xlim)

circos.trackPlotRegion(factors, ylim)

circos.trackPoints(factors, x, y)

circos.trackLines(factors, x, y)第三种方法:

circos.initialize(factors, xlim)

circos.trackPlotRegion(factors, all_x, all_y, ylim,

panel.fun=function(x,y) {

circos.points(x, y)

circos.lines(x, y)

})

3、circos.clear重置图形

下面这幅图展示我们绘制圆形图的一般过程:

我们还要理解一个概念就是:扇形和轨道

一个圆形图是有扇形和轨道组合成的,下图中,红色圆圈就是一个轨道(第二轨道),蓝色就是扇形,扇形和轨道交集就是一个单元(cell)。

下图有4个轨道和10个扇形:

(转帖)-circos-circlize-3_第2张图片

扇形(sector)是在初始化图形的时候决定的,所以circos.initialize必须提供因子变量,当然你还要提供x值;而轨道(track)是在创建轨道的时候决定的circos.trackPlotRegion,在这里你要提供y值。

circos.initialize(factors, x)

circos.initialize(factors, xlim)

circos.trackPlotRegion(factors, y)

circos.trackPlotRegion(factors, ylim)

我们要清楚一些基本的图形参数:

•start.degree:图形起始角度(一共360度)

•gap.degree:一个轨道上,相邻扇形之间距离

•track.margin:轨道上下边距

•cell.padding:一个单元的四个边距(下左上右)

•track.height:轨道高度

•points.overflow.warning:逻辑值

•canvas.xlim:画布范围(-1,1),可以修改,你自己定义的xlim和ylim要在这个范围内

•canvas.ylim:同上

•clock.wise:绘制扇形方向(默认和和我们常见的时钟一致)

下面是默认图形参数的默认值:

(转帖)-circos-circlize-3_第3张图片
(转帖)-circos-circlize-3_第4张图片

还有一个重要参数:get.cell.meta.data提供了一个单元的详细信息,我们可以指定扇形和轨道去查看。

从get.cell.meta.dataare中我们可以观察到:

•sector.index:  扇形名字

•sector.numeric.index:扇形数目

•track.index:   轨道

•xlim:  x轴的范围

•ylim: y轴的范围

•xcenter:x轴的中心

• ycenter:y轴的中心

•xrange:同上.

•yrange:同上.

•cell.xlim:  一个单元x的范围(包括cell.padding)

•cell.ylim:  一个单元上y的范围

•xplot: 绘图区域左右边界起始角度

•yplot: Radius of bottom and top radius in the plotting region.

•cell.start.degree:起始角度.

•cell.end.degree:终止角度。

•cell.bottom.radius:底部单元距离圆心长度

•cell.top.radius:顶部单元距离圆心长度

•track.margin:   一个单元上下边距

•cell.padding:一个单元四周边距

factors = c("a", "b")

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

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

#获取扇形a,轨道1的信息

circlize(0.5, 0.5, sector.index = "a", track.index = 1)

reverse.circlize(90, 0.9, sector.index = "a", track.index = 1)

我们自己手动绘制不同起始角度和半径的扇形:

#定义边距

par(mar = c(1, 1, 1, 1))

#绘制基本图形

plot(c(-1, 1), c(-1, 1), type = "n", axes = FALSE, ann = FALSE)

#绘制从20度到0度的扇形

draw.sector(20, 0)

#30度到60度,半径版0.5-0.8的扇形,逆时针

draw.sector(30, 60, rou1 = 0.8, rou2 = 0.5, clock.wise = FALSE, col = "#FF000080")

#350度到1000度,去掉边界色

draw.sector(350, 1000, col = "#00FF0080", border = NA)

#从0到180度,改变中心点(从c(0,0)到c(-0.5到0.5))

draw.sector(0, 180, rou1 = 0.25, center = c(-0.5, 0.5), border = 2, lwd = 2, lty = 2)

#绘制一个0到360度的扇形

draw.sector(0, 360, rou1 = 0.7, rou2 = 0.6, col = "#0000FF80")

(转帖)-circos-circlize-3_第5张图片

par(mar = c(1, 1, 1, 1))

factors = letters[1:8]

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

for(i in 1:3) {

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

}

circos.info(plot = TRUE)

#高亮扇形a

draw.sector(get.cell.meta.data("cell.start.degree", sector.index = "a"),

get.cell.meta.data("cell.end.degree", sector.index = "a"),

rou1 = 1, col = "#FF000040")

#高亮轨道1

draw.sector(0, 360,

rou1 = get.cell.meta.data("cell.top.radius", track.index = 1),

rou2 = get.cell.meta.data("cell.bottom.radius", track.index = 1),

col = "#00FF0040")

#在轨道2和3高亮扇形e和f

draw.sector(get.cell.meta.data("cell.start.degree", sector.index = "e"),

get.cell.meta.data("cell.end.degree", sector.index = "f"),

get.cell.meta.data("cell.top.radius", track.index = 2),

get.cell.meta.data("cell.bottom.radius", track.index = 3),

col = "#0000FF40")

#高亮一个小的区域,首先我们要计算出位置信息

pos = circlize(c(0.2, 0.8), c(0.2, 0.8), sector.index = "h", track.index = 2)

draw.sector(pos[1, "theta"], pos[2, "theta"], pos[1, "rou"], pos[2, "rou"],

clock.wise = TRUE, col = "#00FFFF40")

circos.clear()

(转帖)-circos-circlize-3_第6张图片

利用函数highlight.sector,我们也可以高亮某个扇形和轨道:

#提供因子变量

factors = letters[1:8]

#初始化

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

#绘制4个轨道

for(i in 1:4) {

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

}

#轨道上添加标签信息

circos.info(plot = TRUE)

#在轨道1高亮扇形a和h,并添加注释信息

highlight.sector(c("a", "h"), track.index = 1, text = "a and h belong to a same group",

facing = "bending.inside", niceFacing = TRUE, text.vjust = -3)

#高亮扇形c

highlight.sector("c", col = "#00FF0040")

#高亮扇形d

highlight.sector("d", col = NA, border = "red", lwd = 2)

#在轨道2和3,高亮扇形e

highlight.sector("e", col = "#0000FF40", track.index = c(2, 3))

#在轨道2和3,高亮f和g

highlight.sector(c("f", "g"), col = NA, border = "green",

lwd = 2, track.index = c(2, 3))

#高亮整个轨道4

highlight.sector(factors, col = "#FFFF0040", track.index = 4)

circos.clear()

(转帖)-circos-circlize-3_第7张图片

下面是一个简单示例:绘制高水平图形

library(circlize)

#10个分类变量

category = paste0("category", "_", 1:10)

#构造数据

percent = sort(sample(40:80, 10))

#提供颜色

color = rev(rainbow(length(percent)))

par(mar = c(1, 1, 1, 1))

#初始角度90

circos.par("start.degree" = 90)

#初始化图形

circos.initialize("a", xlim = c(0, 100))

#添加轨道,绘制图形

circos.trackPlotRegion(ylim = c(0.5, length(percent)+0.5), , track.height = 0.8,

bg.border = NA, panel.fun = function(x, y) {

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

for(i in seq_along(percent)) {

circos.lines(xlim, c(i, i), col = "#CCCCCC")

circos.rect(0, i - 0.45, percent[i], i + 0.45, col = color[i],

border = "white")

}

for(i in seq_along(percent)) {

circos.text(xlim[1], i, paste0(category[i], " - ", percent[i], "%"),

facing = "downward", adj = c(1.1, 0.5))

}

breaks = seq(0, 90, by = 5)

circos.axis(h = "top", major.at = breaks, labels = paste0(breaks, "%"),

major.tick.percentage = 0.02, labels.cex = 0.6,

labels.away.percentage = 0.01)

})

circos.clear()

具有的完整的更加详细的请看circlize 包帮助文档!

你可能感兴趣的:((转帖)-circos-circlize-3)