Как назначить цветовую шкалу для сырых данных в тепловой карте .2()

У меня есть данные, которые выглядят так:

                         Name    h1    h2    h3    h4    h5
1            1420468_at_Asb17 0.000 2.328 0.000 0.000 0.000
2    1430261_at_1700024J04Rik 1.236 2.050 0.000 0.000 0.000
3           1431788_at_Fabp12 0.000 2.150 0.000 0.000 0.587
4    1433187_at_B230112I24Rik 0.000 2.240 1.343 0.000 1.383
5        1434430_s_at_Adora2b 0.000 2.006 1.459 0.000 1.272
6           1435217_at_Gm7969 0.727 2.350 1.494 0.976 0.000
7          1436717_x_at_Hbb-y 0.000 2.712 0.000 0.000 0.000
8            1440859_at_Akap6 0.000 2.053 0.000 0.000 1.840
9              1442625_at_--- 0.000 2.064 1.173 0.000 1.035
10           1443715_at_Rbm24 0.969 2.219 0.000 0.000 0.000
11             1445520_at_--- 0.000 2.497 0.000 0.000 0.000
12          1446035_at_Gm7173 0.000 3.869 0.000 0.000 0.000
13   1446597_at_6820445E23Rik 1.000 2.000 0.000 0.000 0.000
14          1448925_at_Twist2 0.000 2.089 0.938 0.000 0.000
15        1449711_at_Atp6v1e1 0.605 2.363 2.350 1.094 0.976
16          1455931_at_Chrna3 0.000 2.354 0.000 0.000 0.000
17 1457647_x_at_1600023N17Rik 0.000 2.734 0.000 0.000 1.812
18             1458975_at_--- 0.000 2.079 0.000 0.000 0.000
19             1459862_at_--- 0.727 2.606 0.000 0.000 1.151

Примечание в этих данных (и фактическом) нет отрицательных значений, а положительные значения может достигать 100 или около того.

Что я хочу сделать, так это составить график тепла с моей собственной назначенной цветовой шкалой и схемой:

  • Когда значение равно 0, установите его в белый цвет.
  • Когда значение равно == 1, установите его в черный цвет.
  • Когда значение > 1, установите его в оттенок красного.
  • Когда значение равно < 1 и > 0 установите его в оттенок зелень.

также без использования какого-либо масштабирования данных или встроенного преобразования z-score. Как я могу это достичь?

Мой текущий код:

library(gplots)

# Read data
dat <- read.table("http://dpaste.com/1501148/plain/",sep="\t",header=T);
rownames(dat) <- dat$Name
dat <- dat[,!names(dat) %in% c("Name")]

# Clustering and distance measure functions
hclustfunc <- function(x) hclust(x, method="complete")
distfunc <- function(x) dist(x,method="maximum")

#  Define colours
hmcols <- rev(redgreen(2750));

# Plot 
pdf("~/Desktop/tmp.pdf",height=10)
heatmap.2(as.matrix(dat),Colv=FALSE,dendrogram="row",scale="row",col=hmcols,trace="none", margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0),keysize=1);
dev.off()

Создает следующий график, в котором используется масштабирование строк по умолчанию z-score.

enter image description here

Ответ 1

Ключевым моментом здесь является понимание того, что heatmap.2 использует аргумент col в сочетании с аргументом breaks.

Взгляните на код и рисунок ниже, чтобы понять, что я имею в виду.

library(gplots)
set.seed(100)
dat = matrix( rexp(25,1/2), ncol=5 )
breaks = 0:5
col = c("green","blue","red","yellow","brown")
heatmap.2( dat, breaks=breaks, col=col )

enter image description here

Как вы можете видеть, для n breaks должно быть n-1 цветов. Для вашего конкретного вопроса проблема заключается в отображении правильных цветов в перерывы. Я использую параметр scale="none", как указал @josilber.

breaks = seq(0,max(dat),length.out=1000)
gradient1 = colorpanel( sum( breaks[-1]<=1 ), "white", "green", "black" )
gradient2 = colorpanel( sum( breaks[-1]>1 ), "black", "red" )
hm.colors = c(gradient1,gradient2)

heatmap.2(as.matrix(dat),scale="none",breaks=breaks,col=hm.colors,
          Colv=FALSE,dendrogram="row",trace="none", 
          margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0))

enter image description here

Другой альтернативой было бы иметь два градиента: зеленый - черный и черный - красный. Затем вы можете вручную установить нулевые значения в белый цвет, сделав их NA и установив na.color="white".

breaks = seq(0,max(dat),length.out=1000)
gradient1 = colorpanel( sum( breaks[-1]<=1 ), "green", "black" )
gradient2 = colorpanel( sum( breaks[-1]>1 ), "black", "red" )
hm.colors = c(gradient1,gradient2)

dat[dat==0] = NA
heatmap.2(as.matrix(dat),scale="none",breaks=breaks,col=hm.colors,na.color="white",
          Colv=FALSE,dendrogram="row",trace="none", 
          margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0))

И, наконец, вы можете просто вручную отредактировать градиент для нулевых значений.

breaks = seq(0,max(dat),length.out=1000)
gradient1 = colorpanel( sum( breaks[-1]<=1 ), "green", "black" )
gradient2 = colorpanel( sum( breaks[-1]>1 ), "black", "red" )
hm.colors = c(gradient1,gradient2)
hm.colors[1] = col2hex("white")

heatmap.2(as.matrix(dat),scale="none",breaks=breaks,col=hm.colors,na.color="white",
          Colv=FALSE,dendrogram="row",trace="none", 
          margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0))

enter image description here

Изменения сбрасывания журнала

В другой заметке, похоже, вы можете смотреть на изменения смены или некоторый тип отношения. При составлении карты тепла довольно часто приходится записывать изменения логарифма. Я "серил" нулевые значения.

dat[dat==0] = NA
heatmap.2( as.matrix(log2(dat)), col=greenred(100), 
           scale="none", na.color="grey",symbreaks=TRUE,
           Colv=FALSE,dendrogram="row",trace="none", 
           margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0))

enter image description here

Для объяснения приятного решения @josilber:

Этот код hmcols <- c(colfunc1(200), colfunc2(200*(max(dat) - 1))) делает символьный вектор длины 774 (видно на length(hmcols)). Таким образом, это означает, что должно быть определено 775 разрывов. Функция heatmap.2 по умолчанию делает n+1 разрывы, где n - длина вектора, используемого в аргументе col. Таким образом, количество разрывов и цветов выработано, но как hmcols <- c(colfunc1(200), colfunc2(200*(max(dat) - 1))) правильно отображает цвета в разрывы? Фокус в том, что был создан вектор hmcols. Количество цветов в первом градиенте равно 200. Поскольку breaks не было явно определено, мы знаем, что разрывы будут равномерно распределены. Так как первый градиент идет от 0 до 1, а 200 разрывов, ширина каждого разрыва должна быть 0,005 (или 1/200). Поскольку второй градиент идет от 1 до 3.869 (max(dat)), должно быть 2,869/0,005 = 573,8 разрывов (574 разрывов при округлении). Обратите внимание, что 200*(max(dat) - 1)) выполняет этот расчет; он выводит 573.8. Таким образом, тогда 200 + 574 цветов отображаются на правильные перерывы, и все работает!

Ответ 2

Я думаю, здесь есть две вещи. Во-первых, как избавиться от z-баллов. Это можно сделать с параметром scale="none" до heatmap.2.

Другой вопрос окружает ваш желаемый градиент. Я полагался на colorRampPalette для этой части. Ниже я построю градиент, который становится белым → зеленый → черный для значений от 0 до 1, а затем черный → красный для значений 1 → max(dat).

library(gplots)

# Read data
dat <- read.table("http://dpaste.com/1501148/plain/",sep="\t",header=T);
rownames(dat) <- dat$Name
dat <- dat[,!names(dat) %in% c("Name")]

# Clustering and distance measure functions
hclustfunc <- function(x) hclust(x, method="complete")
distfunc <- function(x) dist(x,method="maximum")

#  Define colours
colfunc1 <- colorRampPalette(c("white", "green", "black"))
colfunc2 <- colorRampPalette(c("black", "red"))
hmcols <- c(colfunc1(200), colfunc2(200*(max(dat) - 1)))

# Plot 
pdf("~/Desktop/tmp.pdf",height=10)
heatmap.2(as.matrix(dat),Colv=FALSE,dendrogram="row",scale="none",col=hmcols,trace="none", margin=c(5,10), hclust=hclustfunc,distfun=distfunc,lwid=c(1.5,2.0),keysize=1);
dev.off()

enter image description here

Ответ 3

Основная тема здесь - определить разрывы и конкретные цвета для каждого перерыва. Этого можно добиться с помощью функции heatmap.2.

library(gplots)
library(RColorBrewer)

#Table formatting 
rownames(df)<-df[,1] #setting row names
df<-as.matrix(df[,-1])

# Defining breaks for the color scale!
##defining color scale

myCol <- c("white",colorRampPalette(c("green","darkgreen"))(100),"black",colorRampPalette(c("red","darkred"))    (100)) 
#you can change the colors here. 
#It is important to have the total number of colors defined for all the breaks. 
#i.e if the number of breaks is 100, then there should be 99 colors defined.
#You can change the gradient of the shades by changing no of splots, 
#I have used 100 here

##defining breaks
myBreaks <- c(-1,0,seq(1e-5,1-1e-5,length=100),1,seq(1+1e-3,200,length=100)) 

#set your break start/end and the length here
# I have set it as per your requirements here. Teh shades

#Plotting heatmap 

pdf("temporal_data.pdf",width=8,height=8)
hm <- heatmap.2(df, scale="none", Colv=NA,
                col = myCol, ## using your colors
                breaks = myBreaks, ## using your breaks
                dendrogram = "row",  ## row dendograms
                , cexRow=1, cexCol=1, key=FALSE,
                margins = c(2, 12),trace="none")
legend("topleft", fill = c("white","green","black","red"),
       legend = c("0", "0.0001 to 0.999", "1",">1"),cex=1,horiz =TRUE)
dev.off()