热图中x轴上的对角线标注方向

问题描述 投票:25回答:6

在R中创建热图已成为许多帖子,讨论和迭代的主题。我的主要问题是结合格子levelplot()或基本图形image()中可用解决方案的视觉灵活性,基本的heatmap(),pheatmap的pheatmap()或gplots'heatmap.2()的轻松聚类是很棘手的。这是我想要改变的一个小细节 - x轴上标签的对角线方向。让我告诉你我在代码中的观点。

#example data
d <- matrix(rnorm(25), 5, 5)
colnames(d) = paste("bip", 1:5, sep = "")
rownames(d) = paste("blob", 1:5, sep = "")

您可以使用levelplot()轻松地将方向更改为对角线:

require(lattice)
levelplot(d, scale=list(x=list(rot=45)))

但应用聚类似乎很痛苦。其他视觉选项也是如此,例如在热图单元格周围添加边框。

现在,转移到实际的heatmap()相关功能,聚类和所有基本视觉效果都非常简单 - 几乎不需要调整:

heatmap(d)

所以在这里:

require(gplots)
heatmap.2(d, key=F)

最后,我最喜欢的一个:

require(pheatmap)
pheatmap(d) 

但所有这些都无法旋转标签。 pheatmap手册表明我可以使用grid.text来定制我的标签。真是太高兴 - 尤其是在聚类和更改显示标签的顺序时。除非我在这里遗漏了什么......

最后,有一个古老的好image()。我可以旋转标签,一般来说它是最可定制的解决方案,但没有聚类选项。

image(1:nrow(d),1:ncol(d), d, axes=F, ylab="", xlab="")
text(1:ncol(d), 0, srt = 45, labels = rownames(d), xpd = TRUE)
axis(1, label=F)
axis(2, 1:nrow(d), colnames(d), las=1)

那么我该怎么做才能获得理想的,快速的热图,具有聚类和定位以及良好的视觉功能黑客攻击?我最好的出价是以某种方式改变heatmap()pheatmap(),因为这两者似乎是调整中最通用的。但欢迎任何解决方案。

r label data-visualization heatmap lattice
6个回答
19
投票

要修复pheatmap,你真正想做的就是进入pheatmap:::draw_colnames并在调用grid.text()时调整几个设置。这是使用assignInNamespace()做到这一点的一种方法。 (它可能需要额外的调整,但你得到了图片;):

library(grid)     ## Need to attach (and not just load) grid package
library(pheatmap)

## Your data
d <- matrix(rnorm(25), 5, 5)
colnames(d) = paste("bip", 1:5, sep = "")
rownames(d) = paste("blob", 1:5, sep = "")

## Edit body of pheatmap:::draw_colnames, customizing it to your liking
draw_colnames_45 <- function (coln, ...) {
    m = length(coln)
    x = (1:m)/m - 1/2/m
    grid.text(coln, x = x, y = unit(0.96, "npc"), vjust = .5, 
        hjust = 1, rot = 45, gp = gpar(...)) ## Was 'hjust=0' and 'rot=270'
}

## For pheatmap_1.0.8 and later:
draw_colnames_45 <- function (coln, gaps, ...) {
    coord = pheatmap:::find_coordinates(length(coln), gaps)
    x = coord$coord - 0.5 * coord$size
    res = textGrob(coln, x = x, y = unit(1, "npc") - unit(3,"bigpts"), vjust = 0.5, hjust = 1, rot = 45, gp = gpar(...))
    return(res)}

## 'Overwrite' default draw_colnames with your own version 
assignInNamespace(x="draw_colnames", value="draw_colnames_45",
ns=asNamespace("pheatmap"))

## Try it out
pheatmap(d)

enter image description here


8
投票

它比我的评论稍微复杂一点,因为heatmap打破绘图区域以绘制树形图,最后的绘图区域不是你要附加标签的image图。

有一个解决方案,因为heatmap提供了add.expr参数,该参数在绘制image时对表达式进行评估。人们还需要知道由于树状图排序而发生的标签的重新排序。最后一点涉及一些不优雅的黑客攻击,因为我将首先绘制热图以获取重新排序信息,然后使用它来正确地绘制热像图。

首先来自?heatmap的一个例子

 x  <- as.matrix(mtcars)
 rc <- rainbow(nrow(x), start = 0, end = .3)
 cc <- rainbow(ncol(x), start = 0, end = .3)
 hv <- heatmap(x, col = cm.colors(256), scale = "column",
               RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
               xlab = "specification variables", ylab =  "Car Models",
               main = "heatmap(<Mtcars data>, ..., scale = \"column\")")

在这个阶段,标签不是我们想要它们的方式,但hv包含我们需要重新排序colnamesmtcars组件$colInd所需的信息:

> hv$colInd
 [1]  2  9  8 11  6  5 10  7  1  4  3

你使用这个就像order的输出一样:

> colnames(mtcars)[hv$colInd]
 [1] "cyl"  "am"   "vs"   "carb" "wt"   "drat" "gear" "qsec" "mpg"  "hp"  
[11] "disp"

现在使用它以正确的顺序生成我们想要的标签:

 labs <- colnames(mtcars)[hv$colInd]

然后我们重新调用heatmap,但这次我们指定labCol = ""来抑制列变量的标记(使用零长度字符串)。我们还使用text调用以所需的角度绘制标签。对text的呼吁是:

text(x = seq_along(labs), y = -0.2, srt = 45, labels = labs, xpd = TRUE)

这基本上就是你在问题中所拥有的。使用y的值进行播放,因为您需要将其调整为字符串的长度,以使标签不与image图重叠。我们指定labels = labs以所需的顺序传递我们想要的标签。整个text呼叫被传递给add.expr未引用。这是整个电话:

 hv <- heatmap(x, col = cm.colors(256), scale = "column",
               RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
               xlab = "specification variables", ylab =  "Car Models",
               labCol = "",
               main = "heatmap(<Mtcars data>, ..., scale = \"column\")",
               add.expr = text(x = seq_along(labs), y = -0.2, srt = 45,
                               labels = labs, xpd = TRUE))

结果如下:


6
投票

我也在寻找用热图旋转标签文字的方法。最终我设法找到了这个解决方案:

library(gplots)

library(RColorBrewer)

heatmap.2(x,col=rev(brewer.pal(11,"Spectral")),cexRow=1,cexCol=1,margins=c(12,8),trace="none",srtCol=45)

关键参数是srtCol(or srtRow for row labels),用于在gplots中旋转列标签。


5
投票

使用lattice::levelplotlatticeExtra::dendrogramGrob的解决方案:

library(lattice)
library(latticeExtra)

示例数据:

d <- matrix(rnorm(25), 5, 5)
colnames(d) = paste("bip", 1:5, sep = "")
rownames(d) = paste("blob", 1:5, sep = "")

您必须定义行和列的树形图(在heatmap内部计算):

dd.row <- as.dendrogram(hclust(dist(d)))
row.ord <- order.dendrogram(dd.row)

dd.col <- as.dendrogram(hclust(dist(t(d))))
col.ord <- order.dendrogram(dd.col)

并将它们传递给dendrogramGroblegend论证中的levelplot函数。

我用RColorBrewer的颜色定义了一个新主题,并用borderborder.lwd修改了单元格边框的宽度和颜色:

myTheme <- custom.theme(region=brewer.pal(n=11, 'RdBu'))

levelplot(d[row.ord, col.ord],
          aspect = "fill", xlab='', ylab='',
          scales = list(x = list(rot = 45)),
          colorkey = list(space = "bottom"),
          par.settings=myTheme,
          border='black', border.lwd=.6,
          legend =
          list(right =
               list(fun = dendrogramGrob,
                    args =
                    list(x = dd.col, ord = col.ord,
                         side = "right",
                         size = 10)),
               top =
               list(fun = dendrogramGrob,
                    args =
                    list(x = dd.row,
                         side = "top"))))

您甚至可以使用shrink参数来缩放与其值成比例的单元格大小。

levelplot(d[row.ord, col.ord],
          aspect = "fill", xlab='', ylab='',
          scales = list(x = list(rot = 45)),
          colorkey = list(space = "bottom"),
          par.settings=myTheme,
          border='black', border.lwd=.6,
          shrink=c(.75, .95),
          legend =
          list(right =
               list(fun = dendrogramGrob,
                    args =
                    list(x = dd.col, ord = col.ord,
                         side = "right",
                         size = 10)),
               top =
               list(fun = dendrogramGrob,
                    args =
                    list(x = dd.row,
                         side = "top"))))


3
投票

最新版本的pheatmap(1.0.12)released on 2019-01-04angle_col论证支持这一点。

#example data
d <- matrix(rnorm(25), 5, 5)
colnames(d) = paste("bip", 1:5, sep = "")
rownames(d) = paste("blob", 1:5, sep = "")

#update to latest version on CRAN
install.packages("pheatmap")
library("pheatmap")
pheatmap(d, angle_col = 45)

pretty heatmap with angled column labels

我在GitHub上创建了一个包,其中包含heatmap.2函数的改进版本。这支持调整轴标签,包括传递给srtCol函数的axis参数。它可以从:https://github.com/TomKellyGenetics/heatmap.2x安装

library("devtools")
install_github("TomKellyGenetics/heatmap.2x")
library("heatmap.2x")

heatmap.2x(d, scale = "none", trace = "none", col = heat.colors, srtCol = 45)

enhanced heatmap.2x with angled column labels

version 2.12.1gplots开始,heatmap.2函数也支持srtCol论证。

library("gplots")
heatmap.2(d, scale = "none", trace = "none", srtCol = 45)

heatmap.2 with angled column labels


2
投票

我能够接受Gavin Simpson的回答并将其修剪下来以便为我的简单原型设计工作,其中data1是read.csv()对象,而data1_matrix当然是由此生成的矩阵

heatmap(data_matrix, Rowv=NA, Colv=NA, col=heat.colors(64), scale='column', margins=c(5,10),
   labCol="", add.expr = text(x = seq_along(colnames(data1)), y=-0.2, srt=45, 
   labels=colnames(data1), xpd=TRUE))

繁荣!谢谢加文。

这个工作的关键是在add.expr位之前的部分,他将labCol设置为“”,这是防止前(直下)标签与新的45度标签重叠的必要条件。

© www.soinside.com 2019 - 2024. All rights reserved.