rplotchord-diagramcircos

Adjust highlight.sector() width and placement - Chord diagram (circlize package) in R


I need some help with adjusting highlighted sectors of a chordDiagram() from the circlize package.

I am working with fisheries landings data. Fishing vessels start their trip in one port (homeport PORT_DE), and land their catch in another port (landing port PORT_LA). I am working with scallops live weight in tonnes (landings SCALLOP_W). Here is a simple example of the dataframe:

        PORT_DE  PORT_LA SCALLOP_W
1      Aberdeen Aberdeen       116
2        Barrow   Barrow        98
3       Douglas   Barrow       127
4 Kirkcudbright   Barrow       113
5       Brixham  Brixham        69
6        Buckie   Buckie       180

Each port (Name_short) is labeled by region (Region_lb), and by country (Country_lb). Example below.

   Name_short Country_lb      Region_lb
1   Scalloway   Scotland Shetland Isles
2   Scrabster   Scotland    North Coast
3      Buckie   Scotland    Moray Firth
4 Fraserburgh   Scotland    Moray Firth
5    Aberdeen   Scotland     North East

Using the circilze package, I have generated a customised chordDiagram to visualise the flow of landings between ports. I have adjusted most of the settings, including grouping of ports of the same nation, by adjusting the spacing between sectors (see gap.after setting). This is the current form of my chord diagram,

Flow diagram (chord) of landings between ports

I have nearly produced what I want, apart from the final touch of highlighting sectors by country. I am trying to use highlight.sector() in order to highlight ports of the same country, but I cannot adjust either the width or the placement of the highlighted sector. Currently, the country sectors overlap with all the other labels. Example below:

enter image description here

Please note that there are different colours between the two figures as colours are randomly generated.

Could you please assist me with the final adjustments?

Code for producing the figures shown below:

# calculate gaps by country; 
# 1 degree between ports, 10 degree between countries
gaps <- rep(1, nrow(port_coords))
gaps[cumsum(as.numeric(tapply(port_coords$Name_short, port_coords$Country_lb, length)))] <- 10

# edit initialising parameters
circos.par(canvas.ylim=c(-1.5,1.5), # edit  canvas size 
           gap.after = gaps, # adjust gaps between regions
           track.margin = c(0.01, 0)) # adjust bottom and top margin 
                                      # (blank area out of the plotting regio)

# Plot chord diagram
chordDiagram(m,

             # manual order of sectors
             order = port_coords$Name_short,

             # plot only grid (no labels, no axis)
             annotationTrack = "grid", 
             preAllocateTracks = 1, 

             # adjust grid width and spacing
             annotationTrackHeight = c(0.03, 0.01), 

             # add directionality
             directional=1, 
             direction.type = c("diffHeight", "arrows"), 
             link.arr.type = "big.arrow",

             # adjust the starting end of the link
             diffHeight = -uh(1, "mm"),

             # adjust height of all links
             h.ratio = 0.8,

             # add link border
             link.lwd = 1, link.lty = 1, link.border="gray35"

             )

# add labels and axis manually
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")

  # print labels & text size (cex)
  circos.text(mean(xlim), ylim[1] + .7, sector.name, 
              facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5), cex=0.6)

  # print axis
  circos.axis(h = "top", labels.cex = 0.5, major.tick.percentage = 0.2, 
              sector.index = sector.name, track.index = 2)
}, bg.border = NA)

# add additional track to enhance the visual effect of different groups
# Scotland
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Scotland")],
                 track.index = 1, col = "blue",
                 text = "Scotland", cex = 0.8, text.col = "white", niceFacing = TRUE)
# England
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "England")],
                 track.index = 1, col = "red",
                 text = "England", cex = 0.8, text.col = "white", niceFacing = TRUE)
# Wales
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Wales")],
                 track.index = 1, col = "forestgreen",
                 text = "Wales", cex = 0.8, text.col = "white", niceFacing = TRUE)
# Isle of Man
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Isle of Man")],
                 track.index = 1, col = "darkred",
                 text = "Isle of Man", cex = 0.8, text.col = "white", niceFacing = TRUE)
# Rep. Ireland
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Rep. Ireland")],
                 track.index = 1, col = "darkorange2",
                 text = "Ireland", cex = 0.8, text.col = "white", niceFacing = TRUE)
# N.Ireland
highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "N.Ireland")],
                 track.index = 1, col = "magenta4",
                 text = "N. Ireland", cex = 0.8, text.col = "white", niceFacing = TRUE)

# re-set circos parameters
circos.clear()

Solution

  • I have been trying for a while now to find a solution. I have now managed to adjust the placement and the width of the highlight.sector() by adjusting the default track margins and default track height.

    I have done so by specifying track.margin and track.height parameters in the initialisation of circos.par() step.

    The end product looks like below. Code at the end the answer.

    enter image description here

    # calculate gaps by country; 
    # 1 degree between ports, 10 degree between countries
    gaps <- rep(1, nrow(port_coords))
    gaps[cumsum(as.numeric(tapply(port_coords$Name_short, port_coords$Country_lb, length)))] <- 10
    
    # edit initialising parameters
    circos.par(canvas.ylim=c(-1.5,1.5), # edit  canvas size 
               gap.after = gaps, # adjust gaps between regions
               track.margin = c(0.01, 0.05), # adjust bottom and top margin
               # track.margin = c(0.01, 0.1)
               track.height = 0.05)
    
    # Plot chord diagram
    chordDiagram(m,
    
                 # manual order of sectors
                 order = port_coords$Name_short,
    
                 # plot only grid (no labels, no axis)
                 annotationTrack = "grid",
                 # annotationTrack = NULL, 
                 preAllocateTracks = 1, 
    
                 # adjust grid width and spacing
                 annotationTrackHeight = c(0.03, 0.01), 
    
                 # add directionality
                 directional=1, 
                 direction.type = c("diffHeight", "arrows"), 
                 link.arr.type = "big.arrow",
    
                 # adjust the starting end of the link
                 diffHeight = -uh(1, "mm"),
    
                 # adjust height of all links
                 h.ratio = 0.8,
    
                 # add link border
                 link.lwd = 1, link.lty = 1, link.border="gray35"
    
                 # track.margin = c(0.01, 0.1)
    
                 )
    
    # Scotland
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Scotland")],
                     track.index = 1, col = "blue2",
                     text = "Scotland", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    # England
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "England")],
                     track.index = 1, col = "red2",
                     text = "England", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    # Wales
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Wales")],
                     track.index = 1, col = "springgreen4",
                     text = "Wales", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    # Isle of Man
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Isle of Man")],
                     track.index = 1, col = "orangered4",
                     text = "Isle of Man", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    # Rep. Ireland
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "Rep. Ireland")],
                     track.index = 1, col = "darkorange3",
                     text = "Ireland", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    # N.Ireland
    highlight.sector(port_coords$Name_short[which(port_coords$Country_lb == "N.Ireland")],
                     track.index = 1, col = "magenta4",
                     text = "NI", cex = 1, text.col = "white", 
                     niceFacing = TRUE, font=2)
    
    # add labels and axis manually
    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")
    
      # print labels & text size (cex)
      # circos.text(mean(xlim), ylim[1] + .7, sector.name, 
      #             facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5), cex=0.6)
    
      circos.text(mean(xlim), ylim[1] + 2, sector.name, 
                  facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5), cex=0.6)
    
      # print axis
      circos.axis(h = "bottom", labels.cex = 0.5, 
                  # major.tick.percentage = 0.05, 
                  major.tick.length = 0.6,
                  sector.index = sector.name, track.index = 2)
    }, bg.border = NA)
    
    # re-set circos parameters
    circos.clear()