和弦图 - Chord Diagram

ref:
https://jokergoo.github.io/circlize_book/book/the-chorddiagram-function.html

和弦图

corclize::chordDiagram(mat)

圆形布局的一个独特特征是通过链接对对象之间的关系进行循环可视化。这种类型的图称为和弦图。在circlize中,可以很容易地以简单或高度定制的方式绘制和弦图。

1. 数据数据

chordDiagram() 接收两种格式的输入数据:

  • 邻接矩阵 mat
  • 邻接表 df

1.1 邻接矩阵 mat

mat = matrix(1:9, 3)
rownames(mat) = letters[1:3]
colnames(mat) = LETTERS[1:3]
mat
##   A B C
## a 1 4 7
## b 2 5 8
## c 3 6 9

1.2 邻接表 df

df = data.frame(from = letters[1:3], to = LETTERS[1:3], value = 1:3)
df
##   from to value
## 1    a  A     1
## 2    b  B     2
## 3    c  C     3

1.3 邻接矩阵 mat -> 邻接表 df

df = data.frame(from = rep(rownames(mat), times = ncol(mat)),
    to = rep(colnames(mat), each = nrow(mat)),
    value = as.vector(mat),
    stringsAsFactors = FALSE)

2. 制作和弦图的基本用法

2.1 生成随机Demo数据

生成邻接矩阵 mat

set.seed(999)
mat = matrix(sample(18, 18), 3, 6) 
rownames(mat) = paste0("S", 1:3)
colnames(mat) = paste0("E", 1:6)
mat
##    E1 E2 E3 E4 E5 E6
## S1  4 14 13 17  5  2
## S2  7  1  6  8 12 15
## S3  9 10  3 16 11 18

邻接矩阵 mat -> 邻接表 df

df = data.frame(from = rep(rownames(mat), times = ncol(mat)),
    to = rep(colnames(mat), each = nrow(mat)),
    value = as.vector(mat),
    stringsAsFactors = FALSE)
df
##    from to value
## 1    S1 E1     4
## 2    S2 E1     7
## 3    S3 E1     9
## 4    S1 E2    14
## 5    S2 E2     1
## 6    S3 E2    10
## 7    S1 E3    13
## 8    S2 E3     6
## 9    S3 E3     3
## 10   S1 E4    17
## 11   S2 E4     8
## 12   S3 E4    16
## 13   S1 E5     5
## 14   S2 E5    12
## 15   S3 E5    11
## 16   S1 E6     2
## 17   S2 E6    15
## 18   S3 E6    18

2.2 基于 邻接矩阵 mat 或者 邻接表 df,绘制 和弦图

  • 基于邻接矩阵绘图
library(circlize)
# 绘制和弦图
chordDiagram(mat)
# 每次绘制完需要清空绘图
circos.clear()
  • 基于邻接表绘图
library(circlize)
# 绘制和弦图
chordDiagram(df)
# 每次绘制完需要清空绘图
circos.clear()

两种方法都会得到相同的图片


Fig 2.2 Basic usages of chordDiagram()

3. 图片调整参数

和弦图主要由三个部分组成:

  1. 标签 (labels)
  2. 扇区 (sectors / grids)
  3. 扇区间的连线 (links)

3.1 调整 扇区的位置 chordDiagram(..., order = ...)

扇区的默认顺序是:
输入是邻接矩阵: union(rownames(mat), colnames(mat))
输入是邻接表:union(df[[1]], df[[2]])

par(mfrow = c(1, 2))
chordDiagram(mat, order = c("S2", "S1", "S3", "E4", "E1", "E5", "E2", "E6", "E3"))
circos.clear()

chordDiagram(mat, order = c("S2", "S1", "E4", "E1", "S3", "E5", "E2", "E6", "E3"))
circos.clear()
Fig 3.1 Adjust sector orders in Chord diagram

3.2 通过 circos.par() 调整图形

由于和弦图是通过基本的 circlize 函数实现的,就像普通的圆形图一样,因此可以通过circos.par()自定义布局。

3.2.1 扇区之间的间隙 circos.par(gap.after = ...)

  • gap.after 接收 向量
#自定义布局
circos.par(gap.after = c(
    rep(5, nrow(mat)-1),   # gap at [S1 S2 S3]
    15,                    # gap at [S3 E1]
    rep(5, ncol(mat)-1),    # gap at [E1 E2 E3 E4 E5 E6]
    15                     # gap at [E6 S1]
))
# 绘图
chordDiagram(mat)
# 重置图形设置
circos.clear()
Fig 3.2.1 Set gaps in Chord diagram.
  • gap.after 接收 命名向量
#自定义布局
circos.par(
    gap.after = c("S1" = 5, "S2" = 5, "S3" = 15, "E1" = 5, 
"E2" = 5, "E3" = 5, "E4" = 5, "E5" = 5, "E6" = 15)
)
# 绘图
chordDiagram(mat)
# 重置图形设置
circos.clear()
  • 全局调整 gap chordDiagram(..., big.gap = ..., small.gap = ...)

    big.gap的值对应于行扇区和列扇区(或者输入是数据帧中的第一列扇区和第二列扇区)之间的间隙。
    small.gap参数控制与矩阵行或列对应的扇区之间的间隙。默认值为1度,一般情况下无需设置。

3.2.2 和弦图角度 circos.par(start.degree = ...)

  • 默认是 0 度
# 设置初始角度是 85 度
circos.par(start.degree = 85)
# 逆时针放置 扇区 
chordDiagram(mat, order = c(rev(colnames(mat)), rev(rownames(mat))))
circos.clear()

3.2.3 逆时针放置 扇区

  • 注:不建议用 clock.wise = FALSE
# 设置初始角度是 85 度
circos.par(start.degree = 85)
# 逆时针放置 扇区 
chordDiagram(mat, order = c(rev(colnames(mat)), rev(rownames(mat))))
circos.clear()
Fig 3.2.3 逆时针放置 扇区

3.3 设置颜色

一般来说,扇区分为两组。一个包含在矩阵的行或数据帧的第一列中定义的扇区,另一个包含在矩阵的列或数据帧的第二列中定义的扇区。因此,链接连接两个组中的对象。默认情况下,链接颜色与第一组中相应扇区的颜色相同。

3.3.1 设置扇区(网格)颜色 chordDiagram(..., grid.col = ...)

par(mfrow = c(1, 2))
# 定义扇区颜色的映射 (命名向量)
grid.col = c(S1 = "red", S2 = "green", S3 = "blue",
    E1 = "grey", E2 = "grey", E3 = "grey", E4 = "grey", E5 = "grey", E6 = "grey")
# 通过 grid.col 参数 指定自定义的扇区颜色, 默认连线颜色与第一组扇区颜色相同
chordDiagram(mat, grid.col = grid.col)
circos.clear()
# 转置 邻接矩阵, 设置连线颜色设置与第二组扇区颜色相同
chordDiagram(t(mat), grid.col = grid.col)
circos.clear()
Fig 3.3.1 Set grid colors in Chord diagram

3.3.2 设置链接(link)颜色 chordDiagram(..., col = ...)

  • 对于邻接矩阵mat,可以通过提供颜色矩阵来自定义 link 的颜色。 col = col_mat
# 定义扇区颜色的映射
grid.col = c(S1 = "red", S2 = "green", S3 = "blue",
    E1 = "grey", E2 = "grey", E3 = "grey", E4 = "grey", E5 = "grey", E6 = "grey")
# 用rand_color()生成随机颜色矩阵,用于连线颜色映射
col_mat = rand_color(length(mat), transparency = 0.5)
# to make sure it is a matrix
dim(col_mat) = dim(mat)  
# 分别指定扇区颜色 grid.col 和连线颜色 col_mat
chordDiagram(mat, grid.col = grid.col, col = col_mat)
circos.clear()
Fig 3.3.2 指定扇区颜色 grid.col 和连线颜色 col_mat
  • 对于邻接表df,link 的颜色可以自定义为 向量 col = col
# 定义扇区颜色的映射
grid.col = c(S1 = "red", S2 = "green", S3 = "blue",
    E1 = "grey", E2 = "grey", E3 = "grey", E4 = "grey", E5 = "grey", E6 = "grey")
# 用rand_color()生成随机颜色矩阵,用于连线颜色映射
col = rand_color(nrow(df))
# 分别指定扇区颜色 grid.col 和连线颜色 col_mat
chordDiagram(mat, grid.col = grid.col, col = col)
circos.clear()

图片效果和上面一样

  • link 颜色为连续的值,比如相关性值等 col = col_fun

当关系的强度(例如相关性)表示为连续值时, col也可以指定为自定义的颜色映射函数。 chordDiagram()接受由colorRamp2()生成的颜色映射

# 定义扇区颜色的映射
grid.col = c(S1 = "red", S2 = "green", S3 = "blue",
    E1 = "grey", E2 = "grey", E3 = "grey", E4 = "grey", E5 = "grey", E6 = "grey")
# 由colorRamp2()生成的颜色映射,用于连线颜色映射
col_fun = colorRamp2(range(mat), c("#FFEEEE", "#FF0000"), transparency = 0.5)
# 分别指定扇区颜色 grid.col 和连线颜色 col_mat
chordDiagram(mat, grid.col = grid.col, col = col_fun)
circos.clear()
Fig 3.3.2 Set a color mapping function for links in Chord diagram.

颜色映射函数也适用于邻接表

chordDiagram(df, grid.col = grid.col, col = col_fun)
  • 当输入是矩阵时,有时不需要生成整个颜色矩阵。您可以只提供与行或列相对应的颜色,以便来自同一行/列的链接将具有相同的颜色
    这里注意颜色值可以设置为数字、颜色名称或十六进制代码,与基本 R 图形中相同。
# 将link颜色设置为与和弦图中的行扇区相同
chordDiagram(mat, grid.col = grid.col, row.col = 1:3)
# 将link颜色设置为与和弦图中的列扇区相同
chordDiagram(mat, grid.col = grid.col, column.col = 1:6)
Fig 3.3.2 将链接颜色设置为与和弦图中的行扇区或列扇区相同。

3.4 调整 link 的顺序 chordDiagram(..., link.zindex = ...)

将链接添加到图中的默认顺序基于它们在矩阵或数据框中的顺序。通常,应将链接颜色设置为透明度,以便它们不会相互重叠。在大多数情况下,这看起来不错,但有时,它可以改善可视化效果,将宽链接放在更靠前的位置,将小链接放在更靠后的位置。

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

推荐阅读更多精彩内容