0

Using the package circlize from R, My objective is to be able to reduce the default gaps generated between the sectors in the chord diagram. According to the manual, this is possible by passing the gap.after command within the circos.par command. The circos.par needs to be run right before the chordDiagram command that actually plots the chord diagram.

I have seen other posts where this was done within the code:
Adjust highlight.sector() width and placement - Chord diagram (circlize package) in R

The manual has examples on how to use the gap.afer flag in Section 14.2: 14.2 Adjust by circos.par()

However, no matter how I set-up the gap.after flag, it will not close the gaps between the sectors that are created when I run the chordDiagram command.

Additionally, I am looking to adjust the number scale (tick marks) that are automatically generated. I would like the tick marks to reflect the actual numbers of links (i.e., counts) going to and from that sector. The ticks that are automatically assigned are approximate values, not counts. I would like to put the tick marks on a scale from 0-N for each sector, with N being the actual counts of links going into and out of each sector.

A reproducible example

Division <- data.frame(Types = c("OOP", "UVA", "MAT", "OIC", "FIN", "WSE"))
Div_Cols <- c(OOP = "#548235", UVA = "#660066", MAT = "#4472C4", OIC = "#002060", FIN = "#843C0C", WSE = "#C55A11")
name <- paste(c("Deer", "Tiger", "Cat", "Lemur", "Leopard", "Bear", "Skunk", "Meerkat", "Praire-Dog", "Moose", 
                "Elk", "Kangaroo", "Wolf", "Wild-Boar", "Monkey", "Elephant", "Zebra", "Bob-Cat"))

Div_df <- data.frame(from = sample(name, 35, replace = TRUE), to = sample(name, 35, replace = TRUE))

Div_df$Taxa_1 <- ifelse(Div_df$from %in% c("Deer", "Tiger", "Cat"), "OOP", 
       ifelse(Div_df$from %in% c("Lemur", "Leopard", "Bear"), "UVA", 
              ifelse(Div_df$from %in% c("Skunk", "Meerkat", "Praire-Dog"), "MAT", 
                     ifelse(Div_df$from %in% c("Moose","Elk", "Kangaroo"), "OIC", 
                            ifelse(Div_df$from %in% c("Wolf", "Wild-Boar", "Monkey"), "FIN", 
                                   ifelse(Div_df$from %in% c("Elephant", "Zebra", "Bob-Cat"), "WSE", Div_df$from))))))                  

Div_df$Taxa_2 <- ifelse(Div_df$to %in% c("Deer", "Tiger", "Cat"), "OOP", 
                        ifelse(Div_df$to %in% c("Lemur", "Leopard", "Bear"), "UVA", 
                               ifelse(Div_df$to %in% c("Skunk", "Meerkat", "Praire-Dog"), "MAT", 
                                      ifelse(Div_df$to %in% c("Moose","Elk", "Kangaroo"), "OIC", 
                                             ifelse(Div_df$to %in% c("Wolf", "Wild-Boar", "Monkey"), "FIN", 
                                                    ifelse(Div_df$to %in% c("Elephant", "Zebra", "Bob-Cat"), "WSE", Div_df$to))))))                  


#Setting up sectors, groups, and the grid.col
#orgin/destination
Div2_df <- Div_df %>% mutate(from = paste0(from, ".", Taxa_1), 
                              to = paste0(to, ".", Taxa_2))

head(Div2_df)

#sectors
Div_sect <- sort(unique(c(Div2_df$from, Div2_df$to)))
Div_sect

#groups
Div_group <- structure(gsub("^[^.]*.", "", Div_sect), names = Div_sect)
Div_group

#grid.col
gsub("^[^.]*.", "", Div_sect)
Div_grid.col <- structure(Div_Cols[match(gsub("^[^.]*.", "", Div_sect), labels(Div_Cols))], names = Div_sect)

#Graph chord diagram
library(circlize)

#circos.par(gap.after = ...) #Sets the gaps 

chordDiagram(Div2_df %>% select(from, to), 
             order = Div_sect, 
             group = Div_group, 
             grid.col = Div_grid.col, 
             directional = 1, 
             direction.type = c("diffHeight", "arrows"), 
             annotationTrack = c("grid", "axis"), 
             link.arr.col = rep("gray100", nrow(Div2_df)), 
             preAllocateTracks = 1)

#Adding sector labels
for(si in get.all.sector.index()) {
  xlim = get.cell.meta.data("xlim", sector.index = si, track.index = 2)
  ylim = get.cell.meta.data("ylim", sector.index = si, track.index = 2)
  circos.text(mean(xlim), mean(ylim), 
              labels = gsub("\\..*","", si), 
              sector.index = si, track.index = 2,
              col = "black", cex = 1.2, facing = "clockwise", 
              adj = c(-0.5, 0), niceFacing = TRUE)
}

This produces the following chord diagram (default on left). The right chord diagram points out the gaps I am trying to minimize and the tick marks.

Gap and Ticks

The Gaps

For the gaps, I have tried the following commands and many variations of these:

circos.par(gap.after = c(rep(0.3, length(unique(Div_df$from)))), 
       gap.after = c(rep(0.3, length(unique(Div_df$to)))))

Additionally, according to the manual, you can set gaps as a named vector:

#Getting sector names
get.all.sector.index()
circos.par(gap.after = c("Leopard.UVA" = 0.3, "Zebra.WSE" = 0.3, "Wolf.FIN" = 0.3, "Skunk.MAT" = 0.3, "Moose.OIC" = 0.3, "Tiger.OOP" = 0.3))

However, these approaches don't work.

The Tick Marks

For the tick marks, in the manual in section 3.7, it addresses the tick marks: 3.7 Axes Circular chart customization for the circlize R package

What I'm aiming to do = As an example, the 'Bear' sector tick marks - setting it from 0-3. The 'Wolf' sector only has 2 links total but the tick marks indicate a number higher than 2. Setting this from 0-2, and so on with all of the sectors of the chord diagram (an actual count).

The command to adjust the tick marks is circos.axis or circos.xaxis and the only example I see how to use it is inside the circos.trackPlotRegion. However, I dont see how this flag can be passed to either circos.par or to chordDiagram. Additionally, I also dont see a way to introduce breaks for the ticks - just labels, font, major, minor ticks, etc. Am I missing or misunderstanding something?

Any help with this is greatly appreciated.

Purrsia
  • 712
  • 5
  • 18

1 Answers1

0

Adding group to the chordDiagram() function always separates the groups by a large gap. But by giving a mix of sectors, we can narrow the gap. We can order the chordDiagram according to the sorted sector names as done in the following code.

#Graph chord diagram
library(circlize)
circos.clear()
chordDiagram(Div2_df %>% select(from, to),
             order = names(sort(Div_group)),
             #group = Div_group, 
         grid.col = Div_grid.col, 
         directional = 1, 
         direction.type = c("diffHeight", "arrows"), 
         annotationTrack = c("grid"), 
         link.arr.col = rep("gray100", nrow(Div2_df)), 
         preAllocateTracks = 1)
#Adding sector labels
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(3), 
           labels = gsub("\\..*","", sector.name),
           col = "black", cex = 1.5, facing = "clockwise", 
           adj = c(0, 0.5), niceFacing = TRUE, font = 2)
    #Editing ticks
    circos.axis(
           h = "top",  track.index=2,
           major.at = seq(from = 0, to = xlim[2], by = ifelse(test = xlim[2]>10, yes = 2, no = 1)), 
           minor.ticks = 0, 
           sector.index = sector.name,
           labels.niceFacing = FALSE)
    }, bg.border = NA)

enter image description here

Nitesh Shriwash
  • 128
  • 1
  • 6