Использование grid.edit и grid.remove на гробах, сохраненных с помощью ggplotGrob - PullRequest
0 голосов
/ 25 июня 2019

У меня есть сложный ggplot2 график, созданный с помощью домашней функции (не от меня), которую я хочу использовать в своей собственной функции графика. Я хочу использовать пакет grid для реорганизации всего. Я нашел этот хороший учебник на старой (устаревшей) ggplot wiki , но похоже, что воспроизводимый пример не работает, и я не могу найти эквивалентную страницу на новой вики-странице.

Вот мой собственный воспроизводимый пример:

Сначала я создаю объект ggplot, который храню (не хочу, чтобы он печатался):

library(grid)
library(ggplot2)

set.seed(123)
dd <- data.frame(x = sample(1:6), y = sample(1:6), cat = c("a","b","a","c","c","b"))

gg <- ggplot(dd, aes(x=x,y=y, color=cat)) +
  geom_point()+
  geom_line()

Затем, используя функцию ggplotGrob, я могу извлечь grobs из моего графика:

gg_grod <- ggplotGrob(gg)
gg_grod
TableGrob (12 x 11) "layout": 19 grobs
    z         cells       name                                          grob
1   0 ( 1-12, 1-11) background               rect[plot.background..rect.362]
2   5 ( 6- 6, 4- 4)     spacer                                zeroGrob[NULL]
3   7 ( 7- 7, 4- 4)     axis-l           absoluteGrob[GRID.absoluteGrob.320]
4   3 ( 8- 8, 4- 4)     spacer                                zeroGrob[NULL]
5   6 ( 6- 6, 5- 5)     axis-t                                zeroGrob[NULL]
6   1 ( 7- 7, 5- 5)      panel                      gTree[panel-1.gTree.306]
7   9 ( 8- 8, 5- 5)     axis-b           absoluteGrob[GRID.absoluteGrob.313]
8   4 ( 6- 6, 6- 6)     spacer                                zeroGrob[NULL]
9   8 ( 7- 7, 6- 6)     axis-r                                zeroGrob[NULL]
10  2 ( 8- 8, 6- 6)     spacer                                zeroGrob[NULL]
11 10 ( 5- 5, 5- 5)     xlab-t                                zeroGrob[NULL]
12 11 ( 9- 9, 5- 5)     xlab-b titleGrob[axis.title.x.bottom..titleGrob.323]
13 12 ( 7- 7, 3- 3)     ylab-l   titleGrob[axis.title.y.left..titleGrob.326]
14 13 ( 7- 7, 7- 7)     ylab-r                                zeroGrob[NULL]
15 14 ( 7- 7, 9- 9)  guide-box                             gtable[guide-box]
16 15 ( 4- 4, 5- 5)   subtitle         zeroGrob[plot.subtitle..zeroGrob.358]
17 16 ( 3- 3, 5- 5)      title            zeroGrob[plot.title..zeroGrob.357]
18 17 (10-10, 5- 5)    caption          zeroGrob[plot.caption..zeroGrob.360]
19 18 ( 2- 2, 2- 2)        tag              zeroGrob[plot.tag..zeroGrob.359]

Используя пакет grid, я теперь могу реорганизовать свой макет и перерисовать часть grobs из моего графика:

grid.newpage()
grid.rect()
layout1 <- grid.layout(nrow = 3, ncol = 3,
                       heights = unit(1, c("lines", "null", "lines")),
                       widths = unit(1, c("lines", "null", "lines")))
pushViewport(viewport(layout = layout1))

pushViewport(viewport(layout.pos.row = 2, layout.pos.col = 2))
grid.draw(gg_grod$grobs[[(1:length(gg_grod$grobs))[gg_grod$layout$name=="panel"]]])

Что дает:

enter image description here

Пока это хорошо, но теперь я хочу извлечь легенду, изменить ее (например, удалив фактор "a" и изменив цвет фактора "b") и разместить где-нибудь еще на графике. .

Я пробовал:

grid.remove(gg_grod$grobs[[15]]$grobs[[1]]$grobs[[4]])
grid.edit(gg_grod$grobs[[15]]$grobs[[1]]$grobs[[7]], gp=gpar(col="pink"))

И это не работает, что имеет смысл, потому что grid.remove и grid.edit требуют gPath объекта. Однако я не могу найти этот путь.

Используя пример из вики ggplot2, предполагается, что это можно решить с помощью функции grid.ls, однако, похоже, что вывод теперь очень ограничен:

grid.ls(gg_grod)
layout

Я могу нарисовать неизмененную легенду, используя:

grid.draw(gg_grod$grobs[[15]]$grobs[[1]])

enter image description here

Есть идеи, как использовать grid.remove и grid.edit из объекта ggplot2, извлеченного с помощью ggplotGrob?

Кстати, выполнение примера из учебника теперь выдает ошибку:

grid.remove(gPath("GRID.gTree","layout","panel","grill.gTree","panel.grid.major.x.polyline"),grep=T)
Error in removeDLFromGPath(gPath, name, strict, greppath, grepname, global,  : 
  gPath (GRID.gTree::layout::panel::grill.gTree::panel.grid.major.x.polyline) not found

P.S. Я не думаю, что это необходимо, но я хочу подчеркнуть тот факт, что я хочу использовать пакет grid. Могут быть другие варианты и пакеты для решения подобных проблем, но в моем случае я хочу использовать и изучить пакет grid. Моя настоящая проблема также сложнее, чем этот тривиальный пример. Спасибо.

...