I want to draw a two-color heatmap with a range from -2 to 6, and 0 is in white.
my code is giving me a symmetric color range and apparently my heatmap is too light.
I tried to use symbreaks = F
but then 0 is not white; I also tried manually assign two colors but its not working either.
colfunc1 <- colorRampPalette(brewer.pal(8, "Blues"))
colfunc2 <- colorRampPalette(brewer.pal(8, "Reds"))
hmcols <- c(colfunc1(25), colfunc2(25*(max(data) - 1)))
this is the code I used to generate the following heatmap. Please advise! Thank you!
heatmap.2(as.matrix(data), Colv=FALSE, scale = T, dendrogram = "row", trace = "none",
col = hmcol, key = T, cexCol = 1.5, cexRow = 1, srtCol = 15)
This issue is similar to this one I answered. It's about heatmaps in highcharter
package. The difference is that highcharter
is more convenient to assign colors. I use the same concept to solve this heatmap.2
case.
Sample Data
x <- rnorm(1000, 2, 1.5)
x[x < -2] <- -2
x[x > 6] <- 6
mat <- matrix(x, 20, 50)
Description
First, use symkey = F, symbreaks = F
in heatmap.2
can make the color-key asymmetric. And then, you need to find where the specified value (i.e. 0) is located in your data. By the following formula, you can get a value within 0 ~ 1 to represent the position of a certain value.
In this case, (0-(-2))/(6-(-2))
is 0.25. If there are 100 breakpoints, then you need to concatenate 100 * 0.25 = 25
red colors and 100 - 25 = 75
blue colors. You can find that the white color will be consistent with zero.
library(gplots)
library(RColorBrewer)
hmcol <- function(n){
colfun1 <- colorRampPalette(rev(brewer.pal(9, "Reds")))
colfun2 <- colorRampPalette(brewer.pal(9, "Blues"))
p <- (0 - min(mat)) / (max(mat) - min(mat))
gap <- n * p
c(colfun1(floor(gap)), colfun2(n - gap))
}
heatmap.2(mat, trace = "none", symkey = F, symbreaks = F, col = hmcol(50))
You can set any number in hmcol()
to indicate the number of breakpoints.(You can try col = hmcol(10)
and col = hmcol(100)
to see the difference.)