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)によって作成されました