rchord-diagramcirclize

Aligning labels in a chordDiagram from circlize package


I have quite a complex circos plot and am having some trouble aligning the labels.

To demonstrate the issue I have included a short reproducible example below.

I can not figure out how to nicely align every label so that they all sit exactly the same distance from the corresponding segment e.g. as per the label tyranosauras rex. Many of the labels are hidden and overlapping and different distances from the edge of the plot. Any help would be greatly appreciated.

library("circlize")
circos.clear()

# create data
somelongnames <- c("homo sapiens", "arabidopsis thaliania", "Tyrannosaurus rex",
                  "some other long name", letters[seq(4)])

df <- data.frame(x = somelongnames,
                 y = c("this label is very far away from the plot", "Golgi", 
                       letters[13:18]),
                 count = c(2, 10, 4, 5, 5, 1, 9, 3))

# set colours
ll <- unique(c(df$x, df$y))
grid.col <- rainbow(length(ll))
grid.col <- setNames(grid.col, ll)

# create plot
par(mar = c(1,1,1,1)*12, cex = 0.6, xpd=NA)

chordDiagram(df, annotationTrack = "grid", 
             preAllocateTracks = 1, 
             grid.col = grid.col,
             directional = 1, 
             direction.type = c("diffHeight", "arrows"), 
             link.arr.type = "big.arrow")

circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), 
              ylim[1] + .1, 
              sector.name, 
              facing = "clockwise",
              niceFacing = TRUE, 
              adj = c(-0.5, 0.1),
              cex = 1,
              col=grid.col[sector.name],
              font = 2)
  circos.axis(h = "top",
              labels.cex = .6,
              major.tick.length = 1,
              sector.index = sector.name,
              track.index = 2)
}, bg.border = NA)

enter image description here


Solution

  • This question has been answered here by the package author of circlize

    Re-posting here to answer the above -

    The main problem is the setting of track.index = 2 in circos.axis() which changes the current track.

    Change the position on y-axis to ylim[1] + cm_h(2). This means 2cm's offset to the y = ylim[1]. (It seems it is not really 2cm on the plot, but you can manually change this value). adj is changed to adj = c(0, 0.5). Note the value of adj is multiplied to the length of the text length, so the physical length are not the same for all sector names. Remove major.tick.length = 1 because I think the default length of ticks should look fine.

    The following code fixes the above question

    chordDiagram(df, annotationTrack = "grid", 
                 preAllocateTracks = 1, 
                 grid.col = grid.col,
                 directional = 1, 
                 direction.type = c("diffHeight", "arrows"), 
                 link.arr.type = "big.arrow")
    
    circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
      xlim = get.cell.meta.data("xlim")
      ylim = get.cell.meta.data("ylim")
      sector.name = get.cell.meta.data("sector.index")
      circos.text(CELL_META$xcenter, 
                  ylim[1] + cm_h(2), 
                  sector.name, 
                  facing = "clockwise",
                  niceFacing = TRUE, 
                  adj = c(0, 0.5),
                  cex = 1,
                  col=grid.col[sector.name],
                  font = 2)
      circos.axis(h = "bottom",
                  labels.cex = .6,
                  sector.index = sector.name
                  )
    }, bg.border = NA)
    

    enter image description here