Tokyo.Rでの@berobero11さんの発表を見てて、この等高線どう描くんだろうなあ、とかつぶやいてたら、
こんなすてきなリプが飛んできました!!!
@yutannihilation ユタ兄さん、懇親会で聞かれた等高線の描き方をアップしました。ご参考までに。
http://t.co/qsiwTvfUa0
— berobero (@berobero11) 2015, 2月 23
そのお礼といってはおこがましいですが、等高線にラベルを付ける方法を模索してみました。
directlabelsを使う
意外と知られてない気がしますが、directlabelsというパッケージがあります。これを使うと、ggplot2のグラフに直接ラベルを書き入れることができます。
ちょっと使ってみます。
(beroberoさんのコードを、ggsave(p, file='demo_contour_diff.png', dpi=300, w=6, h=5)の直前まで実行) directlabels::direct.label(p) #> Error in direct.label.ggplot(p) : #> Need colour aesthetic to infer default direct labels.
むむ。なんかエラーが出ました。aesにcolour
を指定していないとだめ、と出てますが、どうやらコードを読んだ感じgeom_contour
には対応してないみたいです。(こういうとこで気が利かないのがdirectlabels
がイケてないなと感じるところです。。)
追記:
aes(colour = ..level..)
を付け加えればいけるみたいでした。
ggplot2 - R: How to Label Specific Contours using direct.label - Stack Overflow
自前で頑張る
仕方ないから自分で頑張ります。
ggplot2のコードを読むと、geom_contour()
は内部ではcontour_lines
という関数を使ってるみたいです。
よく分かりませんが、関数の上にサンプルコードがついてるので実行してみます。contour_lines
はエクスポートされてない関数なので:::
(コロン3つ)で呼び出します。
v3d <- reshape2::melt(volcano) names(v3d) <- c("x", "y", "z") breaks <- seq(95, 195, length = 10) contours <- ggplot2:::contour_lines(v3d, breaks) qplot(x, y, data = contours, geom = "path") + facet_wrap(~ piece)
なんかよくわかりませんが、contour_lines
は、等高線のレベルごとに分かれたdata.frame
的なものを返してくれるみたいです。ということは、各レベルから適当に一点取ってきてgeom_text()
を使えばラベルつけれる?と思って試してみたら↓のような感じになりました。
# contour_linesに渡すのは必ずx, y, zじゃないとむり d.label <- select(d.cont, x, y, z = z.diff) # geom_contour()はbinsかbinwidthを指定しないとデフォルトで10が使われます。なのでここも10の区間に分割しています。 contours <- ggplot2:::contour_lines(d.label, pretty(range(d.label$z), 10)) # それぞれのレベルの真ん中にある点をラベルの座標として使う contour_labels <- contours %>% mutate(label = round(level, digits = 1)) %>% group_by(label) %>% summarise(x = nth(x, round(n()/2)), y = nth(y, round(n()/2))) p <- p + geom_text(data = contour_labels, aes(x, y, label = label), size = 4) ggsave(p, file='demo_contour_diff_with_label.png', dpi=300, w=6, h=5)
ラベルつきました!
今後の課題
今回はうまくいきましたが、等高線のあいだがせまいときだとラベルがかぶったりする予感です。その辺をうまいことやるにはもうちょっと工夫が必要そうです。
あと、まだちょっと見にくいので、文字に白でアウトラインをつけたいんですが、いいやり方が見つかりません。これ↓はなんか無理やりやってますが、もっとスマートにやる方法ないのかな。。
r - Outlined text with ggplot2 - Stack Overflow
究極的にはgeom_contourlabel()
みたいなのをつくりたいんですが、公式のGeomの作り方を見ても今の私のレベルではさっぱり分からないので、とりあえず断念しました。時間があるとき探求したいところではあります。