将图像插入图表区域之外的ggplot [英] Inserting an image to ggplot outside the chart area

查看:135
本文介绍了将图像插入图表区域之外的ggplot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将图像添加到图表区域外的ggplot图表?

Is it possible to add an image to ggplot chart which will be outside chart area?

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

I know it is possible to add images to the chart using annotate_raster and annotate_custom, however they both add images inside the chart. I need to add company logo in the upper right corner above the chart - at the title level.

使用annotate_custom添加图像的示例:
将图片插入ggplot2

Example of adding image using annotate_custom: Inserting an image to ggplot2

更新:根据user1317221_G的建议,我可以将图片放在外面。

UPDATE: Following recommendations from user1317221_G, I'm able to put image outside.

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中。

i would like to put image automatically - determine xmin/xmax and ymin/ymax automatically. Using traditional graphics i can call par('usr') and get chart parameters, but this is not applicable to ggplot charts. Is there an easy way to determine plot area in ggplot? For example get sizes of plt and plug the values for limits into plt2

UPDATE2:如果使用分面,此方法也不会起作用。例如,我想将徽标放在标题级的右下角,如下图所示,如果我使用上述方法,则会出现错误。

UPDATE2: This method also doesn't really work if you use faceting. For example I would like to put logo in the right corner at title level, in the following chart, and I get errors if I use method above.

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")


推荐答案

当分面时, annotation_custom 在所有面板中绘制注释。因此, annotation-custom 可能不是最好的选择。以下是使用 grid 包中的函数的两次尝试。这两者都不是完全自动的,但你可能能够适应其中一种以满足你的需求。他们建立了一个2×2网格,使用 grid.show.layout()命令显示。首先,小平面图填充整个面板,右上方的视口包含标志。恰巧在你的情节中,标识有明确的空间。请注意 layout.pos.row layout.pos.col 如何为视口中的视口占用的行和列

When faceting, annotation_custom draws the annotation in all panels. Therefore, annotation-custom might not be the best way to go. Here are two attempts using functions from the grid package. Neither is entirely automatic, but you might be able to adapt one or the other to meet your needs. They set up a 2 X 2 grid, shown using the grid.show.layout() command. In the first, the faceted plot fills the entire panel, and the top right viewport contains the logo. It just so happens that in your plot, there is clear space for the logo. Note how layout.pos.row and layout.pos.col give the rows and columns occupied by a viewport within the layout.

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放置在包含该标识的视口旁边的左上视口中。

The title does not entirely align with the logo. One fix is to remove the title from the ggplot, draw a separate textGrob that contains the title, then position the textGrob in the top left viewport beside the viewport that contains the logo.

# 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)

这篇关于将图像插入图表区域之外的ggplot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆