circlize 之 Circular layout
circlize 之 Circular layout
1、坐标转换
circlize 绘图包含了三步坐标转换,第一步是将 x 和 y 对应的值转换为正常的坐标体系,第二步转换为极坐标体系,最后一步绘制到 2x2 的画布上。需要注意的是,圆形图总是绘制在半径为 1 的圆内。
2、绘制圆形图规则
绘图基本流程很简单,主要包括:
布局初始化 创建轨道 添加图形 创建轨道 添加图形 ... 一直到绘图结束,清空画板
下面来具体说明流程:
1、circos.initialize() 函数用来初始化画板,输入数据至少包含 1 个分类变量。
2、创建轨道,添加图形。有三种方法给扇形区域添加图形。
A. 创建轨道后,用 circos.points()
,circos.lines()
, … 等低级函数依次给每个单元格添加图形,你需要用 for 循环手动给每个分类变量添加。
circos.initialize(sectors, xlim)
circos.track(ylim)
for(sector.index in all.sector.index) {
circos.points(x1, y1, sector.index)
circos.lines(x2, y2, sector.index)
}
B. 使用 circos.trackPoints()
,circos.trackLines()
,等函数给所有单元格同时添加图形。
circos.initialize(sectors, xlim)
circos.track(ylim)
circos.trackPoints(sectors, x, y)
circos.trackLines(sectors, x, y)
C. 使用 circos.track()
函数在里面添加panel.fun
参数,在创建单元格的同时马上添加图形。panel.fun 需要 x 和 y 两个参数,这两个参数代表当前的单元格的 x、y。
circos.initialize(sectors, xlim)
circos.track(sectors, all_x, all_y, ylim,
panel.fun = function(x, y) {
circos.points(x, y)
circos.lines(x, y)
})
3、重复 2 的步骤来添加更多的轨道和图形。
4、使用 circos.clear()
清空画板。
3、扇区和轨道
环形图由扇区和轨道组成。红色圆圈是一个轨道,蓝色代表一个扇区。扇形和轨迹的交点称为单元格,它可以被认为是数据点的假想绘图区域。我们将介绍如何在单元格的 x 和 y 方向上设置数据范围。
数据范围也可以通过 xlim 参数直接指定。xilm 的有效值是一个两列矩阵,其行数与 xlim 中的每一行对应一个扇区的行数相同。如果 xlim 的行名已经包含扇区名,则 xlim 的行顺序将自动调整。如果 xlim 是长度为 2 的向量,那么所有扇区都有相同的 x 范围。
circos.initialize(sectors, x = x)
circos.initialize(sectors, xlim = xlim)
如果未指定扇区,则将 xlim 的行名作为扇区的值:
circos.initialize(xlim = xlim)
在布局初始化之后,可能看不到绘制任何内容,或者只打开一个空的图形设备。这是因为还没有创建轨道,然而,布局已经被内部记录了。
通过改变扇区的 levels 来改变顺序,默认按字母排序:
sectors = c("d", "f", "e", "c", "g", "b", "a")
s1 = factor(sectors)
circos.initialize(s1, xlim = c(0, 1))
s2 = factor(sectors, levels = sectors)
circos.initialize(s2, xlim = c(0, 1))
在不同的轨迹中,同一扇区中的单元格在 x 轴上是相同的数据范围。然后,对于每个轨道,我们只需要为单元格指定 y 方向(或径向)上的数据范围。与 circos.initialize()类似,circos.track()也接收 y 或 ylim 参数来指定 y 值的范围。由于同一轨道上的所有单元格具有同一个 y 范围,如果指定了 ylim,那么它只是长度为 2 的向量。X 也可以在 circos.track()中指定,但它只用于 panel.fun 参数里。
circos.track(sectors, y = y)
circos.track(sectors, ylim = c(0, 1))
circos.track(sectors, x = x, y = y)
4、图形参数
一些基础参数可以通过 circos.par()
函数设置:
参数 | 说明 |
---|---|
start.degree | 第一个扇区的角度,等于 90 时,表示从正上方开始. |
gap.degree | 两个邻近扇区的距离,gap.after 和它一样. |
track.margin | 轨道之间的空白距离,mm_h()/cm_h()/inches_h()函数设置. |
cell.padding | 单元格填充,是绘图区域的空白区域,mm_h()/cm_h()/inches_h()设置. |
unit.circle.segments | 控制曲线的分段数量. |
track.height | 轨道高度,可通过 mm_h()/cm_h()/inches_h()设置. |
points.overflow.warning | 绘图时数据如果超出范围会出现警告信息,设值为 TRUE 或 FALSE 打开或关闭。 |
canvas.xlim/canvas.ylim | 画布的坐标轴范围,默认时-1 到 1. |
circle.margin | 图的边缘,代表左右下上方向,正值,c(x1, x2, y1, y2)就是 circos.par(canvas.xlim = c(-(1+x1), 1+x2), canvas.ylim = c(-(1+y1), 1+y2)) |
clock.wise | 扇区的方向,默认为 TRUE,顺时针方向 |
xaxis.clock.wise | 每个单元格的方向,默认顺时针方向 |
示例参数使用:
示例 | 数值 |
---|---|
start.degree | 0 |
gap.degree/gap.after | 1 |
track.margin | c(0.01, 0.01) |
cell.padding | c(0.02, 1.00, 0.02, 1.00) |
unit.circle.segments | 500 |
track.height | 0.2 |
points.overflow.warning | TRUE |
canvas.xlim | c(-1, 1) |
canvas.ylim | c(-1, 1) |
circle.margin | c(0, 0, 0, 0) |
clock.wise | TRUE |
xaxis.clock.wise | TRUE |
# 设置
circos.par("start.degree" = 30)
# 用 $ 符设置
circos.par$start.degree = 30
# 重置
circos.par(RESET = TRUE)
5、更新绘图区域
更新和修改指定的单元格:
circos.update(sector.index, track.index)
circos.points(x, y, sector.index, track.index)
6、panel.fun
给 a 和 b 添加点:
sectors = c("a", "a", "a", "b", "b")
x = 1:5
y = 5:1
circos.track(sectors, x = x, y = y,
panel.fun = function(x, y) {
circos.points(x, y)
})
获取当前单元格的名字和扇区和轨道信息:
get.cell.meta.data(name)
get.cell.meta.data(name, sector.index, track.index)
其它参数:
sector.index: The name for the sector. sector.numeric.index: Numeric index for the sector. track.index: Numeric index for the track. xlim: Minimal and maximal values on the x-axis. ylim: Minimal and maximal values on the y-axis. xcenter: mean of xlim. ycenter: mean of ylim. xrange: defined as xlim[2] - xlim[1]. yrange: defined as ylim[2] - ylim[1]. ...
在单元格中间区域添加单元格索引值:
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_META 替换简化代码:
circos.track(ylim = ylim, panel.fun = function(x, y) {
circos.text(CELL_META$xcenter, CELL_META$ycenter,
CELL_META$sector.index)
})
欢迎小伙伴留言评论!
今天的分享就到这里了,敬请期待下一篇!
最后欢迎大家分享转发,您的点赞是对我的鼓励和肯定!
如果觉得对您帮助很大,打赏一下吧!