在ggplot中将图像插入到图表区域之外

12

如何在ggplot图表之外添加图像?

我知道使用annotate_raster和annotate_custom可以将图像添加到图表中,但它们都在图表内部添加图像。我需要在标题级别的右上角上方添加公司标志。

使用annotate_custom添加图像的示例:Inserting an image to ggplot2

更新:根据user1317221_G的建议,我已经成功将图像放在图表之外。

library(png)
library(grid)
library(ggplot2)
img <- readPNG(system.file("img", "Rlogo.png", package="png"))

g <- rasterGrob(img, interpolate=TRUE)
plt <- qplot(1:10, 1:10, geom="blank") +
      opts(title = 'Title') + 
      geom_point() 
plt2 <- plt + annotation_custom(g, xmin=9, xmax=10, ymin=10.5, ymax=11.25)

gt <- ggplot_gtable(ggplot_build(plt2))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)
我想自动放置图片,自动确定xmin/xmax和ymin/ymax。 在传统的图形中,我可以调用par('usr')并获取图表参数,但这不适用于ggplot图表。 有没有一种简单的方法来确定ggplot中的绘图区域?例如获取plt的大小,并将值插入到plt2的限制中。
更新2:如果您使用分面,则此方法也不适用。例如,我想在以下图表中的标题级别右上角放置徽标,如果我使用上述方法,则会出现错误。
d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) + 
     xlim(0, 2) + 
     stat_binhex(na.rm = TRUE) + 
     labs(title = 'Title') +
     theme(aspect.ratio = 1) + 
     facet_wrap(~ color, scales = "free_x")

3
annotate_custom 可以在外部工作。https://dev59.com/I2ct5IYBdhLWcg3wApCH#12417481 - user1317221_G
1个回答

7
当进行分面时,annotation_custom会在所有面板中绘制注释。因此,annotation-custom可能不是最佳选择。这里有两种尝试使用grid软件包中的函数。它们都不是完全自动化的,但您可以尝试调整其中一种来满足您的需求。它们设置一个2 X 2网格,并使用grid.show.layout()命令显示。在第一个图中,分面绘图填充整个面板,右上角视口包含标志。恰好在您的图中,有清晰的空间可用于放置标志。请注意,layout.pos.rowlayout.pos.col给出了布局中视口占用的行和列。
library(ggplot2)
library(png)
library(grid)

# Get the logo
img <- readPNG(system.file("img", "Rlogo.png", package="png"))
g <- rasterGrob(img)

# Set the size of the viewport to contain the logo
size = unit(2, "cm")

# Get the graph
d <- ggplot(diamonds, aes(carat, price)) + 
     xlim(0, 2) + 
     stat_binhex(na.rm = TRUE) + 
     labs(title = 'Title') +
     theme(aspect.ratio = 1) + 
     facet_wrap(~ color, scales = "free_x")

# Set up the layout for grid 
heights = unit.c(size, unit(1, "npc") - size)
widths = unit.c(unit(1, "npc") - size, size)
lo = grid.layout(2, 2, widths = widths, heights = heights)
# Show the layout
grid.show.layout(lo)

# Position the elements within the viewports
grid.newpage()
pushViewport(viewport(layout = lo))

    # The plot
pushViewport(viewport(layout.pos.row=1:2, layout.pos.col = 1:2))
print(d, newpage=FALSE)
popViewport()

    # The logo
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 2))
print(grid.draw(g), newpage=FALSE)
popViewport()
popViewport()

# To save the object
g = grid.grab()

grid.newpage()
grid.draw(g)

标题与标志不完全对齐。一种解决方法是从ggplot中删除标题,绘制一个包含标题的单独的textGrob,然后将textGrob定位在包含标志的视口旁边的左上角视口中。

# Get the logo
img <- readPNG(system.file("img", "Rlogo.png", package="png"))
g <- rasterGrob(img)

# Set the size of the viewport to contain the logo
size = unit(2, "cm")

# Get the graph
d <- ggplot(diamonds, aes(carat, price)) + 
     xlim(0, 2) + 
     stat_binhex(na.rm = TRUE) + 
     # labs(title = 'Title') +
     theme(aspect.ratio = 1) + 
     facet_wrap(~ color, scales = "free_x")

# and the title
title = textGrob("Title", gp = gpar(face = "bold", cex = 2))

# Set up the layout for grid 
heights = unit.c(size, unit(1, "npc") - size)
widths = unit.c(unit(1, "npc") - 1.5*size, size)
lo = grid.layout(2, 2, widths = widths, heights = heights)
# Show the layout
grid.show.layout(lo)

# Position the elements within the viewports
grid.newpage()
pushViewport(viewport(layout = lo))

    # The plot
pushViewport(viewport(layout.pos.row=2, layout.pos.col = 1:2))
print(d, newpage=FALSE)
popViewport()

    # The logo
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 2))
print(grid.draw(g), newpage=FALSE)
popViewport()

    # The title
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 1))
print(grid.draw(title), newpage=FALSE)
popViewport()
popViewport()

# To save the object
g = grid.grab()

grid.newpage()
grid.draw(g)

enter image description here


有没有一种方法可以将图形、标题和图像保存为一个文件,比如使用ggsave? - Jonathan Charlton
2
使用内置的图形设备,如 pngpdf 等。使用 ?png 了解更多信息。ggsave 很好用,但它并不能处理所有情况。 - Tyler Rinker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接