Search code examples
rheatmapcirclizecircos

R package circlize: circos heatmap colors not showing up


I am trying to create a circular plot using circlize package. When using hex color codes, my plot does not show up anything but when I use actual color names, it shows. Why is that?

Code:

suppressPackageStartupMessages({
  library(tidyverse) 
  library(circlize) 
})

# input data
dput(annot)

structure(list(Case_type = c("Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "Initial CNS Tumor", 
"Initial CNS Tumor", "Initial CNS Tumor", "no evidence of disease", 
"no evidence of disease", "no evidence of disease", "Progressive", 
"Progressive", "Progressive", "Progressive", "Progressive", "Progressive", 
"Progressive", "Progressive", "Progressive", "Progressive", "Recurrence", 
"Recurrence", "Recurrence", "Recurrence", "Recurrence", "Recurrence", 
"Recurrence", "Recurrence")), row.names = c("15635-32", "15635-37", 
"15635-38", "15635-42", "15635-43", "15635-53", "15635-58", "15635-60", 
"15635-63", "15635-70", "15635-75", "15635-80", "15635-87", "15635-100", 
"15635-108", "15635-132", "15635-134", "15635-135", "15635-2", 
"15635-7", "15635-11", "15635-145", "15635-150", "15635-154", 
"15635-161", "15635-169", "15635-170", "15635-187", "15635-197", 
"15635-214", "15635-228", "15635-225", "15635-234", "15635-239", 
"15635-251", "15635-246", "15635-254", "15635-182", "15635-45", 
"15635-46", "15635-68", "15635-90", "15635-101", "15635-127", 
"15635-1", "15635-148", "15635-156", "15635-29", "15635-31", 
"15635-215", "15635-81", "15635-120", "15635-129", "15635-158", 
"15635-279"), class = "data.frame")

# split into 4 categories
split <- factor(annot$Case_type)
circos.clear()

# does not work with the hex color codes
col_fun1 <- list('Initial CNS Tumor' = '#59acff',
                 'Recurrence' = '#ffac59',
                 'Progressive' = '#ffff59',
                 'no evidence of disease' = '#acff59')
circos.par(start.degree = 30, gap.degree = 1, points.overflow.warning = FALSE)
circos.heatmap(annot, 
               split = split, 
               col = col_fun1, 
               track.height = 0.4, 
               bg.border = "gray50",
               show.sector.labels = T)
circos.clear()

enter image description here

When I use non-hex color names, it works:

# this works
col_fun2 <- list('Initial CNS Tumor' = 'yellow',
                 'Recurrence' = 'blue',
                 'Progressive' = 'green',
                 'no evidence of disease' = 'orange')
circos.par(start.degree = 30, gap.degree = 1, points.overflow.warning = FALSE)
circos.heatmap(annot, 
               split = split, 
               col = col_fun2, 
               track.height = 0.4, 
               bg.border = "gray50",
               show.sector.labels = T)
circos.clear()

enter image description here


Solution

  • According to the docs, when describing the argument col

    If the values are characters, the color should be a named color vector.

    Whereas you are passing a list rather than a named vector. So if you unlist col_fun1 (or create it with c() instead of list()), you get

    circos.par(start.degree = 30, gap.degree = 1, points.overflow.warning = FALSE)
    circos.heatmap(annot, 
                   split = split, 
                   col = unlist(col_fun1),
                   track.height = 0.4, 
                   bg.border = "gray50",
                   show.sector.labels = T)
    circos.clear()
    

    enter image description here

    The puzzle for me is why the first version works, not why the second one doesn't.