这里的关键是将您的数据转换为矩阵(邻接矩阵,其中行对应于'from',列对应于'to')。
df = read.table(textConnection("
Brand_from model_from Brand_to Model_to
VOLVO s80 BMW 5series
BMW 3series BMW 3series
VOLVO s60 VOLVO s60
VOLVO s60 VOLVO s80
BMW 3series AUDI s4
AUDI a4 BMW 3series
AUDI a5 AUDI a5
"), header = TRUE, stringsAsFactors = FALSE)
from = paste(df[[1]], df[[2]], sep = ",")
to = paste(df[[3]], df[[4]], sep = ",")
mat = matrix(0, nrow = length(unique(from)), ncol = length(unique(to)))
rownames(mat) = unique(from)
colnames(mat) = unique(to)
for(i in seq_along(from)) mat[from[i], to[i]] = 1
的mat
值为
> mat
BMW,5series BMW,3series VOLVO,s60 VOLVO,s80 AUDI,s4 AUDI,a5
VOLVO,s80 1 0 0 0 0 0
BMW,3series 0 1 0 0 1 0
VOLVO,s60 0 0 1 1 0 0
AUDI,a4 0 1 0 0 0 0
AUDI,a5 0 0 0 0 0 1
然后将矩阵发送到chordDiagram
指定order
和directional
。手动规范order
是为了确保将相同的品牌组合在一起。
par(mar = c(1, 1, 1, 1))
chordDiagram(mat, order = sort(union(from, to)), directional = TRUE)
circos.clear()
为了使图形更复杂,您可以创建品牌名称跟踪、品牌标识跟踪、型号名称跟踪。此外,我们可以将品牌之间的差距设置为大于每个品牌内部的差距。
1套gap.degree
circos.par(gap.degree = c(2, 2, 8, 2, 8, 2, 8))
2 在绘制和弦图之前,我们创建了两条空轨道,一条用于品牌名称,一条用于通过preAllocateTracks
参数识别线。
par(mar = c(1, 1, 1, 1))
chordDiagram(mat, order = sort(union(from, to)),
direction = TRUE, annotationTrack = "grid", preAllocateTracks = list(
list(track.height = 0.02),
list(track.height = 0.02))
)
3 将模型名称添加到注释轨道(默认创建此轨道,左右图中较粗的轨道。注意这是从外圈到内圈的第三个轨道)
circos.trackPlotRegion(track.index = 3, panel.fun = function(x, y) {
xlim = get.cell.meta.data("xlim")
ylim = get.cell.meta.data("ylim")
sector.index = get.cell.meta.data("sector.index")
model = strsplit(sector.index, ",")[[1]][2]
circos.text(mean(xlim), mean(ylim), model, col = "white", cex = 0.8, facing = "inside", niceFacing = TRUE)
}, bg.border = NA)
4 添加品牌标识线。由于品牌涉及多个部门,我们需要手动计算线(弧)的起点和终点。接下来,
rou1
和rou2
是第二个轨道中两个边界的高度。标识线绘制在第二条轨道中。
all_sectors = get.all.sector.index()
rou1 = get.cell.meta.data("yplot", sector.index = all_sectors[1], track.index = 2)[1]
rou2 = get.cell.meta.data("yplot", sector.index = all_sectors[1], track.index = 2)[2]
start.degree = get.cell.meta.data("xplot", sector.index = all_sectors[1], track.index = 2)[1]
end.degree = get.cell.meta.data("xplot", sector.index = all_sectors[3], track.index = 2)[2]
draw.sector(start.degree, end.degree, rou1, rou2, clock.wise = TRUE, col = "red", border = NA)
5 先获取文本在极坐标系中的坐标,然后通过 映射到数据坐标系reverse.circlize
。请注意,您映射回坐标的单元格和您绘制文本的单元格应该是同一个单元格。
m = reverse.circlize( (start.degree + end.degree)/2, 1, sector.index = all_sectors[1], track.index = 1)
circos.text(m[1, 1], m[1, 2], "AUDI", cex = 1.2, facing = "inside", adj = c(0.5, 0), niceFacing = TRUE,
sector.index = all_sectors[1], track.index = 1)
对于其他两个品牌,使用相同的代码。
start.degree = get.cell.meta.data("xplot", sector.index = all_sectors[4], track.index = 2)[1]
end.degree = get.cell.meta.data("xplot", sector.index = all_sectors[5], track.index = 2)[2]
draw.sector(start.degree, end.degree, rou1, rou2, clock.wise = TRUE, col = "green", border = NA)
m = reverse.circlize( (start.degree + end.degree)/2, 1, sector.index = all_sectors[1], track.index = 1)
circos.text(m[1, 1], m[1, 2], "BMW", cex = 1.2, facing = "inside", adj = c(0.5, 0), niceFacing = TRUE,
sector.index = all_sectors[1], track.index = 1)
start.degree = get.cell.meta.data("xplot", sector.index = all_sectors[6], track.index = 2)[1]
end.degree = get.cell.meta.data("xplot", sector.index = all_sectors[7], track.index = 2)[2]
draw.sector(start.degree, end.degree, rou1, rou2, clock.wise = TRUE, col = "blue", border = NA)
m = reverse.circlize( (start.degree + end.degree)/2, 1, sector.index = all_sectors[1], track.index = 1)
circos.text(m[1, 1], m[1, 2], "VOLVO", cex = 1.2, facing = "inside", adj = c(0.5, 0), niceFacing = TRUE,
sector.index = all_sectors[1], track.index = 1)
circos.clear()
如果要设置颜色,请转到包小插图,如果需要,还可以使用circos.axis
在绘图上添加轴。