# Support HCL colormaps in ComplexHeatmap

To demonstrate this new feature, I first generate a small random matrix.

``````set.seed(123)
nr1 = 4; nr2 = 8; nr3 = 6; nr = nr1 + nr2 + nr3
nc1 = 6; nc2 = 8; nc3 = 10; nc = nc1 + nc2 + nc3
mat = cbind(rbind(matrix(rnorm(nr1*nc1, mean = 1,   sd = 0.5), nr = nr1),
matrix(rnorm(nr2*nc1, mean = 0,   sd = 0.5), nr = nr2),
matrix(rnorm(nr3*nc1, mean = 0,   sd = 0.5), nr = nr3)),
rbind(matrix(rnorm(nr1*nc2, mean = 0,   sd = 0.5), nr = nr1),
matrix(rnorm(nr2*nc2, mean = 1,   sd = 0.5), nr = nr2),
matrix(rnorm(nr3*nc2, mean = 0,   sd = 0.5), nr = nr3)),
rbind(matrix(rnorm(nr1*nc3, mean = 0.5, sd = 0.5), nr = nr1),
matrix(rnorm(nr2*nc3, mean = 0.5, sd = 0.5), nr = nr2),
matrix(rnorm(nr3*nc3, mean = 1,   sd = 0.5), nr = nr3))
)``````

Since this matrix contains both positive and negative values, we may want the color mapping to be symmetric to zero, thus we define a zero-centric color mapping function with `circlize::colorRamp2()`. The “blue-white-red” heatmap looks like as follows:

``````library(circlize)
library(ComplexHeatmap)
col_fun = colorRamp2(c(-2, 0, 2), c("blue", "white", "red"))
Heatmap(mat, name = "mat", col = col_fun,
show_row_dend = FALSE, show_column_dend = FALSE)`````` In the example, the color mapping function `col_fun` defines three colors (blue/white/red) for the three breaks values (-2/0/2), and other values are linearly interpolated in the LAB color space (by default).

In the paper “colorspace: A Toolbox for Manipulating and Assessing Colors and Palettes”, it described color maps in the HCL color space, which are more natural for human perception of colors. It also provides rich color palettes extracted in the HCL color space. The list of color palettes are listed in `grDevides::hcl.pals()`.

``hcl.pals("diverging")``
``````##   "Blue-Red"      "Blue-Red 2"    "Blue-Red 3"    "Red-Green"
##   "Purple-Green"  "Purple-Brown"  "Green-Brown"   "Blue-Yellow 2"
##   "Blue-Yellow 3" "Green-Orange"  "Cyan-Magenta"  "Tropic"
##  "Broc"          "Cork"          "Vik"           "Berlin"
##  "Lisbon"        "Tofino"``````
``hcl.pals("divergingx")``
``````##   "ArmyRose" "Earth"    "Fall"     "Geyser"   "TealRose" "Temps"
##   "PuOr"     "RdBu"     "RdGy"     "PiYG"     "PRGn"     "BrBG"
##  "RdYlBu"   "RdYlGn"   "Spectral" "Zissou 1" "Cividis"  "Roma"``````
``hcl.pals("sequential")``
``````##   "Grays"         "Light Grays"   "Blues 2"       "Blues 3"
##   "Purples 2"     "Purples 3"     "Reds 2"        "Reds 3"
##   "Greens 2"      "Greens 3"      "Oslo"          "Purple-Blue"
##  "Red-Purple"    "Red-Blue"      "Purple-Orange" "Purple-Yellow"
##  "Blue-Yellow"   "Green-Yellow"  "Red-Yellow"    "Heat"
##  "Heat 2"        "Terrain"       "Terrain 2"     "Viridis"
##  "Plasma"        "Inferno"       "Rocket"        "Mako"
##  "Dark Mint"     "Mint"          "BluGrn"        "Teal"
##  "TealGrn"       "Emrld"         "BluYl"         "ag_GrnYl"
##  "Peach"         "PinkYl"        "Burg"          "BurgYl"
##  "RedOr"         "OrYel"         "Purp"          "PurpOr"
##  "Sunset"        "Magenta"       "SunsetDark"    "ag_Sunset"
##  "BrwnYl"        "YlOrRd"        "YlOrBr"        "OrRd"
##  "Oranges"       "YlGn"          "YlGnBu"        "Reds"
##  "RdPu"          "PuRd"          "Purples"       "PuBuGn"
##  "PuBu"          "Greens"        "BuGn"          "GnBu"
##  "BuPu"          "Blues"         "Lajolla"       "Turku"
##  "Hawaii"        "Batlow"``````

From circlize version 0.4.14, the function `colorRamp2()` now accepts a new argument `hcl_palette` which allows to set a specific HCL color palette. The valid values are those supported in `grDevides::hcl.pals()`.

To set a color mapping function which extends colors in the HCL color space, simply set the `hcl_palette` argument. For example:

``colorRamp2(c(-2, 0, 2), hcl_palette = "Blue-Red 2")``

Please note: DO NOT set as in the following code. In there, three colors are extracted from the “Blue-Red 2” palette, but all other colors are still interpolated in the LAB color space.

``colorRamp2(c(-2, 0, 2), hcl.colors(3, "Blue-Red 2"))  # this is wrong``

In the following, each heatmap uses a specific HCL color palette. You can see how the heatmap looks like under different HCL color palettes.

``````pl = list()
for(palette in sort(hcl.pals("diverging"))) {
col_fun = colorRamp2(c(-2, 0, 2), hcl_palette = palette)
ht = Heatmap(mat, name = "mat", col = col_fun,
show_row_dend = FALSE, show_column_dend = FALSE,
column_title = paste0("palette = '", palette, "'"),
heatmap_legend_param = list(legend_height = unit(6, "cm")))
pl[[palette]] = grid.grabExpr(draw(ht))
}
library(cowplot)
plot_grid(plotlist = pl, ncol = 5)`````` ``````pl = list()
for(palette in sort(hcl.pals("divergingx"))) {
col_fun = colorRamp2(c(-2, 0, 2), hcl_palette = palette)
ht = Heatmap(mat, name = "mat", col = col_fun,
show_row_dend = FALSE, show_column_dend = FALSE,
column_title = paste0("palette = '", palette, "'"),
heatmap_legend_param = list(legend_height = unit(6, "cm")))
pl[[palette]] = grid.grabExpr(draw(ht))
}
plot_grid(plotlist = pl, ncol = 5)`````` ``````pl = list()
for(palette in sort(hcl.pals("sequential"))) {
col_fun = colorRamp2(range(mat), hcl_palette = palette, reverse = TRUE)
ht = Heatmap(mat, name = "mat", col = col_fun,
show_row_dend = FALSE, show_column_dend = FALSE,
column_title = paste0("palette = '", palette, "'"),
heatmap_legend_param = list(legend_height = unit(6, "cm")))
pl[[palette]] = grid.grabExpr(draw(ht))
}
plot_grid(plotlist = pl, ncol = 5)`````` 