ggplot2のヒートマップで中間値を任意に指定する
目的
ggplot2でヒートマップを作るときに中間値1を任意に指定したい。
最終的に記事下部のやり方その2に着地。
例
このプロットで0を青、1を黄色、2000を赤にする。
library(ggplot2) data <- faithfuld data$z <- faithfuld$density * 50000 ggplot(data, aes(waiting, eruptions, fill = z)) + geom_tile() + scale_fill_gradient2(low = "blue", mid = "yellow", high = "red")
プロット中にも凡例にも青が見えない。
失敗例
最初はmidpoint
とlimit
を設定してやればいいだろ......と思っていたのだが実際やってみると以下の通り。青が見えない。
ggplot(data, aes(waiting, eruptions, fill = z)) + geom_tile() + scale_fill_gradient2(low = "blue", mid = "yellow", high = "red", midpoint = 1, limits = c(0, 2000))
成功例
その1:values = rescale(c(最小値, 中間値, 最大値))
やり方その1。scale_fill_gradientn()
にvalues = rescale(c(最小値, 中間値, 最大値))
を設定する。
ggplot(data, aes(waiting, eruptions, fill = z)) + geom_tile() + scale_fill_gradientn(colours = c("blue", "yellow", "red"), values = rescale(c(0, 1, 2000)))
問題点
- 青の部分がべったりしているのが気になる(対処可能:やり方2参照)。
- legendに青が見えない。
その2:breaks/labels/limits = c(最小値, 中間値, 最大値)
やり方その2。scale_fill_gradientn()
のbreaks
・labels
・limits
にc(最小値, 中間値, 最大値)
を設定する。
ggplot(data, aes(waiting, eruptions, fill = z)) + geom_tile() + scale_fill_gradientn(colours = c("blue", "yellow", "red"), na.value = "blue", breaks = c(1 / 2000, 1, 2000), labels = c(0, 1, 2000), limits = c(1 / 2000, 2000), trans = "log")
今回は1をlegendの中央に持ってくるためにtrans = "log"
を設定しているので最小値を1/2000
にしているが、log変換しないのならば最小値は0
でいい。
na.value = "最小値の色"
の指定もlog変換しないなら不要。データ中にNAが存在する場合は、na.value
を指定する代わりにプロット前に最小値未満の値を最小値に置換しておく。
legendに青が見えるようになり、値が分かりやすくなった。
問題点?
- やはり青がべったりしている。
colours
とbreaks
の指定を増やすことで対処できるはず(試していない)だが今回は面倒くさいのでそこまでしていない。 - legendの0の横が凹んでいる(分かりづらいだけで実は1の横も凹んでいる)。
guide_colorbar()
のticks
まわりの設定で対処可能のはず(試していない)。
以上。
-
中央値ではない ↩