如何使用R語(yǔ)言circlize包繪制漂亮圈圖(一)

圈圖對(duì)于展示復(fù)雜的數(shù)據(jù)信息非常有用,它既可以展示不同類別的數(shù)據(jù)信息,還可以直觀地展示聚焦于同一對(duì)象的多個(gè)軌跡上的數(shù)據(jù)變化,它還能夠展示多個(gè)元素之間的關(guān)系。
目前大家比較熟知的是使用circos(http://circos.ca/)來(lái)進(jìn)行繪圖,但由于circos是基于Perl語(yǔ)言來(lái)進(jìn)行繪圖的,如果對(duì)Perl不夠熟悉,小伙伴們?cè)趯W(xué)習(xí)和使用時(shí)依然有些費(fèi)神。如今在R中的circlize包也能實(shí)現(xiàn)圈圖繪制功能,甚至可能更為強(qiáng)大和便捷。下面我們一起來(lái)了解一下吧~
circlize包是由德國(guó)癌癥中心的華人博士Zuguang Gu開發(fā)的。
有興趣的可以去看看他的Github主頁(yè):
https://github.com/jokergoo
circlize包的學(xué)習(xí)文檔:
https://jokergoo.github.io/circlize_book/book/
主要分為三個(gè)部分:
第一部分主要介紹繪制圈圖的基本原理與通用函數(shù);
第二部分主要介紹針對(duì)基因組數(shù)據(jù)如何繪制圈圖;
第三部分主要介紹如何繪制和弦圖。
今天,先為大家介紹第一部分的學(xué)習(xí)內(nèi)容。
1. circlize包安裝
首先,安裝circlize包,請(qǐng)使用以下命令:
install.packages("circlize")
或者
devtools::install_github("jokergoo/circlize")
2. circlize包繪圖規(guī)則
2.1 坐標(biāo)系的轉(zhuǎn)換
繪制圈圖首先要進(jìn)行坐標(biāo)系轉(zhuǎn)換,circlize首先將數(shù)據(jù)坐標(biāo)從數(shù)據(jù)坐標(biāo)系轉(zhuǎn)換為極坐標(biāo)系,最后轉(zhuǎn)換為畫布坐標(biāo)系(如下圖)。實(shí)際上,最終的畫布坐標(biāo)是基本R圖形系統(tǒng)中的普通坐標(biāo),默認(rèn)情況下x范圍為(-1,1),y范圍為(-1,1)。需要注意的是,圈圖總是在半徑為1的圓內(nèi)繪制(這意味著它總是一個(gè)單位圓),并且是從外到內(nèi)。

2.2 繪圖規(guī)則
繪制圈圖一般遵循如下步驟:初始化圖形(initialize)——添加軌道(create track)——添加圖形(add graphics)——添加軌道——添加圖形……——重置(circos.clear)
1)初始化圖形:
一般使用函數(shù)circos.initialize 進(jìn)行初始化,所需數(shù)據(jù)必須包括因子變量和X值。
2)創(chuàng)建軌道:
使用函數(shù)circos.trackPlotRegion創(chuàng)建軌道(可簡(jiǎn)寫為circos.track)。
3)添加圖形:
在新創(chuàng)建的軌道上添加圖形一般有三種方法:
使用circos.points, circos.lines等低級(jí)繪圖參數(shù)
使用circis.trackPoints, circos.trackLines等進(jìn)行繪圖
在circos.trackPlotRegion中使用panel.fun函數(shù)
4)重置:
使用函數(shù)circos.clear進(jìn)行重置。應(yīng)該始終在每個(gè)圈圖的結(jié)尾處調(diào)用circos.clear()。圈圖有幾個(gè)參數(shù),只能在circos.initialize()之前設(shè)置,因此,在繪制下一個(gè)圈圖之前,需要重置這些參數(shù)。

2.3 扇區(qū)和軌道
圈圖由扇區(qū)和軌道組成。紅色圓圈是一條軌道,藍(lán)色代表一個(gè)扇區(qū)。扇區(qū)和軌道的交點(diǎn)稱為單元格,單元格是圈圖中的基本單位,可以將其視為數(shù)據(jù)的繪圖區(qū)域。

3. circlize包常用函數(shù)
3.1 常用的布局函數(shù)
circos.initialize():初始化
circos.trackPlotRegion():創(chuàng)建新的軌道
circos.updatePlotRegion():更新繪制的已有的單元格
circos.par():繪圖參數(shù)(用法同par類似)
circos.info():打印當(dāng)前繪圖信息
circos.clear():重置圖形參數(shù)和內(nèi)部變量
通過circos.par可設(shè)置的基本圖形參數(shù):
start.degree:第一個(gè)扇區(qū)放置的起始角度(默認(rèn)0)
gap.degree/gap.after:兩個(gè)相鄰扇區(qū)之間的間隙:(default: 1)
track.margin:繪圖區(qū)域之外的空白區(qū)域:c(0.01, 0.01)
cell.padding:?jiǎn)卧奶畛洌篶(0.02, 1.00, 0.02, 1.00)
unit.circle.segments:控制表示曲線的線段數(shù)量:(default: 500)
track.height:軌道的默認(rèn)高度:(default: 0.2)
points.overflow.warning:TRUE
canvas.xlim:畫布中的范圍沿x方向坐標(biāo):c(-1, 1)
canvas.ylim:畫布中的范圍沿y方向坐標(biāo):c(-1, 1)
clock.wise:繪圖扇區(qū)的順序,默認(rèn)值TRUE指順時(shí)針:TRUE

3.2 常用繪圖函數(shù)
circos.points():在單元格內(nèi)繪制點(diǎn)
circos.lines():在單元格內(nèi)繪制線
circos.segments():在單元格內(nèi)繪制片段
circos.rect():在單元格內(nèi)繪制矩形
circos.polygon():在單元格內(nèi)繪制多邊形
circos.text():在單元格內(nèi)添加文本
circos.axis()/circos.yaxis():在單元格內(nèi)繪制坐標(biāo)軸
circos.arrow():在單元格內(nèi)繪制圓形箭頭
circos.link():繪制單元格之間的聯(lián)系(circlize 包特有)
3.3 高級(jí)繪圖函數(shù)
circos.trackPoints():“循環(huán)”繪制點(diǎn)
circos.trackLines():“循環(huán)”繪制線
circos.trackText():“循環(huán)”繪制文本
4. 高亮扇區(qū)和軌道
·draw.sector():繪制扇形、圓環(huán)。如果要突出顯示圈圖的某些部分,此函數(shù)很有用。
draw.sector()的參數(shù)主要包括圓心的位置(默認(rèn)為c(0,0))、扇區(qū)的開始角度和結(jié)束角度以 及上邊界或下邊界的兩條邊(或一條邊)的半徑。其用法如下:
draw.sector(start.degree, end.degree, rou1) draw.sector(start.degree, end.degree, rou1, rou2, center) draw.sector(start.degree, end.degree, rou1, rou2, center, col, border, lwd, lty)
start.degree和end.degree的方向?qū)τ诶L制扇區(qū)很重要。默認(rèn)情況下,它是順時(shí)針的。
draw.sector(start.degree, end.degree, clock.wise = FALSE)
示例如下:
定義邊距
par(mar = c(1, 1, 1, 1))
繪制基本圖形
plot(c(-1, 1), c(-1, 1), type = "n", axes = FALSE, ann = FALSE, asp = 1)
繪制從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")

突出顯示圈圖中的單元格,我們可以使用get.cell.meta.data()獲得單元格位置的信息。
示例如下:
創(chuàng)建一個(gè)具有八個(gè)扇區(qū)和三個(gè)軌跡的圈圖
factors = letters[1:8]circos.initialize(factors, xlim = c(0, 1))for(i in 1:3) {circos.track(ylim = c(0, 1))}
突出顯示扇區(qū)a
draw.sector(get.cell.meta.data("cell.start.degree", sector.index = "a"), get.cell.meta.data("cell.end.degree", sector.index = "a"), rou1 = get.cell.meta.data("cell.top.radius", track.index = 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")
突出顯示扇區(qū)e和f中的軌道2和3
draw.sector(get.cell.meta.data("cell.start.degree", sector.index = "e"), get.cell.meta.data("cell.end.degree", sector.index = "f"), rou1 = get.cell.meta.data("cell.top.radius", track.index = 2), rou2 = get.cell.meta.data("cell.bottom.radius", track.index = 3), col = "#0000FF40")
突出顯示單元格h:2中的一個(gè)小區(qū)域
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():突出顯示整個(gè)單元格
highlight.sector()的優(yōu)點(diǎn)之一是它支持在突出顯示的區(qū)域中添加文本。默認(rèn)情況下,文本繪制在突出顯示區(qū)域的中心。基本方向的位置可以通過text.vjust參數(shù)設(shè)置,可以通過數(shù)字值或字符串形式使用“ 2 inch”或“ -1.2cm”
factors = letters[1:8]circos.initialize(factors, xlim = c(0, 1))for(i in 1:4) { circos.track(ylim = c(0, 1))}circos.info(plot = TRUE)
highlight.sector(c("a", "h"), track.index = 1, text = "a and h belong to a same group", facing = "bending.inside", niceFacing = TRUE, text.vjust = "6mm", cex = 0.8)highlight.sector("c", col = "#00FF0040")highlight.sector("d", col = NA, border = "red", lwd = 2)highlight.sector("e", col = "#0000FF40", track.index = c(2, 3))highlight.sector(c("f", "g"), col = NA, border = "green", lwd = 2, track.index = c(2, 3), padding = c(0.1, 0.1, 0.1, 0.1))highlight.sector(factors,?col?=?"#FFFF0040",?track.index?=?4)

5. 利用circlize包繪圖示例
下面我們拿一個(gè)例子進(jìn)行繪圖示例:
首先,構(gòu)建數(shù)據(jù)并加載circlize包
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ù),調(diào)整軌道高度并初始化
circos.par("track.height"= 0.1)circos.initialize(factors = df$factors, x = df$x)
創(chuàng)建第一個(gè)軌道
circos.track(factors = df$factors, y = df$y, panel.fun = function(x, y) { circos.text(CELL_META$xcenter, CELL_META$cell.ylim[2] + uy(5,"mm"), CELL_META$sector.index) circos.axis(labels.cex = 0.6) })
設(shè)置顏色并在軌道上添加點(diǎn)和文本標(biāo)簽
col = rep(c("#FF0000","#00FF00"), 4) circos.trackPoints(df$factors, df$x, df$y, col = col, pch = 16, cex = 0.5) circos.text(-1, 0.5,"text", sector.index = "a", track.index = 1)

設(shè)置軌道背景色并使用高級(jí)繪圖函數(shù)創(chuàng)建第二個(gè)軌道添加條形圖
bgcol = rep(c("#EFEFEF", "#CCCCCC"), 4)circos.trackHist(df$factors, df$x, bin.size = 0.2, bg.col = bgcol, col = NA)

創(chuàng)建第三個(gè)軌道并添加線
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(x2[od], y2[od]) })
圖5.3?| 創(chuàng)建第三圈軌道并添加折線圖
修改已經(jīng)繪制的圖形(扇形d,軌道2)
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(CELL_META$xcenter, CELL_META$ycenter, "updated", col = "white")

創(chuàng)建第四個(gè)軌道,并添加矩形
circos.track(ylim = c(0, 1), panel.fun = function(x, y) { xlim = CELL_META$xlim ylim = CELL_META$ylim breaks = seq(xlim[1], xlim[2], by = 0.1) n_breaks = length(breaks) circos.rect(breaks[-n_breaks], rep(ylim[1], n_breaks - 1), breaks[-1], rep(ylim[2], n_breaks - 1), col = rand_color(n_breaks), border = NA) })

繪制單元格之間的鏈接(由點(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()

這一期circlize包的基本用法先介紹到這里,如大家有使用問題,歡迎留言提問,也可以參考閱讀circlize官方教程!或點(diǎn)擊報(bào)名R語(yǔ)言培訓(xùn)班,讓老師手把手教你更多內(nèi)容!
參考文獻(xiàn):
1. circlize官方教程:
https://jokergoo.github.io/circlize_book/book/
文章系歐易生物微信公眾號(hào)首發(fā)