我想使用我们的数据发布here类似的图表,但是,我收到此错误消息“检测到某些间隙太大”。您是否认为因为某些值与其他值相比非常小(例如,1对1812)?我通过在1或2之后添加几个零来对矩阵2中的数据进行一些更改,并且它可以正常工作。有没有办法解决这一系列的数据?我想用我的真实数据(矩阵1)绘制这个漂亮的图形。非常感谢任何帮助。
library(circlize)
#matrix 1
#level0 <- c(1, 8, 39, 14, 2)
#level1 <- c(1, 19, 153, 93, 1)
#level2 <- c(2, 19, 274, 46, 13)
#level3 <- c(0, 8, 152, 1812, 465)
#level4 <- c(0, 2, 1, 164, 226)
#matrix 2
#level0 <- c(100,8,39,14,200)
#level1 <- c(100,190, 153,93,100)
#level2 <- c(200,19,274,646,130)
#level3 <- c(200,800,152,1812,465)
#level4 <- c(200,200,100,164,226)
#build matrix 2
a <- list(c(100,8,39,14,200),c(100,19, 153,93,100), c(200,19,274,646,13), c(200,8,152,1812,465),c(200,200,100,164,226))
mat <- do.call(rbind, a)
#mat = matrix(sample(1:100, 25, replace = TRUE), 5, 5)
rownames(mat) = c("level 0", "level 1", "level 2", "level 3", "level 4")
colnames(mat) = c("Level0", "Level1", "Level2", "Level3", "Level4")
rn = rownames(mat)
cn = colnames(mat)
factors = c(rn, rev(cn))
factors = factor(factors, levels = factors)
col_sum = apply(mat, 2, sum)
row_sum = apply(mat, 1, sum)
xlim = cbind(rep(0, 10), c(row_sum, col_sum))
par(mar = c(1, 1, 1, 1))
circos.par(cell.padding = c(0, 0, 0, 0), clock.wise = FALSE, track.margin=c(0,0.1),
gap.degree = 4, start.degree =90)
circos.initialize(factors = factors, xlim = xlim
, sector.width = c(row_sum/sum(row_sum), col_sum/sum(col_sum)))
circos.trackPlotRegion(factors = factors, ylim = c(0, 1), bg.border = NA,
# bg.col = c("red", "orange", "yellow", "green", "blue", rep("grey", 5)), track.height = 0.05,
bg.col = c(c("red", "orange", "yellow", "green", "blue"),
c("blue", "green", "yellow", "orange", "red")), track.height = 0.05,
panel.fun = function(x, y) {
sector.name = get.cell.meta.data("sector.index")
xlim = get.cell.meta.data("xlim")
circos.text(mean(xlim), 3, sector.name, adj = c(0.5, 0))
circos.axis(labels.cex=0.8, direction="outside", labels.away.percentage=0.5)
if(sector.name %in% rn) {
for(i in seq_len(ncol(mat))) {
circos.lines(rep(sum(mat[sector.name, seq_len(i)]), 2), c(0, 1),
col = "white")
}
} else if(sector.name %in% cn) {
for(i in seq_len(nrow(mat))) {
circos.lines(rep(sum(mat[ seq_len(i), sector.name]), 2), c(0, 1),
col = "white")
}
}
})
col = c("#FF000020", "#FFA50020", "#FFFF0020", "#00FF0020", "#0000FF20")
for(i in seq_len(nrow(mat))) {
for(j in seq_len(ncol(mat))) {
circos.link(rn[i], c(sum(mat[i, seq_len(j-1)]), sum(mat[i, seq_len(j)])),
cn[j], c(sum(mat[seq_len(i-1), j]), sum(mat[seq_len(i), j])),
col = col[i], border = "white")
}
}
答案 0 :(得分:8)
所以我认为你的df1
对象与我原来的代码有点不同。如果你设置矩阵m
和df1
......
m <- matrix(c(1, 8, 39, 14, 2,
1, 19, 153, 93, 1,
2, 19, 274, 46, 13,
0, 8, 152, 1812, 465,
0, 2, 1, 164, 226), nrow=5, byrow=TRUE)
df1 <- data.frame(order=1:5, region=paste0("level",1:5),
rcol = c("red", "orange", "yellow", "green", "blue"),
lcol = c("#FF000020", "#FFA50020", "#FFFF0020", "#00FF0020", "#0000FF20"),
stringsAsFactors=FALSE)
df1$region <- factor(df1$region, levels=df1$region)
df1$xmin <- 0
df1$xmax <- rowSums(m)+colSums(m)
n <-nrow(df1)
dimnames(m) <- list(orig=df1$region,dest=df1$region)
你得到以下物品......
> df1
order region rcol lcol xmin xmax
1 1 level1 red #FF000020 0 68
2 2 level2 orange #FFA50020 0 323
3 3 level3 yellow #FFFF0020 0 973
4 4 level4 green #00FF0020 0 4566
5 5 level5 blue #0000FF20 0 1100
> addmargins(m)
dest
orig level1 level2 level3 level4 level5 Sum
level1 1 8 39 14 2 64
level2 1 19 153 93 1 267
level3 2 19 274 46 13 354
level4 0 8 152 1812 465 2437
level5 0 2 1 164 226 393
Sum 4 56 619 2129 707 3515
我在working paper中更详细地解释了df1
的目的。简而言之,df1
对象包含有关要绘制的扇区长度(xmin
和xmax
)以及外部rcol
和带状链接上的圆形矩形的颜色的信息颜色lcol
。您当然可以使用相同的lcol
和rcol
,......在您获得自己喜欢的调色板/样式(可能对lcol
的透明度稍低)之前进行调整。< / p>
然后你可以继续使用与migest package中的演示文件中的代码非常相似的代码来获取一个图(我只更改了circos.axis
轴参数和{的子集{1}})...
df2
这给出了这样的情节...
如果你想为情节添加一些方向性,那么取消注释library(circlize)
library(plyr)
par(mar=rep(0,4))
circos.clear()
#basic circos graphic parameters
circos.par(cell.padding=c(0,0,0,0), track.margin=c(0,0.15), start.degree = 90, gap.degree =4)
#sector details
circos.initialize(factors = df1$region, xlim = cbind(df1$xmin, df1$xmax))
#plot sectors
circos.trackPlotRegion(ylim = c(0, 1), factors = df1$region, track.height=0.1,
#panel.fun for each sector
panel.fun = function(x, y) {
#select details of current sector
name = get.cell.meta.data("sector.index")
i = get.cell.meta.data("sector.numeric.index")
xlim = get.cell.meta.data("xlim")
ylim = get.cell.meta.data("ylim")
#plot labels
circos.text(x=mean(xlim), y=2.2, labels=name, facing = "arc", cex=0.8)
#plot main sector
circos.rect(xleft=xlim[1], ybottom=ylim[1], xright=xlim[2], ytop=ylim[2], col = df1$rcol[i], border=df1$rcol[i])
#blank in part of main sector
#circos.rect(xleft=xlim[1], ybottom=ylim[1], xright=xlim[2]-rowSums(m)[i], ytop=ylim[1]+0.3, col = "white", border = "white")
#white line all the way around
#circos.rect(xleft=xlim[1], ybottom=0.3, xright=xlim[2], ytop=0.32, col = "white", border = "white")
#plot axis
circos.axis(labels.cex=0.6, major.at=seq(from=0,to=floor(df1$xmax)[i],by=500),
labels.away.percentage = 0.15)
})
##
##plot links
##
#add sum values to df1, marking the x-position of the first links out (sum1) and in (sum2). Updated for further links in loop below.
df1$sum1 <- colSums(m)
df1$sum2 <- numeric(n)
#create a data.frame of matrix sorted by element size, to allow largest plotted first
df2 <- cbind(as.data.frame(m),orig=rownames(m), stringsAsFactors=FALSE)
df2 <- reshape(df2, idvar="orig", varying=list(1:n), direction="long", timevar="dest", time=rownames(m), v.names = "m")
df2 <- arrange(df2,desc(m))
#loose non zero links
df2 <- subset(df2, m>0)
#plot links
for(k in 1:nrow(df2)){
#i,j reference of flow matrix
i<-match(df2$orig[k],df1$region)
j<-match(df2$dest[k],df1$region)
#plot link
circos.link(sector.index1=df1$region[i], point1=c(df1$sum1[i], df1$sum1[i] + abs(m[i, j])),
sector.index2=df1$region[j], point2=c(df1$sum2[j], df1$sum2[j] + abs(m[i, j])),
col = df1$lcol[i])
#update sum1 and sum2 for use when plotting the next link
df1$sum1[i] = df1$sum1[i] + abs(m[i, j])
df1$sum2[j] = df1$sum2[j] + abs(m[i, j])
}
中添加白色矩形和边界线的两条线。
答案 1 :(得分:1)
大!这是我做的以获得以下图表: - 改变了gap.degree = 0.1 - 将数字转换为百分比(mat <-mat / 4700 * 100) - 删除因子
中的rev()