Need a palette with 64 colours: simple heatmap question

Viewed 100

I have a several thousand matrices which look something like the following:

         [,1]     [,2]     [,3]     [,4]     [,5]     [,6]
 [1,] 560.5681 526.3265 501.4808 447.4124 475.3496 487.1298
 [2,] 556.7537 525.3711 460.2989 412.7424 478.1070 506.8339
 [3,] 570.1362 534.5701 461.2309 476.0936 509.1480 491.3332
 [4,] 564.1036 538.4911 593.1357 573.0606 532.7869 496.5737
 [5,] 606.3170 583.7723 536.8325 614.4326 514.1198 427.6375
 [6,] 555.8331 576.4716 642.0229 617.1337 620.3885 483.4476
 [7,] 790.4830 790.4830 790.4830 790.4830 790.4830 790.4830
 [8,] 790.4830 790.4830 790.4830 790.4830 790.4830 790.4830
 [9,] 790.4830 790.4830 790.4830 790.4830 790.4830 790.4830
[10,] 790.4830 790.4830 790.4830 790.4830 790.4830 790.4830

I wanted to build a heatmap which was sensitive enough to give each cell its own shade. I tried the following:

heatmap(irradiances_shaded_ready_to_use_FINAL[[160]][[1200]], Colv=NA, 
        Rowv=NA, xlab="", ylab="Irradiance", 
        main="Snapshot 1200 day 160", 
        col=colorRampPalette(brewer.pal(64, "Oranges"))(3))

...but then the error/warning message is:

Warning message:
In brewer.pal(64, "Oranges") :
  n too large, allowed maximum for palette Oranges is 9
Returning the palette you asked for with that many colors

Please note: in the above matrix which I pasted above, there are several repeated values, but this is generally not the case. I have like 500,000 such matrices, and I will want to heatmap a small sample of them, but in general I expect that in most cases there will be 64 unique values.

So basically: I need a palette which can illustrate a matrix of 64 unique values. I'm sorry if this is such a simple question.

@jay.sf has suggested that I use "heat.colors (etc etc)," but this doesn't work for me. See the heatmap below: the top four rows are left unshaded, while they should be.

enter image description here

2 Answers

You can extend RColorBrewer palettes using the base colorRampPalette function:

library(RColorBrewer)
colorRampPalette(brewer.pal(8, "Oranges"))(64)

I also recommend using pheatmap::pheatmap. You provide a numeric matrix + a vector of 100 colors and it does the rest for you.

library(pheatmap)
data <- matrix(rnorm(100), ncol = 10)
pheatmap(mat = data, color = colorRampPalette(brewer.pal(8, "Oranges"))(100))

By default heatmap uses scale="row", where also available "column" and "none". I think the latter is what you need, because a row with no variation gets scaled to zero and thus would appear unshaded. When you do col=heat.colors(64), the "problematic" rows are in a very light color. The trick is to add a number of surplus colors and subset to 64 colors.

heatmap(m, Colv=NA, Rowv=NA,
        xlab="", ylab="Irradiance", 
        main="Snapshot 1200 day 160", 
        col=heat.colors(64+6)[1:64], scale="none")

enter image description here


m <- structure(c(560.5681, 556.7537, 570.1362, 564.1036, 606.317, 
555.8331, 790.483, 790.483, 790.483, 790.483, 526.3265, 525.3711, 
534.5701, 538.4911, 583.7723, 576.4716, 790.483, 790.483, 790.483, 
790.483, 501.4808, 460.2989, 461.2309, 593.1357, 536.8325, 642.0229, 
790.483, 790.483, 790.483, 790.483, 447.4124, 412.7424, 476.0936, 
573.0606, 614.4326, 617.1337, 790.483, 790.483, 790.483, 790.483, 
475.3496, 478.107, 509.148, 532.7869, 514.1198, 620.3885, 790.483, 
790.483, 790.483, 790.483, 487.1298, 506.8339, 491.3332, 496.5737, 
427.6375, 483.4476, 790.483, 790.483, 790.483, 790.483), .Dim = c(10L, 
6L))
Related