Home | Blog | Software | Publications | GitHub


Adjust orders of links added to the Chord diagram

Assuming following matrix for the Chord diagram:

set.seed(123)
mat = matrix(sample(16, 16), 4, byrow = TRUE)
rownames(mat) = paste0("R", 1:4)
colnames(mat) = paste0("C", 1:4)
mat
##    C1 C2 C3 C4
## R1  5 12  6 15
## R2 13  1 14  9
## R3 16  4 10  3
## R4  8  2 11  7

The order to add links is:

R1 -> C1
R2 -> C1
R3 -> C1
R4 -> C1
R1 -> C2
...
R4 -> C4

Internally if the input is a matrix, the matrix will be converted to a data frame:

##    Var1 Var2 value
## 1    R1   C1     5
## 2    R2   C1    13
## 3    R3   C1    16
## 4    R4   C1     8
## 5    R1   C2    12
## 6    R2   C2     1
## 7    R3   C2     4
## 8    R4   C2     2
## 9    R1   C3     6
## 10   R2   C3    14
## 11   R3   C3    10
## 12   R4   C3    11
## 13   R1   C4    15
## 14   R2   C4     9
## 15   R3   C4     3
## 16   R4   C4     7

and the links are added from the first row to the last.

There are several scenarios that we need to adjust the default order:

  1. we want to put the widest link on the most top,
  2. we want to put the non-transparent links on the top.

These two scenarios are all for emphasizing certain links. If we have the data frame which contains the interactions, we can adjust the order of rows to adjust the order of links which are added to the Chord diagram.

If it is a matrix, we can use melt() from reshape2 package to convert it to a data frame:

df = reshape2::melt(mat)

To make it simple, we define colors for sectors:

grid.col = c("#00000040", "red", "#00FF0040", "#0000FF40", "orange", "pink", "yellow", "grey")
names(grid.col) = c(rownames(mat), colnames(mat))
grid.col
##          R1          R2          R3          R4          C1          C2 
## "#00000040"       "red" "#00FF0040" "#0000FF40"    "orange"      "pink" 
##          C3          C4 
##    "yellow"      "grey"

For the chordDiagram() function, if there is no color defined for the links, the links will have same color as the sectors where the interactions come from (here is the “R*” sectors).

Following is the default Chord diagram. As you can see links from “R2” are completely red, it is covered by links from “R3” and “R4” because “R3” and “R4” links are drawn later than “R2” links.

library(circlize)
chordDiagram(df, grid.col = grid.col)

plot of chunk unnamed-chunk-6

Next we adjust the order of rows of df to put “R2” links to the end, and then make the plot:

df2 = df[c(which(df[[1]] == "R1"), which(df[[1]] == "R3"), which(df[[1]] == "R4"), which(df[[1]] == "R2")), ]
chordDiagram(df2, grid.col = grid.col)

plot of chunk unnamed-chunk-7

Now the “R2” links are on the top, but the order of sectors changed that “R2” becomes the last sector in all “R*” sectors. This problem can be simply solved by explictly setting order options:

chordDiagram(df2, grid.col = grid.col, order = c(paste0("R", 1:4), paste0("C", 1:4)))

plot of chunk unnamed-chunk-8

In a same way, if you want to put the widest link on the very top, just reorder the rows of the data frame by the associated absolute values.

df3 = df[order(abs(df[[3]])), ]
chordDiagram(df3, grid.col = grid.col, order = c(paste0("R", 1:4), paste0("C", 1:4)))

plot of chunk unnamed-chunk-9

However, there is one serious problem that the order of rows also affect the positioning of links on a sector. As you can see in above plot, the order of links on a sector is not very optimized that links are twisted. We want the left second red link to be moved to the most right on sector “R2”.

From version 0.3.9, if the input is a data frame, the chordDiagram() recognizes a rank column which defines the order for adding links (so here rank == 1 means draw first).

df$rank = rank(abs(df[[3]]))
chordDiagram(df, grid.col = grid.col)

plot of chunk unnamed-chunk-10

Or to put non-transparent links on the top, note the values for the rank column can be duplicated.

df$rank = ifelse(df[[1]] == "R2", 2, 1)
chordDiagram(df, grid.col = grid.col)

plot of chunk unnamed-chunk-11

I am happy that now you can control the order of adding links while not change the structure of the diagram.