読者です 読者をやめる 読者になる 読者になる

廿TT

譬如水怙牛過窓櫺 頭角四蹄都過了 因甚麼尾巴過不得

image 関数で行列を可視化(ヒートマップ、色付きテーブル)

R

マイブーム

最近ぼくのなかでヒートマップ(色付きテーブル)が再評価されている。

人間の目は色を量的に把握することができないので、折れ線グラフや棒グラフで済む場合はそちらのほうが優れていると思っている。

図示の目的を「探索」、「説明」の2つに分けるとするとヒートマップは以下のようなメリットがあると考えた。

  1. 探索:データの傾向を試行錯誤で探る。ヒートマップはいわばヒストグラムの2次元版として使うことができ、データ解析のインフォーマルな段階で便利。
  2. 説明:データの傾向を分かりやすく伝える。ヒートマップは見た目がきれいなので、プレゼン資料とかに貼り付けるのに便利。

image 関数について

今回は image 関数を使って色付きテーブルをつくる。

ggplot で書いたやつの例は

などを参照。

デフォルトで入ってる graphics の image 関数は行列(matrix)オブジェクトを視覚化してくれる。でもたぶんぱっと見だと挙動がわかりにくいと思う。

下記のような行列を image に入力すると下図のようになる。

#行列を生成#
mat1 <- diag(rep(1,9))
mat1[1,2] <- 2
mat1[2,9] <- 2
mat1 <- mat1[,-1]
#この行列に特に意味はない
image(mat1) #描画

f:id:abrahamcow:20140904152016p:plain

これは図のいちばん左下が行列の (1,1) 成分、その右隣が (2,1) 成分……という順番で対応している。

> mat1
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
 [1,]    2    0    0    0    0    0    0    0
 [2,]    1    0    0    0    0    0    0    2
 [3,]    0    1    0    0    0    0    0    0
 [4,]    0    0    1    0    0    0    0    0
 [5,]    0    0    0    1    0    0    0    0
 [6,]    0    0    0    0    1    0    0    0
 [7,]    0    0    0    0    0    1    0    0
 [8,]    0    0    0    0    0    0    1    0
 [9,]    0    0    0    0    0    0    0    1
text(expand.grid(seq(0,1,length=dim(mat1)[1]),seq(0,1,length=dim(mat1)[2])),
     labels=c(mat1))

なので行列の見た目と一致させるにはこういう変換をかませてやるといいと思う。

#行の上下を順番に入れ替えて転置をとる
#つまり行列を90°回転
mat4img <- function(mat1){
  t(apply(mat1,2,rev))
}

色の塗り分けはデフォルトだと heat.colors(12) を使っている。
heat.colors の色は以下を参照してほしい。

plot(NULL, xlim=c(0,12), ylim=c(0,1),xlab="", ylab="")
rect(0:11, 0, 1:12, 1, col= heat.colors(12))

f:id:abrahamcow:20140904161805p:plain
小さい数字が濃い赤、大きい数字が薄い赤。


RColorBrewer というパッケージではより見やすいカラーパレットが用意されている。「より見やすい」というのは好みの問題かもしれないが、おもいっきり原色がばんばん出てくるグラフは目がチカチカする気がするので避けたい。

出来上がり

こんな風だ。

library(RColorBrewer)
mat2 <- mat4img(mat1)
image(mat2, axes=FALSE, col=brewer.pal(8, "Blues"))
text(expand.grid(seq(0,1,length=dim(mat2)[1]),seq(0,1,length=dim(mat2)[2])),
     labels=c(mat2),col="white")

f:id:abrahamcow:20140904162254p:plain

修正(9月5日)

行列の変換のところ、最初はこうしてたけど書きかえました。

mat4img <- function(mat1){
  dim1 <- dim(mat1)
  mat2 <- matrix(0,dim1[1],dim1[2])
  for(i in 1:dim1[1]){
    j <- dim1[1]:1 
    mat2[j[i],] <- mat1[i,]
  }
  return(t(mat2))
}

関連エントリ

abrahamcow.hatenablog.com