jokergoo / circlize

Circular visualization in R
http://jokergoo.github.io/circlize_book/book/
Other
959 stars 141 forks source link

How to use circos.labels with chordDiagram? #388

Open mhoban opened 4 months ago

mhoban commented 4 months ago

I'd like to use the overlap-avoidance of circos.labels to label sectors on a a chordDiagram. I've got it to where I can plot the labels, but I can't get them to plot on the outside of the chord diagram. They always seem to stay inside. I tried allocating new tracks and that didn't seem to really work. Is there a way to do this?

As a second question, the way I'm currently calculating x values for the circos.labels call feels a little hacky. Is there a better way?

Here's my current code:

library(circlize)
#> ========================================
#> circlize version 0.4.16
#> CRAN page: https://cran.r-project.org/package=circlize
#> Github page: https://github.com/jokergoo/circlize
#> Documentation: https://jokergoo.github.io/circlize_book/book/
#> 
#> If you use it in published research, please cite:
#> Gu, Z. circlize implements and enhances circular visualization
#>   in R. Bioinformatics 2014.
#> 
#> This message can be suppressed by:
#>   suppressPackageStartupMessages(library(circlize))
#> ========================================

dd <- structure(list(marker = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 5L, 
1L, 2L, 3L, 5L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 1L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 5L, 3L, 2L, 3L, 3L, 
1L, 2L, 3L, 5L, 2L, 3L, 1L, 2L, 3L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 
2L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 1L, 2L, 3L, 1L, 2L, 
3L, 4L, 5L, 2L, 3L, 3L, 1L, 1L, 3L, 4L), .Label = c("MiFish_E", 
"MiFish_U", "Riaz_12S", "CO1", "Berry_16S", "28S"), class = "factor"), 
family = c("Acanthuridae", "Acanthuridae", "Acanthuridae", 
"Acanthuridae", "Acanthuridae", "Acanthuridae", "Agonidae", 
"Balistidae", "Balistidae", "Balistidae", "Balistidae", "Chaetodontidae", 
"Chaetodontidae", "Chaetodontidae", "Chaetodontidae", "Chaetodontidae", 
"Clupeidae", "Clupeidae", "Clupeidae", "Clupeidae", "Clupeidae", 
"Cyclopteridae", "Gadidae", "Gadidae", "Gadidae", "Gadidae", 
"Gadidae", "Holocentridae", "Holocentridae", "Holocentridae", 
"Holocentridae", "Labridae", "Labridae", "Labridae", "Labridae", 
"Lotidae", "Moronidae", "Moronidae", "Mullidae", "Nemipteridae", 
"Nemipteridae", "Nemipteridae", "Nemipteridae", "Pleuronectidae", 
"Pleuronectidae", "Pomacanthidae", "Pomacanthidae", "Pomacanthidae", 
"Pomacanthidae", "Pomacentridae", "Pomacentridae", "Pomacentridae", 
"Pomacentridae", "Pomacentridae", "Pseudochromidae", "Pseudochromidae", 
"Salmonidae", "Salmonidae", "Salmonidae", "Salmonidae", "Salmonidae", 
"Salmonidae", "Scombridae", "Scombridae", "Scombridae", "Scombridae", 
"Sebastidae", "Sebastidae", "Sebastidae", "Siganidae", "Siganidae", 
"Siganidae", "Siganidae", "Siganidae", "Sparidae", "Sparidae", 
"Stromateidae", "Chimaeridae", "Rajidae", "Rajidae", "Triakidae"
), n = c(20L, 19L, 18L, 8L, 18L, 3L, 1L, 3L, 3L, 3L, 3L, 
6L, 6L, 7L, 6L, 3L, 12L, 11L, 8L, 3L, 12L, 1L, 4L, 6L, 7L, 
1L, 3L, 1L, 1L, 2L, 1L, 3L, 2L, 3L, 3L, 1L, 1L, 2L, 1L, 3L, 
3L, 3L, 3L, 1L, 3L, 5L, 5L, 5L, 4L, 10L, 11L, 9L, 2L, 9L, 
1L, 2L, 10L, 11L, 13L, 2L, 7L, 3L, 2L, 1L, 3L, 1L, 2L, 2L, 
2L, 3L, 3L, 3L, 2L, 3L, 1L, 1L, 1L, 2L, 1L, 1L, 1L)), row.names = c(NA, 
-81L), class = c("tbl_df", "tbl", "data.frame"))

palette <- c(`28S` = "#4E79A7FF", Berry_16S = "#F28E2BFF", CO1 = "#E15759FF", 
MiFish_E = "#76B7B2FF", MiFish_U = "#59A14FFF", Riaz_12S = "#EDC948FF", 
Acanthuridae = "#1C3333", Agonidae = "#1C3737", Albulidae = "#1D3B3B", 
Apogonidae = "#1D3F3F", Atherinidae = "#1E4343", Balistidae = "#1E4747", 
Belonidae = "#1F4B4B", Blenniidae = "#1F4F4F", Carangidae = "#205353", 
Chaetodontidae = "#205757", Cichlidae = "#215B5B", Cirrhitidae = "#215F5F", 
Clupeidae = "#266464", Coryphaenidae = "#2C696A", Cyclopteridae = "#326F71", 
Dactylopteridae = "#387477", Diodontidae = "#3D797D", Engraulidae = "#437F83", 
Exocoetidae = "#498489", Fistulariidae = "#4F898F", Gadidae = "#558F95", 
Gempylidae = "#5A949B", Gobiidae = "#6099A1", Hemiramphidae = "#689CA1", 
Holocentridae = "#729E9E", Kuhliidae = "#7C9F9A", Kyphosidae = "#86A197", 
Labridae = "#90A293", Lethrinidae = "#9AA490", Lotidae = "#A4A68C", 
Lutjanidae = "#AEA788", Molidae = "#B8A985", Monacanthidae = "#C2AA81", 
Moronidae = "#CCAC7E", Mugilidae = "#D1AA7A", Mullidae = "#CFA575", 
Muraenidae = "#CDA070", Nemipteridae = "#CB9B6B", Nomeidae = "#CA9566", 
Ostraciidae = "#C89061", Pleuronectidae = "#C68B5C", Poeciliidae = "#C48657", 
Pomacanthidae = "#C38052", Pomacentridae = "#C17B4D", Pseudochromidae = "#BF7648", 
Salmonidae = "#BB7044", Scombridae = "#B16940", Scorpaenidae = "#A6623C", 
Sebastidae = "#9B5A39", Serranidae = "#915335", Siganidae = "#864C31", 
Sparidae = "#7B452E", Sphyraenidae = "#703D2A", Stromateidae = "#663626", 
Tetraodontidae = "#5B2F23", Xiphiidae = "#50281F", Zanclidae = "#46211C", 
Carcharhinidae = "#2CB11B", Chimaeridae = "#77C049", Echinorhinidae = "#A6D076", 
Hexanchidae = "#A5D89D", Myliobatidae = "#32BBAC", Pseudotriakidae = "#0B91B8", 
Rajidae = "#065FA7", Triakidae = "#172869")

markers <-c("28S", "Berry_16S", "CO1", "MiFish_E", "MiFish_U", "Riaz_12S") 

chordDiagram(dd, annotationTrack = "grid", preAllocateTracks = 1,grid.col = palette)
cellz <- list(
  x = c(),
  index = c(),
  name = c()
)
circos.track(track.index = 1, panel.fun = function(x, y) {
  if (CELL_META$sector.index %in% markers) {
    circos.text(CELL_META$xcenter, CELL_META$ylim[1], CELL_META$sector.index,
                facing = "bending.outside", adj = c(0.5,1),cex=1)#, niceFacing = TRUE, adj = c(0, 0))
  } else {
    cellz$x[CELL_META$sector.numeric.index] <<- CELL_META$xcenter
    cellz$index[CELL_META$sector.numeric.index] <<- CELL_META$sector.numeric.index
    cellz$name[CELL_META$sector.numeric.index] <<- CELL_META$sector.index
  }
},bg.border=NA)
#> Note: 1 point is out of plotting region in sector 'CO1', track '1'.
#> Note: 2 points are out of plotting region in sector '28S', track '1'.

cellz <- lapply(cellz,na.omit)

circos.labels(cellz$name,cellz$x,cellz$name,side="outside")

As you can see, the labels all show up inside the chord diagram. How can I place them on the outside? (note: I'm only using circos.labels for the top sectors, the bottom ones are labeled normally using circos.text)

mhoban commented 4 months ago

I initially tried to put circos.labels inside of panel.fun (like I did with circos.text), but I got the error:

"Error: panel_fun should not change the current track index. Please check the functions used inside panel_fun."