ggplot2の等高線にラベルをつけるパッケージをつくってみました(注:今のggplot2では動きません)

前にこんな記事を書きましたが、パッケージにしようしようと思いつつ大変そうなので放置してました。

notchained.hatenablog.com

が、風の噂で次期バージョン(1.1.0)のggplot2から新しいgeomとかstatをつくるのが簡単になると聞いたのでつくってみました。

レポジトリ

github.com

使い方

単純明快です。geom_labeled_contour()+するだけです。

library(gglabeledcontour)

v3d <- reshape2::melt(volcano)
ggplot(v3d, aes(Var1, Var2, z = value)) +
  geom_labeled_contour()

ただ、タイトルに書いたように、これは今のCRANにあるggplot2のバージョンでは動きません。開発中のバージョンが必要なので、install_github("hadley/ggplot2")する必要があります。

ggprotoの使い方

を書こうと思ったんですけど、詳しくはめんどくさいので今回は触りだけ書いておきます。すみません。。

geom_contour()にラベルをつけるのは、geom_contour()の計算結果からいい感じの点を抜き出してきてそれをgeom_text()に渡せばオッケーです。

それを実装するのに、ggprotoはオブジェクト指向的にクラスを継承したりできるので、多少楽ができます。今回は、Stat(stat用のベースクラス)を継承しています。(ほんとはStatContourを継承してもよかったのかもしれない)

Statが最低限必要とするのはdefault_aesaesマッピング)とcompute_group()(データを変形・計算する関数)です。

compute_group()は、stat_contour()がやってる計算の結果を加工したいので、StatContourcompute_group()を呼び出して、その結果を加工しています。前はこういう他のstatとかgeomがやってる処理にアクセス方法が見つからなくて、stat_contour()が使っているエクスポートされていない関数(contour_lines())を:::でむりやり呼び出していました。それに比べればだいぶ楽になっています。

こんな感じです。

StatContourLabel <- ggplot2::ggproto(
  "StatContourLabel",

  ggplot2::Stat,

  default_aes = aes(label = ..level..),

  compute_group = function(..., digits = 3) {
    ggplot2::StatContour$compute_group(...) %>%
      dplyr::group_by(level) %>%
      dplyr::summarise(x = nth(x, round(n() / 2)),
                       y = nth(y, round(n() / 2))) %>%
      dplyr::mutate(level = signif(level, digits = digits))
  }
)

(人に説明できるほど理解できてない…)

参考

github.com

rud.is