Grobs 根本没有绘制或位置错误
Grobs are not plotted at all or in wrong position
我无法理解如何将 grob 放入绘图区域。
这是我的意思的一个例子。
假设我有以下情节。
library(tidyverse)
p <- mpg %>%
ggplot(aes(year)) +
geom_bar()
p
我知道我可以从中得到一个 grobs 列表并像这样绘制它。
l <- ggplotGrob(p)
grid::grid.newpage()
grid::grid.draw(l)
从列表l
的结构我也了解到矩形是画成rectGrob
的。我在
中找到了这些
grobs <- l$grobs[[6]]
rect_grobs <- grobs$children[[3]]
但是如果我想使用直接来自 rect_grobs
的数据绘制至少一个矩形,什么也不会发生。这与我是否使用 grid::grid.newpage()
创建新的 canvas 无关。
# This draws nothing
grid::grid.draw(
grid::rectGrob(
x = rect_grobs$x[1],
y = rect_grobs$y[1],
height = rect_grobs$height[1],
width = rect_grobs$width[1],
just = rect_grobs$just[1],
)
)
然而,如果我手动插入 rect_grobs
中的值,则会在错误的位置绘制一个矩形。我怀疑这与视口有关,但我尝试查看 l
、grobs
和 rect_grobs
,但我不知道这样设置的视口是什么。我看的地方只有vp = NULL
.
# This draws in wrong position
grid::grid.draw(
grid::rectGrob(
x = 0.0455,
y = 0.955,
width = 0.431,
height = 0.909,
just = 'left'
)
)
所以,我的问题是
- 如果我直接从
rect_grobs
列表中获取值,为什么代码不绘制矩形?
- 如果我手动添加矩形,如何将它放到正确的位置?
rect_grobs
不画的原因确实是没有viewport。如果一个 grob 没有设置视口,它将从它的父级继承,但是因为你已经从 gTable
中取出它,它没有父级。这很容易通过给它一个默认视口来纠正:
rect_grobs$vp <- grid::viewport()
grid::grid.draw(rect_grobs)
只要我们指定正确的just
,我们就在同一个地方得到了矩形:
red_rect <- grid::rectGrob(
x = 0.0455,
y = 0.955,
width = 0.431,
height = 0.909,
just = c("left", "top"),
gp = grid::gpar(fill = "red")
)
grid::grid.draw(red_rect)
但是,这不是矩形在 ggplot 中的位置。那是因为在 ggplot
中,面板有自己的视口。要在此上下文中绘制矩形,我们需要在调用 grid.draw
之前导航到正确的视口
plot(p)
grid::seekViewport(grid::vpPath("layout", "panel.7-5-7-5"))
grid::grid.draw(red_rect)
我无法理解如何将 grob 放入绘图区域。 这是我的意思的一个例子。 假设我有以下情节。
library(tidyverse)
p <- mpg %>%
ggplot(aes(year)) +
geom_bar()
p
我知道我可以从中得到一个 grobs 列表并像这样绘制它。
l <- ggplotGrob(p)
grid::grid.newpage()
grid::grid.draw(l)
从列表l
的结构我也了解到矩形是画成rectGrob
的。我在
grobs <- l$grobs[[6]]
rect_grobs <- grobs$children[[3]]
但是如果我想使用直接来自 rect_grobs
的数据绘制至少一个矩形,什么也不会发生。这与我是否使用 grid::grid.newpage()
创建新的 canvas 无关。
# This draws nothing
grid::grid.draw(
grid::rectGrob(
x = rect_grobs$x[1],
y = rect_grobs$y[1],
height = rect_grobs$height[1],
width = rect_grobs$width[1],
just = rect_grobs$just[1],
)
)
然而,如果我手动插入 rect_grobs
中的值,则会在错误的位置绘制一个矩形。我怀疑这与视口有关,但我尝试查看 l
、grobs
和 rect_grobs
,但我不知道这样设置的视口是什么。我看的地方只有vp = NULL
.
# This draws in wrong position
grid::grid.draw(
grid::rectGrob(
x = 0.0455,
y = 0.955,
width = 0.431,
height = 0.909,
just = 'left'
)
)
所以,我的问题是
- 如果我直接从
rect_grobs
列表中获取值,为什么代码不绘制矩形? - 如果我手动添加矩形,如何将它放到正确的位置?
rect_grobs
不画的原因确实是没有viewport。如果一个 grob 没有设置视口,它将从它的父级继承,但是因为你已经从 gTable
中取出它,它没有父级。这很容易通过给它一个默认视口来纠正:
rect_grobs$vp <- grid::viewport()
grid::grid.draw(rect_grobs)
只要我们指定正确的just
,我们就在同一个地方得到了矩形:
red_rect <- grid::rectGrob(
x = 0.0455,
y = 0.955,
width = 0.431,
height = 0.909,
just = c("left", "top"),
gp = grid::gpar(fill = "red")
)
grid::grid.draw(red_rect)
但是,这不是矩形在 ggplot 中的位置。那是因为在 ggplot
中,面板有自己的视口。要在此上下文中绘制矩形,我们需要在调用 grid.draw
plot(p)
grid::seekViewport(grid::vpPath("layout", "panel.7-5-7-5"))
grid::grid.draw(red_rect)