niszetの日記

細かい情報を載せていくブログ

(R) ggplotにlimitsを指定しない時のrangeはどうやって取ってくる?

一旦計算してもらう方が良さそう。

先日のbode plotで、panel.grid.minor.xmissing(xlim)の時は表示されないという問題がありました。
対数軸のgrid.minorは自分で計算しないと(多分)表示されないし、始点と終点が中途半端な数字になっている場合、意図しないところにgridが出てくるためfloor()ceiling()で調整しました。

が、xlimを与えなくても適当に表示してほしいものです。その対応をしました。

どこにあるか

たとえばScaleオブジェクトのget_limits()関数1github.com

RangeContinuousオブジェクトのtrain()関数、 github.com

などはそれっぽい要素ですが、そもそも、ggplotオブジェクトはprint.ggplot()によって描画される直前に座標を含めた表示の調整・計算をしているので、これらのggprotoオブジェクトを追うよりはprint.ggplot()を追いかけた方が良いです。

実際、内部ではggplot_build.ggplot()という関数が呼ばれていて2、ここで処理がされています。 そこで、この関数単体を呼び出すことで、plot前の座標調整された状態の情報が得られるという寸法です。こちらのSOの投稿を参考にしました。

stackoverflow.com

ただ、データ構造がこの投稿当時と異なるようでして、私が欲しい情報は例えば変数gggplot()+geom_line()dataaes()が与えられているものが代入されているとして、ggplot2::ggplot_build(g)[["layout"]][["panel_ranges"]][[1]]$x.rangeによって得ることが出来ました。これ以外の情報も、例によってView()によって追いかけることが容易です3

ただ、前処理部とはいっても、このデータ処理分は全体として遅くなってしまうので注意が必要だと思うのと、このデータ構造はいつ変わるかわからないという点が不安ですね。
あまり内部構造に立ち入った形では使いたくないというのが正直なところです。

まぁ目的は達したので、よしよし。

Enjoy!!


  1. メソッドと呼ぶ方が適切かも。そういう意味だとScaleオブジェクトって呼び方で良いのか?という話もあるので…。

  2. 正確にはメソッドディスパッチがされているので直接呼ばれているのはggplot_build()ですが

  3. それもいずれ書こうかと思いますが、いつになるのかは不明。あくまでniszetさんがとても必要になったときにのみ日記に書いていくスタンスですので…。