原文地址:https://mp.weixin.qq.com/s/-npB5r3W-WVkt7x4tLN_MA
目前基因組的圖形很多使用circos來(lái)做圖餐抢,你可以在網(wǎng)站
http://circos.ca/
看到兄墅,是個(gè)基因組研究繪圖強(qiáng)大工具飘蚯,大家應(yīng)該熟練掌握。當(dāng)然盆色,這個(gè)是基于perl語(yǔ)言來(lái)繪制的摧扇,很多對(duì)perl不熟悉不了解的還要從頭學(xué)習(xí),累殴泰。目前也可以在R中實(shí)現(xiàn)于宙,circlize包完全可以實(shí)現(xiàn),下面我們簡(jiǎn)單看看吧悍汛。
常用參數(shù):
?circos.points:單元格內(nèi)繪制點(diǎn)
?circos.lines:單元格內(nèi)畫(huà)線
?circos.rect:繪制矩形
?circos.polygon:多邊形
?circos.text: 添加文本
?circos.axis:坐標(biāo)軸
?circos.link:?jiǎn)卧裰g建立聯(lián)系(circlize? 包特有)
上面這些點(diǎn)線和常規(guī)作圖區(qū)別不大捞魁,只是在前面加了circos.
但是如果利用上述參數(shù)在單元格內(nèi)繪制點(diǎn)線的話,需要借助for循環(huán)离咐,太麻煩谱俭,還很慢。
我們可以利用circlize提供的低級(jí)繪圖參數(shù):
?circos.trackPoints: ‘循環(huán)’繪制點(diǎn)
?circos.trackLines: ‘循環(huán)’繪制線
?circos.trackText:‘循環(huán)’繪制文本一些常用的布局函數(shù):
?circos.trackPlotRegion:創(chuàng)建新的軌道
?circos.updatePlotRegion:? 更新繪制的已有的單元格
?circos.par:? 作圖參數(shù)(和par類似)
?circos.info:? 打印當(dāng)前繪圖信息
?circos.clear:? 重置
下面我們拿一個(gè)例子快速瀏覽一下:
layout(mat=matrix(1:6,ncol=2,byrow = T))
#構(gòu)建數(shù)據(jù)
set.seed(1)
n = 1000
a = data.frame(factor = sample(letters[1:8], n, replace = TRUE),
x = rnorm(n), y = runif(n))
#載入包
library(circlize)
#設(shè)置整體作圖參數(shù)
par(mar = c(1, 1, 1, 1), lwd = 0.1, cex = 0.7)
#調(diào)整軌道高度
circos.par("track.height" = 0.1)
#初始化
circos.initialize(factors = a$factor, x = a$x)
#創(chuàng)建新的軌道
circos.trackPlotRegion(factors = a$factor, y = a$y,
panel.fun = function(x, y) {
circos.axis()
})
#設(shè)置顏色
col = rep(c("#FF0000", "#00FF00"), 4)
#在軌道上繪制點(diǎn)
circos.trackPoints(a$factor, a$x, a$y, col = col, pch = 16, cex = 0.5)
#添加文本標(biāo)簽
circos.text(-1, 0.5, "left", sector.index = "a", track.index = 1)
circos.text(1, 0.5, "right", sector.index = "a")
#設(shè)置軌道背景色
bgcol = rep(c("#EFEFEF", "#CCCCCC"), 4)
#添加高級(jí)繪圖函數(shù)
circos.trackHist(a$factor, a$x, bg.col = bgcol, col = NA)
#在創(chuàng)建新的軌道
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)
})
#修改已經(jīng)繪制的圖形(扇形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")
#創(chuàng)建新的軌道旺上,繪制線
circos.trackPlotRegion(factors = a$factor, y = a$y)
circos.trackLines(a$factor[1:100], a$x[1:100], a$y[1:100], type = "h")
#繪制單元格之間的連接(點(diǎn)到點(diǎn),點(diǎn)到區(qū)間糖埋,區(qū)間到區(qū)間)
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()
一般來(lái)說(shuō)宣吱,繪制圓形圖需要幾個(gè)步驟:初始化圖形(initialize)——添加軌道(create track)——添加圖形(add graphics)——添加軌道——添加圖形……——重置(circos.clear)
1、初始化圖形:一般利用函數(shù)circos.initialize去初始化瞳别,所需數(shù)據(jù)必須包括因子變量和X值征候。
2、創(chuàng)建軌道:函數(shù)circos.trackPlotRegion可以完成祟敛,在新創(chuàng)建的軌道上繪制圖形疤坝,一般有三種方法:
a:circos.points, circos.lines等低級(jí)繪圖參數(shù),需要借助于for循環(huán)
b:circis.trackPoints,circos.trackLines等馆铁,我們不推薦使用跑揉,主要是不能繪制復(fù)雜的圖形!
c:在circos.trackPlotRegion中使用panel.fun函數(shù)(需要兩個(gè)參數(shù)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重置圖形
下面這幅圖展示我們繪制圓形圖的一般過(guò)程:
我們還要理解一個(gè)概念就是:扇形和軌道
一個(gè)圓形圖是有扇形和軌道組合成的,下圖中辣垒,紅色圓圈就是一個(gè)軌道(第二軌道)望侈,藍(lán)色就是扇形,扇形和軌道交集就是一個(gè)單元(cell)勋桶。
下圖有4個(gè)軌道和10個(gè)扇形:
扇形(sector)是在初始化圖形的時(shí)候決定的脱衙,所以circos.initialize必須提供因子變量侥猬,當(dāng)然你還要提供x值;而軌道(track)是在創(chuàng)建軌道的時(shí)候決定的circos.trackPlotRegion捐韩,在這里你要提供y值退唠。
circos.initialize(factors, x)
circos.initialize(factors, xlim)
circos.trackPlotRegion(factors, y)
circos.trackPlotRegion(factors, ylim)
我們要清楚一些基本的圖形參數(shù):
?start.degree:圖形起始角度(一共360度)
?gap.degree:一個(gè)軌道上,相鄰扇形之間距離
?track.margin:軌道上下邊距
?cell.padding:一個(gè)單元的四個(gè)邊距(下左上右)
?track.height:軌道高度
?points.overflow.warning:邏輯值
?canvas.xlim:畫(huà)布范圍(-1荤胁,1)铜邮,可以修改,你自己定義的xlim和ylim要在這個(gè)范圍內(nèi)
?canvas.ylim:同上
?clock.wise:繪制扇形方向(默認(rèn)和和我們常見(jiàn)的時(shí)鐘一致)
下面是默認(rèn)圖形參數(shù)的默認(rèn)值:
還有一個(gè)重要參數(shù):get.cell.meta.data提供了一個(gè)單元的詳細(xì)信息,我們可以指定扇形和軌道去查看寨蹋。
從get.cell.meta.dataare中我們可以觀察到:
?sector.index:? 扇形名字
?sector.numeric.index:扇形數(shù)目
?track.index:?? 軌道
?xlim:? x軸的范圍
?ylim: y軸的范圍
?xcenter:x軸的中心
? ycenter:y軸的中心
?xrange:同上.
?yrange:同上.
?cell.xlim:? 一個(gè)單元x的范圍(包括cell.padding)
?cell.ylim:? 一個(gè)單元上y的范圍
?xplot: 繪圖區(qū)域左右邊界起始角度
?yplot: Radius of bottom and top radius in the plotting region.
?cell.start.degree:起始角度.
?cell.end.degree:終止角度。
?cell.bottom.radius:底部單元距離圓心長(zhǎng)度
?cell.top.radius:頂部單元距離圓心長(zhǎng)度
?track.margin:?? 一個(gè)單元上下邊距
?cell.padding:一個(gè)單元四周邊距
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)
我們自己手動(dòng)繪制不同起始角度和半徑的扇形:
#定義邊距
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的扇形,逆時(shí)針
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度运褪,改變中心點(diǎn)(從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)
#繪制一個(gè)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")
#高亮一個(gè)小的區(qū)域,首先我們要計(jì)算出位置信息
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()
利用函數(shù)highlight.sector玖瘸,我們也可以高亮某個(gè)扇形和軌道:
#提供因子變量
factors = letters[1:8]
#初始化
circos.initialize(factors, xlim = c(0, 1))
#繪制4個(gè)軌道
for(i in 1:4) {
circos.trackPlotRegion(ylim = c(0, 1))
}
#軌道上添加標(biāo)簽信息
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))
#高亮整個(gè)軌道4
highlight.sector(factors, col = "#FFFF0040", track.index = 4)
circos.clear()
下面是一個(gè)簡(jiǎn)單示例:繪制高水平圖形
library(circlize)
#10個(gè)分類變量
category = paste0("category", "_", 1:10)
#構(gòu)造數(shù)據(jù)
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()
具有的完整的更加詳細(xì)的請(qǐng)看circlize 包幫助文檔!