2.1 坐标转换(Coordinate transformation)
为了将图形映射到圆中,需要进行多个坐标系的转换。
- 数据坐标系(data coordinate systems)
首先需要进行数据坐标体系的转换,其中x-轴和y-轴是原始数据的范围。
- 极坐标系
极坐标系使所有的坐标系得以映射在圆上。
- 画布坐标系(canvas coordinate system)
画布坐标系使得图形真正绘制到圆上。
每个单元的坐标系都是独立的,Circlize首先将数据坐标系转换为极坐标系,最后再转换为画布坐标系(Fig 2.1)。
Fig 2.1 坐标系的转换(左上:数据坐标系;左下:极坐标系;右:画布坐标系)
最终的画布坐标系实际是基于我们经常接触的基础的R图形系统,其中x轴的范围为(-1, 1),y轴范围也为(-1, 1)。需要注意的是,这个圆的单位半径为1,即一单位的圆,在绘制时总是按照从外向内的顺序进行。
2.2 绘制圆的规则
绘制圆的规则实际上很简单,只需要遵循以下顺序:
initialize layout -> # 初始化布局
create track -> # 创建轨迹
add graphics -> # 添加图形
creat track -> # 创建轨迹
add graphics -> # 添加图形
... -> #重复创建轨迹、添加图形的步骤
clear # 绘制结束
在创建轨迹后,可以随时添加图形(Fig 2.2)。
Fig 2.2 Order
- 初始化布局(Initialize the layout)
初始化的函数为circos.initialize().
circos.initialize()
由于圆形布局实际上是可视化数据中的类别,因此至少需要有一个分类变量。每个类别的x值得范围可以是一组向量,也可以是范围本身(详见2.3)。
- 创建绘图区域(Create plotting regions)和添加图形(add graphic)
新的轨迹会在之前创建的轨迹的内测,只有创建一个轨迹后,才能在其中添加图形。可以通过3种方法在一个单元(cells)中添加图形。
- 低级绘图函数
在创建轨迹后,可以通过诸如circos.points()、circos.lines()这样的低级绘图函数逐单元的添加图形单元。通常这个过程会涉及循环,需要通过分类变量对划分数据子集。 - 批量模式(batch mode)
通过circos.trackPoints()、circos.trackLine()等函数在所有的单元中同时添加简单的图形。 - 即时添加函数
通过panel.fun的参数在circos.track()中建立一个单元后立刻添加图形。panel.fun需要x和y两个参数,这两个值需要代表当前的单元。这个子集操作符是自己运行的,是最推荐使用的方法。panel.fun的参数细节详见2.7。
- 重复步骤2添加更多的轨迹,直到作图目标达成。
- 输入circos.clear()去清理数据,结束绘制。
circos.clear()
正如上面所提到的,有三种方法在轨迹中添加图形。
- 为整个轨迹创建绘图区域,然后通过特定的sector.index去添加图形,在下面的伪代码中,x1、x2是给定单元中的数据点,需要手动设置数据子集。circos.points()和circos.lines()是分别应用于circos.track(),因此,区域的划分需要通过sector.index的参数进行分割,当前(current)轨迹是这两个函数的默认参数,介于这两个函数都跟在circos.track()函数后,因此"current"参数通常可以省略。
circos.initialize(factors, xlim)
circos.track(factors, ylim)
for(sector.index in all.sector.index) {
circos.points(x1, y1, sector.index)
circos.lines(x2, y2, sector.index)
}
- 通过批量模式添加图形,在随后的代码中,circos.trackPoints()和circos.trackLine()需要一个分类变量,关于x值得向量和关于y值得向量。x和y的值可以被分类变量所分割,并被发送至坐标系用以添加图形。本质上,这种方法是通过使用circos.point()和circos.lines()进行for 循环实现的。当只添加一种特定类型的简单图形(例如点)时,比较方便,但是不适用于创建比较复杂的图形。
circos.trackPoints()和circos.trackLines() 需要track.index去指定用于绘制图形的轨迹。但同样的,由于其跟随在circos.track()之后,因此会在新绘制的轨迹中添加图形。
circos.initialize(factors, xlim)
circos.track(factors, ylim)
circos.trackPoints(factors, x, y)
circos.trackLines(factors, x, y)
- 在单元倍创建后,使用面板函数添加自定义的各种图形,这是最为提倡的方法,本书中主要使用panel.fun。通过circos.track()依次创建单元,每创建一个单元,panel.fun立即在该单元绘制图形。在这种情况下,当前扇区、当前轨迹都被限定于新绘制的单元中,可以使用低等函数而不需要指定扇区序号和轨迹序号。
下面的代码中,panel.fun如同在普通的R图形系统中一般自然的使用points()和lines()。这应该可以帮你想像单元就是一个虚构的矩形绘图区域。
circos.initialize(factors, xlim)
circos.track(factors, all_x, all_y, ylim,
panel.fun = function(x, y) {
circos.points(x, y)
circos.lines(x, y)
})
当使用circos.track()和circos.update()时,有一些内部变量保持对当前扇区和轨迹的追踪。因此,即使像 circos.points()、 circos.lines()这种需要对扇区和轨迹进行索引的函数,也可以使用当前扇区和轨迹作为默认值。当添加点、线、文字时,不需要指定索引,会在最近的创建或升级的单元中绘制。
2.3 扇区和轨迹(Sectors and tracks)
一个图形布局是由一些扇区和轨迹组成的。如同在下图中所演示的一样,红色的圆是一个轨迹,而蓝色的部分代表了一个扇区,扇区和轨迹的交界处被称为单元,可以被当做数据点的虚拟绘制区域(Fig 2.3)。在这里我们介绍如何设定单元中x和y方向中数据的范围。
<center>fig 2.3 扇形、轨迹和单元</center>