如何在 ggplot2 中为矩形 rasterGrob 添加边框?
How to add a border to a rectangular rasterGrob in ggplot2?
我正在尝试为矩形 png 图像添加边框 (found here) 我已将其添加到 ggplot,并使用 npc 指定了定位。
library(png)
library(grid)
library(ggplot2)
img <- readPNG("gb.png")
g <- rasterGrob(img, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
border <- rectGrob(x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"),
# height = resolveRasterSize(g)$height,
gp = gpar(lwd = 2, col = "black", fill="#00000000"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
在 RStudio 查看器中看起来像这样:
因为我已经从光栅中指定了 x 和 y 坐标以及宽度,所以很容易为边界坐标复制这些坐标。因为我没有指定任何高度,所以我不确定找出 npc 来设置边界高度的最佳方法。我没有设置高度,因为我想根据 .png 尺寸自动保留标志的任何纵横比。
我查看了一些可能对网格有用的函数,比如 resolveRasterSize
,它说你可以
Determine the width and height of a raster grob when one or both are
not given explicitly
还有关于 aspect/viewport 的其他内容,我不太了解它如何影响在 ggplot2 中创建的绘图。在 rectgrob
和 height = resolveRasterSize(g)$height
中,情节最终看起来像:
边框与图片不符。我还注意到用 resolveRasterSize
创建的高度变量被赋予了一个英寸而不是 npc 的属性。
如果我调整 Plots 平面的大小,我注意到标志和边框的高度会动态变化,有时我可以使它们对齐,但我想要一种更精确的方法来使它们正确对齐,例如,如果我在 ggsave 或某些用法中使用不同的维度进行保存。
我尝试查看其他 grid
函数,例如 convertHeight
,height = convertHeight(resolveRasterSize(g)$height, "npc")
在 rectGrob
中,它似乎总是在 RStudio 的绘图窗格中设置正确的边框, 但如果我调整窗格的大小,边框会再次错位,如果我用 ggsave 保存,它也会错位。
ggsave(filename = "my_example.png", plot = myplot, width = 16, height = 9)
正如您已经正确确定的那样,问题是您的 rectGrob
的尺寸将受到绘图缩放 window 与 [=14= 的尺寸不同的影响].您可以使用一点数学来解决这个问题,以校正光栅的纵横比和绘图 window。唯一的缺点是在调整绘图大小时必须重新运行计算 window。对于大多数应用程序,这不是主要问题。例如,要保存为 16 x 9 的 png 文件,您可以这样做:
img <- readPNG("gb.png")
g <- rasterGrob(img, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
img_aspect <- dim(g$raster)[1] / dim(g$raster)[2]
dev_aspect <- 16/9
rect_aspect <- dev_aspect * img_aspect
border <- rectGrob(x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = g$width,
height = g$width * rect_aspect,
gp = gpar(lwd = 2, col = "black", fill="#00000000"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
ggsave(filename = "my_example.png",
plot = myplot, width = 16, height = 9)
这导致:
my_example.png
如果你想让边框适合 R Studio 中的当前设备,那么你可以使用
dev_aspect <- dev.size()[1]/dev.size()[2]
如果您想要一个矩形来缩放绘图中发生的任何事情,那么这可以通过创建仅包含黑色边框的 rasterGrob
来完成。
例如,如果您这样做:
border <- g$raster
border[] <- "#00000000"
border[1:2, ] <- "#000000FF"
border[, 1:2] <- "#000000FF"
border[nrow(border) + seq(-1, 0), ] <- "#000000FF"
border[, ncol(border) + seq(-1, 0)] <- "#000000FF"
border <- rasterGrob(border, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
然后 myplot
将在标志周围显示一个黑色边框,该边框会随着重新缩放而持续存在。
为什么不使用 library(magick)
及其 image_border()
功能?
library(grid)
library(magick)
library(ggplot2)
img <- image_read("gb.png")
img_with_border <- rasterGrob(image_border(img,"black","1x1"),
x = unit(0.5, "npc"), y = unit(0.5, "npc"), width = unit(0.4, "npc"))
ggplot() +
annotation_custom(img_with_border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
我正在尝试为矩形 png 图像添加边框 (found here) 我已将其添加到 ggplot,并使用 npc 指定了定位。
library(png)
library(grid)
library(ggplot2)
img <- readPNG("gb.png")
g <- rasterGrob(img, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
border <- rectGrob(x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"),
# height = resolveRasterSize(g)$height,
gp = gpar(lwd = 2, col = "black", fill="#00000000"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
在 RStudio 查看器中看起来像这样:
因为我已经从光栅中指定了 x 和 y 坐标以及宽度,所以很容易为边界坐标复制这些坐标。因为我没有指定任何高度,所以我不确定找出 npc 来设置边界高度的最佳方法。我没有设置高度,因为我想根据 .png 尺寸自动保留标志的任何纵横比。
我查看了一些可能对网格有用的函数,比如 resolveRasterSize
,它说你可以
Determine the width and height of a raster grob when one or both are not given explicitly
还有关于 aspect/viewport 的其他内容,我不太了解它如何影响在 ggplot2 中创建的绘图。在 rectgrob
和 height = resolveRasterSize(g)$height
中,情节最终看起来像:
边框与图片不符。我还注意到用 resolveRasterSize
创建的高度变量被赋予了一个英寸而不是 npc 的属性。
如果我调整 Plots 平面的大小,我注意到标志和边框的高度会动态变化,有时我可以使它们对齐,但我想要一种更精确的方法来使它们正确对齐,例如,如果我在 ggsave 或某些用法中使用不同的维度进行保存。
我尝试查看其他 grid
函数,例如 convertHeight
,height = convertHeight(resolveRasterSize(g)$height, "npc")
在 rectGrob
中,它似乎总是在 RStudio 的绘图窗格中设置正确的边框, 但如果我调整窗格的大小,边框会再次错位,如果我用 ggsave 保存,它也会错位。
ggsave(filename = "my_example.png", plot = myplot, width = 16, height = 9)
正如您已经正确确定的那样,问题是您的 rectGrob
的尺寸将受到绘图缩放 window 与 [=14= 的尺寸不同的影响].您可以使用一点数学来解决这个问题,以校正光栅的纵横比和绘图 window。唯一的缺点是在调整绘图大小时必须重新运行计算 window。对于大多数应用程序,这不是主要问题。例如,要保存为 16 x 9 的 png 文件,您可以这样做:
img <- readPNG("gb.png")
g <- rasterGrob(img, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
img_aspect <- dim(g$raster)[1] / dim(g$raster)[2]
dev_aspect <- 16/9
rect_aspect <- dev_aspect * img_aspect
border <- rectGrob(x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = g$width,
height = g$width * rect_aspect,
gp = gpar(lwd = 2, col = "black", fill="#00000000"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
ggsave(filename = "my_example.png",
plot = myplot, width = 16, height = 9)
这导致:
my_example.png
如果你想让边框适合 R Studio 中的当前设备,那么你可以使用
dev_aspect <- dev.size()[1]/dev.size()[2]
如果您想要一个矩形来缩放绘图中发生的任何事情,那么这可以通过创建仅包含黑色边框的 rasterGrob
来完成。
例如,如果您这样做:
border <- g$raster
border[] <- "#00000000"
border[1:2, ] <- "#000000FF"
border[, 1:2] <- "#000000FF"
border[nrow(border) + seq(-1, 0), ] <- "#000000FF"
border[, ncol(border) + seq(-1, 0)] <- "#000000FF"
border <- rasterGrob(border, x = unit(0.5, "npc"),
y = unit(0.5, "npc"),
width = unit(0.4, "npc"))
myplot <- ggplot() +
annotation_custom(g) +
annotation_custom(border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))
然后 myplot
将在标志周围显示一个黑色边框,该边框会随着重新缩放而持续存在。
为什么不使用 library(magick)
及其 image_border()
功能?
library(grid)
library(magick)
library(ggplot2)
img <- image_read("gb.png")
img_with_border <- rasterGrob(image_border(img,"black","1x1"),
x = unit(0.5, "npc"), y = unit(0.5, "npc"), width = unit(0.4, "npc"))
ggplot() +
annotation_custom(img_with_border) +
scale_x_continuous(limits = c(0, 1)) +
scale_y_continuous(limits = c(0, 1))