ggplot2中geom_point的npc坐标
npc coordinates of geom_point in ggplot2
如何获取geom_point的x、y坐标] 在 ggplot 中,参考帧是整个绘制的图像?
我可以用一些 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 的一些附加信息,例如与绘图相关的坐标面板,由紫色箭头标记。但是,这忽略了轴占用的 space。
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
从整个画面的左下角开始测量,如何得到x、y坐标的值图片,用绿色箭头标记?
如果可能的话,我希望解决方案考虑到 ggplot 的 theme。添加像 + theme_void()
这样的 主题 会影响坐标轴,也会改变点相对于整个绘制图像的位置。
更新:
我意识到轴的字体大小会根据绘图的宽度和高度而变化,从而影响 绘图面板 的相对大小。因此,在不定义 plot width 和 plot height[=52] 的情况下提供 npc 单位的位置并非易事=].如果可能,将 geom_points 的位置作为 绘图宽度 和 绘图高度的函数给出=52=].
调整 ggplot 大小时,面板内元素的位置在 npc 中不固定 space。这是因为绘图的某些组件具有固定尺寸,而其中一些组件(例如面板)会根据设备的尺寸改变尺寸。
这意味着任何解决方案都必须考虑设备大小,如果您想调整绘图大小,则必须重新 运行 计算。话虽如此,对于大多数应用程序(包括您的应用程序,听起来),这不是问题。
另一个困难是确保您在面板 grob 中识别出正确的 grob,并且很难看出这如何容易地被概括。在您的示例中使用列表子集函数 [[6]]
和 [[3]]
不能推广到其他图。
无论如何,此解决方案的工作原理是测量面板尺寸和 gtable 中的位置,并将所有尺寸转换为毫米,然后除以以毫米为单位的地块尺寸以转换为 npc space。我试图通过按名称而不是数字索引提取面板和点来使其更通用。
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
我们可以通过在你的红点上绘制一些点 grob 来确认这些值是正确的,使用我们的值作为 npc 坐标:
my.plot
grid::grid.draw(pointsGrob(x = my.points$x, y = my.points$y, default.units = "npc"))
由 reprex package (v0.3.0)
于 2020 年 3 月 25 日创建
如何获取geom_point的x、y坐标] 在 ggplot 中,参考帧是整个绘制的图像?
我可以用一些 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 的一些附加信息,例如与绘图相关的坐标面板,由紫色箭头标记。但是,这忽略了轴占用的 space。
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
从整个画面的左下角开始测量,如何得到x、y坐标的值图片,用绿色箭头标记?
如果可能的话,我希望解决方案考虑到 ggplot 的 theme。添加像 + theme_void()
这样的 主题 会影响坐标轴,也会改变点相对于整个绘制图像的位置。
更新: 我意识到轴的字体大小会根据绘图的宽度和高度而变化,从而影响 绘图面板 的相对大小。因此,在不定义 plot width 和 plot height[=52] 的情况下提供 npc 单位的位置并非易事=].如果可能,将 geom_points 的位置作为 绘图宽度 和 绘图高度的函数给出=52=].
调整 ggplot 大小时,面板内元素的位置在 npc 中不固定 space。这是因为绘图的某些组件具有固定尺寸,而其中一些组件(例如面板)会根据设备的尺寸改变尺寸。
这意味着任何解决方案都必须考虑设备大小,如果您想调整绘图大小,则必须重新 运行 计算。话虽如此,对于大多数应用程序(包括您的应用程序,听起来),这不是问题。
另一个困难是确保您在面板 grob 中识别出正确的 grob,并且很难看出这如何容易地被概括。在您的示例中使用列表子集函数 [[6]]
和 [[3]]
不能推广到其他图。
无论如何,此解决方案的工作原理是测量面板尺寸和 gtable 中的位置,并将所有尺寸转换为毫米,然后除以以毫米为单位的地块尺寸以转换为 npc space。我试图通过按名称而不是数字索引提取面板和点来使其更通用。
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
我们可以通过在你的红点上绘制一些点 grob 来确认这些值是正确的,使用我们的值作为 npc 坐标:
my.plot
grid::grid.draw(pointsGrob(x = my.points$x, y = my.points$y, default.units = "npc"))
由 reprex package (v0.3.0)
于 2020 年 3 月 25 日创建