ggplot2のgeom_pointのnpc座標


10

どのように私は得ることができますのxyの座標geom_pointggplot参照フレームが全体のプロットイメージですか、?

私はいくつかのgeom_pointを使ってggplotを作成できます:

library(ggplot2)

my.plot <- ggplot(data.frame(x = c(0, 0.456, 1), y = c(0, 0.123, 1))) +
             geom_point(aes(x, y), color = "red")

これは与える:

ここに画像の説明を入力してください

これをgrobに変換することにより、紫色の矢印でマークされた、プロットパネルに関する座標など、このggplotに関する追加情報を抽出できます。ただし、これは軸が占めるスペースを無視します。

my.grob <- ggplotGrob(my.plot)
my.grob$grobs[[6]]$children[[3]]$x
# [1] 0.0454545454545455native 0.46native 0.954545454545454native 
my.grob$grobs[[6]]$children[[3]]$y
# [1] 0.0454545454545455native 0.157272727272727native 0.954545454545454native

緑の矢印でマークされた画像全体の左下隅から測定を開始するときに、xy座標の値を取得するにはどうすればよいですか?

可能であれば、ggplotのテーマを考慮した解決策を求めています。のようなテーマを追加すると、Axesに影響し、プロットされた画像全体に対して点の位置もシフトします。+ theme_void()

更新:軸のフォントサイズは、プロットの幅と高さに応じて変化し、プロットパネルの相対サイズに影響することに気付きました。そのため、プロット幅プロット高さを定義せずにnpc単位で位置を指定するのは簡単ではありません。可能な場合は、geom_pointsの位置をプロット幅プロット高さの関数として指定します。


5
なぜ2つの反対票を投じるのですか?
マーカス

2
はい、懸念や提案がある場合はコメントしてください。
LBogaardt

1
プロット自体の次元が固定されていないことを考慮してください。絶対点の位置は、印刷するデバイスのサイズだけでなく、軸の比率にも依存します。したがって、必要なものにかなり興味があります
Tjebo

1
反対票については、SEで有効な質問になるために質問を正当化する必要がないことに注意してください。なぜ知りたいのですか?やってるから。
LBogaardt

1
これも。しかし、本当の答えをやったことがなかったstackoverflow.com/questions/48710478/...
Tjebo

回答:


5

ggplotのサイズを変更すると、パネル内の要素の位置がnpc空間の固定位置になりません。これは、プロットの一部のコンポーネントのサイズが固定されており、それらの一部(たとえば、パネル)がデバイスのサイズに応じて寸法を変更するためです。

つまり、どのソリューションでもデバイスサイズを考慮する必要があり、プロットのサイズを変更する場合は、計算を再度実行する必要があります。そうは言っても、ほとんどのアプリケーション(あなたのアプリケーションを含む、物音によって)では、これは問題ではありません。

もう1つの問題は、パネルグロブ内で正しいグロブを識別していることを確認することであり、これを簡単に一般化する方法を確認することは困難です。リストのサブセット機能を使用する[[6]]と、[[3]]あなたの例では、他のプロットに一般化ではありません。

とにかく、このソリューションは、gtable内のパネルのサイズと位置を測定し、すべてのサイズをメートル単位に変換してから、メートル単位のプロット次元で割ってnpc空間に変換することで機能します。数値インデックスではなく名前でパネルとポイントを抽出することで、もう少し一般的なものにしようとしました。

library(ggplot2)
library(grid)
require(gtable)

get_x_y_values <- function(gg_plot)
{
  img_dim      <- grDevices::dev.size("cm") * 10
  gt           <- ggplot2::ggplotGrob(gg_plot)
  to_mm        <- function(x) grid::convertUnit(x, "mm", valueOnly = TRUE)
  n_panel      <- which(gt$layout$name == "panel")
  panel_pos    <- gt$layout[n_panel, ]
  panel_kids   <- gtable::gtable_filter(gt, "panel")$grobs[[1]]$children
  point_grobs  <- panel_kids[[grep("point", names(panel_kids))]]
  from_top     <- sum(to_mm(gt$heights[seq(panel_pos$t - 1)]))
  from_left    <- sum(to_mm(gt$widths[seq(panel_pos$l - 1)]))
  from_right   <- sum(to_mm(gt$widths[-seq(panel_pos$l)]))
  from_bottom  <- sum(to_mm(gt$heights[-seq(panel_pos$t)]))
  panel_height <- img_dim[2] - from_top - from_bottom
  panel_width  <- img_dim[1] - from_left - from_right
  xvals        <- as.numeric(point_grobs$x)
  yvals        <- as.numeric(point_grobs$y)
  yvals        <- yvals * panel_height + from_bottom
  xvals        <- xvals * panel_width + from_left
  data.frame(x = xvals/img_dim[1], y = yvals/img_dim[2])
}

これで、例を使用してテストできます。

my.plot <- ggplot(data.frame(x = c(0, 0.456, 1), y = c(0, 0.123, 1))) +
             geom_point(aes(x, y), color = "red")

my.points <- get_x_y_values(my.plot)
my.points
#>           x         y
#> 1 0.1252647 0.1333251
#> 2 0.5004282 0.2330669
#> 3 0.9479917 0.9442339

そして、これらの値が正しいことを確認するには、npc座標として値を使用して、赤い点の上にいくつかの点群をプロットします。

my.plot
grid::grid.draw(pointsGrob(x = my.points$x, y = my.points$y, default.units = "npc"))

2020-03-25にreprexパッケージ(v0.3.0)によって作成されました


1
このsum(to_mm(gt$heights[seq(panel_pos$t - 1)]))部分は最も奇妙です。ここで何を合計しているのか説明できますか?
LBogaardt

1
@LBogaardt panel_pos$tは、(フレキシブル)パネルが配置されているグリッドseq(panel_pos$t -1)の行を示しsum(to_mm(gt$heights[seq(panel_pos$t - 1)]))ます。したがって、これより上のすべての行番号、つまりこれらの行の高さの合計になります。
アランキャメロン

@LBogaardt私は簡潔さと明快さのバランスをとろうとしていましたが、おそらく私はこれを正しく理解していません...
アランキャメロン

ああ、ggplotはテーブルのようなもので、yラベル用に1列、y軸番号付け用に1列ずつあります。同様に、それぞれ幅/高さを持つ行の場合も同様です。パネルはこの表の1つのセルですか?とった。アラン、ありがとう。
LBogaardt

1
まさに、@ LBogaardt。実際、ggplotGrobはgTable、またはグロブテーブルを生成します
Allan Cameron
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.