Добавьте фоновое изображение в график ggplot, чтобы изображение было видно только внутри баров - PullRequest
0 голосов
/ 03 января 2019

Я хотел бы создать барплот в R, используя ggplot2, чтобы полосы были прозрачными, позволяя видеть фоновое изображение, в то время как остальная часть графика была непрозрачной и покрывала фоновое изображение.

Я могу добавить изображение к фону, как показано ниже, но я не могу найти способ, чтобы только фоновое изображение было видно внутри полос.По сути, я надеюсь создать обратное тому, что у меня есть здесь.

library(ggplot2)
library(jpeg)
library(grid)
library(scales)

montage <- readJPEG("AcanthMontage.jpg")
mont <- rasterGrob(montage, 
                   width = unit(1,"npc"), 
                   height = unit(1,"npc"))

montplot <- ggplot(frequencyDF, aes(x=depth, y= perLiter)) + 
  annotation_custom(mont, -Inf, Inf, -Inf, Inf) +
  scale_fill_continuous(guide = FALSE) +
  geom_bar(stat = "identity", color="black", fill="white", alpha=0.5) + 
  coord_flip() + 
  scale_y_continuous(limits= c(0,1.25), expand = c(0, 0)) + 
  scale_x_continuous(limits= c(-1000,0), expand = c(0,0)) + 
  theme_bw() + 
  theme(text=element_text(size=16)) + 
  xlab("Depth (m)") + 
  ylab("Cells per Liter")

montplot

ggplot with image as background

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Это напоминает мне о подобной проблеме здесь , где принятое решение использовало geom_ribbon() для обеспечения маскирующего слоя.

В том же духе, поскольку в этом случае маска должна окружать отдельные стержни, мы стремимся создать слой многоугольника, который изящно обрабатывает отверстия. Последнее, что я проверил, geom_polygon делает не так здорово, но geom_polypath из пакета ggpolypath делает.

Воспроизводимый пример с использованием логотипа R в качестве образца изображения и встроенного фрейма данных:

library(ggplot2)
library(grid)
library(jpeg)

montage <- readJPEG(system.file("img", "Rlogo.jpg", package="jpeg"))
mont <- rasterGrob(montage, width = unit(1,"npc"), 
                   height = unit(1,"npc"))

p <- ggplot(mpg, aes(x = class)) +
  annotation_custom(mont, -Inf, Inf, -Inf, Inf) +
  geom_bar(color = "black", fill = NA) +
  coord_flip() +
  theme_bw()

p

plot 1

Создание фрейма данных координат для маскирующего слоя:

library(dplyr)
library(tidyr)

# convert the xmin/xmax/ymin/ymax values for each bar into
# x/y coordinates for a hole in a large polygon,
# then add coordinates for the large polygon

new.data <- layer_data(p, 2L) %>%  

  select(ymin, ymax, xmin, xmax) %>%
  mutate(group = seq(1, n())) %>%
  group_by(group) %>%
  summarise(coords = list(data.frame(x = c(xmin, xmax, xmax, xmin),
                                     y = c(ymin, ymin, ymax, ymax),
                                     order = seq(1, 4)))) %>%
  ungroup() %>%
  unnest() %>%

  rbind(data.frame(group = 0,
                   x = c(-Inf, Inf, Inf, -Inf),
                   y = c(-Inf, -Inf, Inf, Inf),
                   order = seq(1, 4)))

> new.data
# A tibble: 32 x 4
   group     x     y order
   <dbl> <dbl> <dbl> <int>
 1     1  0.55     0     1
 2     1  1.45     0     2
 3     1  1.45     5     3
 4     1  0.55     5     4
 5     2  1.55     0     1
 6     2  2.45     0     2
 7     2  2.45    47     3
 8     2  1.55    47     4
 9     3  2.55     0     1
10     3  3.45     0     2
# ... with 22 more rows

Добавьте маскирующий слой:

library(ggpolypath)

p +
  geom_polypath(data = new.data,
                aes(x = x, y = y, group = group),
                inherit.aes = FALSE, 
                rule = "evenodd",
                fill = "white", color = "black")

plot 2

p.s. Старая поговорка «только потому, что вы можете, не значит, что вы должны», вероятно, применима здесь ...

0 голосов
/ 03 января 2019

Достаточно интересная проблема. Я присоединяюсь к @ r2evans, обеспокоенному тем, что это может привести к запутанному сюжету, который может передать неправильные интерпретации с шаблонами внутри столбцов.

Если это был вопрос редактирования изображения, вы ищете маску, где столбцы представляют собой маску, которая фильтрует фоновое изображение. Пакет raster имеет функцию для этого, но я не уверен, как объединить его с ggplot2.

ggplot2 использует пакет grid для визуализации элементов на графическом устройстве (например, экран, окно, pdf и т. Д.). Здесь вы можете комбинировать rasterGrob с окном просмотра для каждой панели для создания маскирующего эффекта. Сначала остановимся на рендеринге ggplotGrob объекта из вашего объекта ggplot2 (фактически ggplotGrob(p), где p <- ggplot(...) + ...).

Для получения дополнительной информации о видовых экранах см. Zhou 2010 и Murell 2018

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...