web-dev-qa-db-ja.com

ヒートマップのx軸の対角ラベルの向き

Rでヒートマップを作成することは、多くの投稿、議論、イテ​​レーションのトピックとなっています。私の主な問題は、lattict levelplot()または基本的なグラフィックスimage()で利用可能なソリューションの視覚的な柔軟性と、基本的なheatmap()、ピートマップの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)))
_

enter image description here

しかし、クラスタリングの適用は苦痛のようです。ヒートマップセルの周囲に境界線を追加するなど、他の視覚的なオプションも同様です。

これで、実際のheatmap()関連関数、クラスタリング、およびすべての基本的なビジュアルへの移行が非常に簡単になりました。ほとんど調整は必要ありません。

_heatmap(d)
_

enter image description here

そしてここにあります:

_require(gplots)
heatmap.2(d, key=F)
_

enter image description here

そして最後に、私の好きなもの:

_require(pheatmap)
pheatmap(d) 
_

enter image description here

しかし、それらすべてにラベルを回転させるオプションはありませんがあります。 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)
_

enter image description here

それで、クラスタリングと方向付け、そして素敵なビジュアル機能のハッキングを使用して、理想的なクイックヒートマップを取得するにはどうすればよいですか?私の最高の入札は、何とかheatmap()またはpheatmap()を変更することです。しかし、どんな解決策も歓迎します。

26
Geek On Acid

pheatmapを修正するには、_pheatmap:::draw_colnames_に移動して、grid.text()の呼び出しでいくつかの設定を調整するだけです。これを行う1つの方法は、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

19
Josh O'Brien

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))

その結果:

enter image description here

8
Gavin Simpson

ヒートマップでラベルテキストを回転させる方法も探しています。最終的に私はこの解決策を見つけることができました:

_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)で、これはgplotの列ラベルを回転させるために使用されます。

6
Yongsheng Cheng

lattice::levelplotおよびlatticeExtra::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"))))

levelplot with dendrogram

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"))))

levelplot with dendrogram and scaled cell sizes

5

pheatmap (1.0.12) 2019-01-04にリリース の最新バージョンは、angle_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

heatmap.2関数の改良版を含むパッケージをGitHubで作成しました。これは、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

バージョン2.12.1gplots 以降、heatmap.2関数はsrtCol引数もサポートします。

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

heatmap.2 with angled column labels

3
Tom Kelly

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))

ブーム!ギャビンに感謝します。

これが機能するための重要なビットは、彼がlabColを ""に設定したadd.exprビットの前の部分です。これは、以前の(真下の)ラベルが新しい45度のラベルと重ならないようにするために必要です。

2
boulder_ruby