2016-04-25 659 views
2

当我使用pheatmap创建值的热图,愿与矩阵中的Z值单位标注图例单位。在这个例子中,我希望图例顶部的温度[°C]。我已经阅读了pheatmap的guidelines here,看起来图例的唯一操作是添加一个默认数字列表来代替缩放比例。我看不到任何添加图例标题的选项。的R - 图例标题或使用Pheatmap

这里是代码的通用块使用pheatmap以生成矩阵和情节。我真的很感激任何关于如何给图例添加标题的建议。

test <- matrix(rexp(200, rate=.1), ncol=20) 
colnames(test) = paste("Room", 1:20, sep = "") 
rownames(test) = paste("Building", 1:10, sep = "") 

pheatmap(test, legend = TRUE, cluster_rows = FALSE, cluster_cols = FALSE) 

enter image description here

回答

5

OK等等,因为有人还没有回答这个问题,我给你一个可能的选项,如果你绝对必须使用pheatmap功能。使用 ggplot可以简单得多,不过这里有:

首先,我们要生成我们的绘图,以便我们可以使用所有绘图对象创建我们自己的绘图,并带有编辑的图例。

#Edited to add in library names 
library(gtable) 
library(grid) 

#Starting with data and generating initial plot 
test <- matrix(rexp(200, rate=.1), ncol=20) 
colnames(test) = paste("Room", 1:20, sep = "") 
rownames(test) = paste("Building", 1:10, sep = "") 

p<-pheatmap(test, legend = TRUE, cluster_rows = FALSE, cluster_cols = FALSE) 



#Get grobs we want - will use these to create own plot later 
plot.grob <- p$gtable$grob[[1]] 
xlab.grob <- p$gtable$grob[[2]] 
ylab.grob <- p$gtable$grob[[3]] 
legend.grob <- p$gtable$grob[[4]] 

现在,一旦我们有了我们的对象,我们实际上希望稍微改变这个图例来为标题留出空间。

#Shift both down by 1 inch 
legend.grob$children[[1]]$y <- legend.grob$children[[1]]$y - unit(0.85,"inches") 
legend.grob$children[[2]]$y <- legend.grob$children[[2]]$y - unit(0.85,"inches") 
legend.grob$children[[1]]$x <- legend.grob$children[[1]]$x + unit(0.4,"inches") 
legend.grob$children[[2]]$x <- legend.grob$children[[2]]$x + unit(0.4,"inches") 

既然我们已经取得空间的传说,现在我们可以创造传奇textGrob,并把它添加到传说grobTree(只是我们希望我们的传说是设置图形对象的)

#New legend label grob 
leg_label <- textGrob("Temperature [°C]",x=0,y=0.9,hjust=0,vjust=0,gp=gpar(fontsize=10,fontface="bold")) 

#Add label to legend grob 
legend.grob2 <- addGrob(legend.grob,leg_label) 

如果你想看看我们的传说将是什么样子的尝试:

grid.draw(legend.grob2) 

现在我们确实需要建立我们gtable对象。为此,我们将使用与pheatmap函数生成的图相似的布局(进行一些修改)。还要注意的是,pheatmap函数生成可接一个gtable对象:

p$gtable 

为了看到宽度/每个在我们gtable对象所有我们需要做的“部门”的高度是:

p$gtable$heights 
p$gtable$widths 

这将作为我们的参考值。对于更多的图形显示尝试:

gtable_show_layout(p$gtable) 

其中产量这一形象:

enter image description here

好了,现在我们有我们想要的grobs,我们需要做的是建立我们的gtable基于就我们看到的pheatmap构建的gtable而言。我已经写了一些示例代码:

my_new_gt <- gtable(widths= unit.c(unit(0,"bigpts") + unit(5,"bigpts"), 
            unit(0,"bigpts"), 
            unit(1,"npc") - unit(1,"grobwidth",plot.grob) + unit(10,"bigpts") - max(unit(1.1,"grobwidth",plot.grob), (unit(12,"bigpts")+1.2*unit(1.1,"grobwidth",plot.grob))) + unit(5,"bigpts") - unit(3,"inches"), 
            unit(1,"grobwidth",ylab.grob) + unit(10,"bigpts"), 
            max(unit(1,"grobwidth",legend.grob2),unit(12,"bigpts")+1.2*unit(1.1,"grobwidth",legend.grob2)) + unit(1,"inches") , 
            max(unit(0,"bigpts"),unit(0,"bigpts")) 
            ), 



        height = unit.c(unit(0,"npc"), 
            unit(5,"bigpts"), 
            unit(0,"bigpts"), 
            unit(1,"npc") - unit(1,"grobheight",xlab.grob) + unit(15,"bigpts") - unit(0.2,"inches"), 
            unit(1,"grobheight",xlab.grob) + unit(15,"bigpts")  
        )) 

最后,我们可以把我们的所有对象添加到我们的新gtable得到一个非常类似的情节由pheatmap与添加图例标题所产生的一个。

#Adding each grob to the appropriate spot 
gtable <- gtable_add_grob(my_new_gt,plot.grob,4,3) 
gtable <- gtable_add_grob(gtable,xlab.grob,5,3) 
gtable <- gtable_add_grob(gtable,ylab.grob,4,4) 
gtable <- gtable_add_grob(gtable,legend.grob2,4,5) 

grid.draw(gtable) 

最后生成的输出是:

enter image description here

希望这有助于。你可以调整不同的大小来尝试使布局更具动态性,但我认为这是一个很好的设置,并且可以得到你想要的 - 带有图例的pheatmap。

编辑 - ggplot选项:

由于我推荐ggplot这里的替代是一些代码来完成它:

library(ggplot2) 
library(reshape) 
test <- as.data.frame(matrix(rexp(200, rate=.1), ncol=20)) 
colnames(test) = paste("Room", 1:20, sep = "") 
test$building = paste("Building", 1:10, sep = "") 

#Get the sorting right 
test$sort <- 1:10 

#Melting data so we can plot it with GGplot 
test.m <- melt(test,id.vars = c("building","sort")) 

#Resetting factors 
test.m$building <- factor(test.m$building, levels=(test.m$building)[order(test.m$sort)]) 

#Creating the plot itself 
plot <- ggplot(test.m,aes(variable,building)) + geom_tile(aes(fill=value),color = "white") + 
     #Creating legend 
     guides(fill=guide_colorbar("Temperature [°C]")) + 
     #Creating color range 
     scale_fill_gradientn(colors=c("skyblue","yellow","tomato"),guide="colorbar") + 
     #Rotating labels 
     theme(axis.text.x = element_text(angle = 270, hjust = 0,vjust=-0.05)) 
plot 

将会产生这样的情节:

enter image description here

由于你可以看到ggplot2方法快得多。你所要做的就是将你的数据转换为数据帧,然后将其融化。完成后,您可以轻松更改图例标题。

+0

对不起,我迟到的答复,但非常感谢你对这个惊人响应。你的回答非常详细,帮助我更好地理解pheatmap!我实际上是要问你ggplot和pheatmap之间的区别,但你已经回答了!我喜欢关于pheatmap的一件事是它可以通过将它们作为不同的颜色来处理NA值。这对我来说很有用,因为我正在处理具有一些NA值的数据集。虽然我还没有尝试使用ggplot。非常感谢。 – alkey

3

MikeyMike的答案令人难以置信;我通过阅读也学到了很多东西。

但是,我需要一个愚蠢的,丑陋的,10个第二个解决方案:

test <- matrix(rexp(200, rate=.1), ncol=20) 
colnames(test) = paste("Room", 1:20, sep = "") 
rownames(test) = paste("Building", 1:10, sep = "") 

pheatmap(test, legend_breaks = c(10, 20, 30, 40, max(test)), 
main = "", legend_labels = c("10", "20", "30", "40", "title\n"), 
legend = TRUE, cluster_rows = FALSE, cluster_cols = FALSE) 

将会产生这种热图:

enter image description here