rcirclizecircos

How to make stacked circos plot?


I need to make a circos plot (preferably using circlize or other R package) that should look similar to this one: https://journals.plos.org/plosone/article/figure/image?size=large&id=10.1371/journal.pone.0075072.g003, but I want it to be divided in half based on group variable. Then, each track should represent proportions of enst1 to 5 for each gene. Finally, instead of names I'd like to plot div variable in the boxes. I'd be grateful for any help constructing the plot!

Example data:

group <- c(
  rep("G1",3),
  rep("G2",3)
  )
gene <- rep(letters[1:3], 2)
enst1 <- runif(6, min = 0, max = 1)
enst2 <- runif(6, min = 0, max = 1)
enst3 <- runif(6, min = 0, max = 1)
enst4 <- runif(6, min = 0, max = 1)
enst5 <- runif(6, min = 0, max = 1)
mtx <- cbind.data.frame(enst1, enst2, enst3, enst4, enst5)*1/rowSums(cbind.data.frame(enst1, enst2, enst3, enst4, enst5))
div <- runif(6, min = 1, max = 3)
data <- cbind.data.frame(group, 
                         gene,
                         mtx,
                         div)

Edit: This is one track of a desired output (proportions may be different than in the example data).

Desired output

Cross-posted on github: https://github.com/jokergoo/circlize/issues/329


Solution

  • Okay, there are a few issues with the texts in my code. But you can use the idea for the tracks...

    group <- c(
      rep("G1",3),
      rep("G2",3)
    )
    gene <- rep(letters[1:3], 2)
    enst1 <- runif(6, min = 0, max = 1)
    enst2 <- runif(6, min = 0, max = 1)
    enst3 <- runif(6, min = 0, max = 1)
    enst4 <- runif(6, min = 0, max = 1)
    enst5 <- runif(6, min = 0, max = 1)
    mtx <- cbind.data.frame(enst1, enst2, enst3, enst4, enst5)*1/rowSums(cbind.data.frame(enst1, enst2, enst3, enst4, enst5))
    div <- runif(6, min = 1, max = 3)
    data <- cbind.data.frame(group, 
                             gene,
                             mtx,
                             div)
    
    data.init <- data.frame(name = c("Text"), start = c(0,1), end = c(1,2))
    
    
    library(circlize)
    
    circos.par("start.degree" = 80)
    circos.par("gap.degree" = 25)
    
    circos.initialize(sectors = factor(data$group), xlim = c(0,1))
    
    for (gene in unique(data$gene)) {
      circos.track(ylim = c(0,1), bg.border = NA)
    }    
    
    track = 3
    for (gene in unique(data$gene)){
        circos.text(1.08,track, round(data$div[which(data$group == "G1" & data$gene == gene)], 2))
        start <- 0
        end <- 0
        end <- start + data$enst1[which(data$group == "G1" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "blue", sector.index = "G1", track.index = track)
        start <- end
        end <- end + data$enst2[which(data$group == "G1" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "green", sector.index = "G1", track.index = track)
        start <- end
        end <- end + data$enst3[which(data$group == "G1" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "orange", sector.index = "G1", track.index = track)
        start <- end
        end <- end + data$enst4[which(data$group == "G1" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "yellow", sector.index = "G1", track.index = track)
        start <- end
        end <- end + data$enst5[which(data$group == "G1" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "red", sector.index = "G1", track.index = track)
        track <- track - 1
    }
    
    
    track = 3
    for (gene in unique(data$gene)){
        circos.text(-0.08,track, round(data$div[which(data$group == "G2" & data$gene == gene)], 2))
        start <- 0
        end <- 0
        end <- start + data$enst1[which(data$group == "G2" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "blue", sector.index = "G2", track.index = track)
        start <- end
        end <- end + data$enst2[which(data$group == "G2" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "green", sector.index = "G2", track.index = track)
        start <- end
        end <- end + data$enst3[which(data$group == "G2" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "orange", sector.index = "G2", track.index = track)
        start <- end
        end <- end + data$enst4[which(data$group == "G2" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "yellow", sector.index = "G2", track.index = track)
        start <- end
        end <- end + data$enst5[which(data$group == "G2" & data$gene == gene)]
        circos.rect(start,0,end,1, col = "red", sector.index = "G2", track.index = track)
        track <- track - 1
    }
    
    circos.clear()
    

    enter image description here