Вставка изображения в ggplot вне области диаграммы

Можно ли добавить изображение в график ggplot, которое будет находиться вне области графика?

Я знаю, что можно добавлять изображения на график с помощью annotate_raster и annotate_custom, однако оба они добавляют изображения внутри графика. Мне нужно добавить логотип компании в верхнем правом углу над диаграммой - на уровне заголовка.

Пример добавления изображения с использованием annotate_custom: вставка изображения в 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")

1 ответ

Решение

При огранке, annotation_custom рисует аннотацию на всех панелях. Следовательно, annotation-custom может быть, не лучший путь. Вот две попытки использования функций из grid пакет. Ни один из них не является полностью автоматическим, но вы можете адаптировать один или другой к вашим потребностям. Они создали сетку 2 X 2, показанную с помощью grid.show.layout() команда. В первом случае граненый график заполняет всю панель, а в правом верхнем окне просмотра отображается логотип. Так получилось, что на вашем сюжете есть свободное место для логотипа. Обратите внимание, как layout.pos.row а также layout.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)

Другие вопросы по тегам