(转帖)-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.

但是如果利用上述参数在单元格内绘制点线的话,需要借助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个扇形:

扇形(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:绘制扇形方向(默认和和我们常见的时钟一致)

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

还有一个重要参数: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")

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()

利用函数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()

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

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 包帮助文档!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容