Home | Blog | Software | Publications | GitHub

In Chord diagram, when there are two groups (which correspond to rows and columns if the input is a adjacency matrix), it is always visually beautiful to rotate the diagram to be symmetric on horizontal direction or vertical direction. Actually it is quite easy to calculate a proper degree that needs to be rotated for the circle. In this post, I will show how to calculate such kind of “rotated degree value”.

First let's create some random data.

```
set.seed(123)
mat = matrix(rnorm(30), nrow = 10, dimnames = list(letters[1:10], LETTERS[1:3]))
nr = nrow(mat)
nc = ncol(mat)
n_sector = nr + nc
```

In the Chord diagram, the total width of row sectors corresponds to the sum of row sum of the matrix with absolute values and so is for the column sectors.

```
row_sum = sum(rowSums(abs(mat)))
col_sum = sum(colSums(abs(mat)))
```

Small gaps between sectors are set to 1 degree and big gaps between row and column sectors are set to 20 degree.

```
small_gap = 1
big_gap = 20
```

In the circle, there are regions which are covered by small gaps, big gaps and sectors. Since the width of sectors are proportional to the row sums and/or column sums of the matrix, it is easy to calculate how much degrees are hold by the row sectors:

```
row_sector_degree = (360 - small_gap*(n_sector - 2) - big_gap*2) * (row_sum/(row_sum + col_sum)) +
small_gap*(nr-1)
```

If the row sectors are put in the right of the circle, we can calculate the “start degree” for the circle.
Note `chordDiagram()`

always draw row sectors first and by default the circle goes clockwisely.

```
start_degree = 90 - (180 - row_sector_degree)/2
```

Note there are small gaps and big gaps between sectors, the `gap.degree`

in `circos.par()`

should be set
as a vector. I also added a vertical line which assists to see the symmetry.

```
gaps = c(rep(small_gap, nrow(mat) - 1), big_gap, rep(small_gap, ncol(mat) - 1), big_gap)
circos.par(gap.degree = gaps, start.degree = start_degree)
grid_col = structure(rand_color(n_sector), names = c(rownames(mat), colnames(mat)))
chordDiagram(mat, grid.col = grid_col)
circos.clear()
abline(v = 0, lty = 2, col = "#00000080")
```

Similar we can adjust the “start degree” to let the circle looks horizonal.

```
start_degree = 0 - (180 - row_sector_degree)/2
gaps = c(rep(small_gap, nrow(mat) - 1), big_gap, rep(small_gap, ncol(mat) - 1), big_gap)
circos.par(gap.degree = gaps, start.degree = start_degree)
chordDiagram(mat, grid.col = grid_col)
circos.clear()
abline(h = 0, lty = 2, col = "#00000080")
```

```
sessionInfo()
```

```
## R version 3.3.2 (2016-10-31)
## Platform: x86_64-apple-darwin13.4.0 (64-bit)
## Running under: macOS Sierra 10.12.3
##
## locale:
## [1] C/en_US.UTF-8/C/C/C/C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets base
##
## other attached packages:
## [1] circlize_0.3.11 digest_0.6.12 htmltools_0.3.5 GetoptLong_0.1.7
## [5] markdown_0.7.7 knitr_1.15.1
##
## loaded via a namespace (and not attached):
## [1] Rcpp_0.12.9 grid_3.3.2 magrittr_1.5
## [4] evaluate_0.10 highr_0.6 stringi_1.1.2
## [7] GlobalOptions_0.0.11 rjson_0.2.15 tools_3.3.2
## [10] stringr_1.2.0 colorspace_1.3-2 shape_1.4.2
## [13] methods_3.3.2
```