[英]R - Legend title or units when using Pheatmap
我正在使用pheatmap创建值的热图,并希望使用矩阵中z值的单位标注图例。 在这个例子中,我希望图例的顶部说温度[°C]。 我已经阅读了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)
好吧,因为有人还没有回答这个问题,如果你绝对必须使用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)
这会产生这个图像:
好的,现在我们有了我们想要的grob,我们需要做的就是根据我们在pheatmap构建的gtable中看到的构建我们的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)
最后生成的输出是:
希望这有帮助。 您可以通过不同的大小调整来尝试使布局更加动态,但我认为这是一个很好的设置,可以获得您想要的 - 带有图例的pheatmap。
由于我推荐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
这产生了这个情节:
正如您所看到的,ggplot2方法要快得多。 您所要做的就是将数据转换为数据帧,然后将其融化。 完成后,您可以轻松更改图例标题。
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)
这产生了这个热图:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.