gtable_add_grob (): linesGrob () не отображается

Почему на следующем графике линии (через linesGrob) не нарисованы?

require(gtable)
base <- gtable(widths=unit(rep(1, 2), "null"),
               heights=unit(rep(1, 3), "null"))
grid.newpage()
g <- 1
for(i in 1:3) {
    for(j in 1:2) {
        base <- gtable_add_grob(base,
                                grobs=list(linesGrob(x=1:4, y=4:1),
                                           rectGrob(gp=gpar(fill="#FF0000")),
                                           textGrob(label=g)), i, j, name=1:3)
        g <- g+1
    }
}
grid.draw(base)

person Marius Hofert    schedule 03.08.2013    source источник


Ответы (1)


Две причины:

  • координаты выходят за пределы области просмотра

  • rectGrob рисуется сверху и маскирует его


require(gtable)
# let's fix this name before it's too late
gtable_add_grobs <- gtable_add_grob

base <- gtable(widths=unit(rep(1, 2), "null"),
               heights=unit(rep(1, 3), "null"))
grid.newpage()
g <- 1
for(i in 1:3) {
    for(j in 1:2) {
        base <- gtable_add_grobs(base,
                                grobs=list(rectGrob(gp=gpar(fill="#FF0000")),
                                           linesGrob(x=1:4, y=4:1, def="native", 
                                                     vp=dataViewport(1:4, 1:4)),
                                           textGrob(label=g)), i, j, name=1:3)
        g <- g+1
    }
}
grid.draw(base)

Примечание gtable_add_grobs векторизовано, что означает, что вам не нужно использовать циклы for, в идеале. Будет проще, если вы сначала сгруппируете все группы вместе для данной ячейки в gTree. Вот упрощенная версия,

library(gtable)

g <- gtable(widths = unit(c(1,1), "null"),
            heights = unit(c(1,1), "null"))


cell <- function(ii)
  grobTree(rectGrob(), 
           linesGrob(1:4, 1:4, default.units="native"), 
           textGrob(ii),
           vp=dataViewport(c(1,4), c(1,4)))

gl <- lapply(1:4, cell)

xy <- expand.grid(1:2, 1:2)

g <- gtable_add_grobs(g, gl, 
                      l=xy[,1],
                      r=xy[,1],
                      t=xy[,2],
                      b=xy[,2])


grid.newpage()
grid.draw(g)
person baptiste    schedule 03.08.2013
comment
Спасибо, Батист. Вторая причина понятна, но первая (?). Все окна просмотра имеют значение по умолчанию NULL, поэтому не следует рисовать точки просто в соответствующем прямоугольнике, как в случае открытия новой страницы. Это то, чего я еще не понимаю ... почему (и как) я должен указывать это ... В «классической» сетке я нажимал на область просмотра, и тогда это просто работало. - person Marius Hofert; 03.08.2013
comment
каждая ячейка таблицы gtable имеет область просмотра, и когда вы рисуете в ней гроб, вам нужно убедиться, что координаты соответствуют области просмотра. Базовый пример - grid.newpage(); grid.lines(x=1:4, y=4:1, default.units = "npc"): он ничего не рисует, потому что 1:4 интерпретируются как нормализованные координаты от 0 до 1. Вам нужно либо изменить масштаб ваших данных, либо указать область просмотра и работать с собственными координатами. - person baptiste; 03.08.2013
comment
спасибо за ответ, Батист. Решение с изменением масштаба данных также работает (но менее интуитивно / естественно). - person Marius Hofert; 03.08.2013
comment
@MariusHofert Я добавил более естественную версию, чтобы добавить несколько гробов за один раз, без циклов for. - person baptiste; 03.08.2013
comment
Большое спасибо, Батист, я посмотрю на него поближе. Обобщает ли некоторые части в gTree сначала необходимость использования разных имен для всех гробов в gTree? Причина, по которой я спрашиваю: stackoverflow.com/questions/18028920/, где предлагаемое решение использует разные имена для каждого rectGrob, _4 _..., что довольно утомительно. Я бы предпочел иметь одно имя, такое как панель, для всех rectGrob, textGrob и lineGrob вместе. - person Marius Hofert; 03.08.2013
comment
Я так считаю, но не уверен; Я тоже не понимаю требований к именованию. - person baptiste; 03.08.2013