Search code examples
rr-gridgrob

R grid package: How to create a textGrob with multiple colors and position it in the center of a viewport


I need something like the following, but with a different color for each word in the String:

library(grid)

grid.newpage()
pushViewport(viewport(width = unit(5, 'cm'), height = unit(5, 'cm')))
grid.rect()
grid.text(label = 'Hello, World!')

I tried to create individual grobs for each segment an then group them together, but I cannot figure out how to position the result in the center of the viewport:

grid.newpage()
pushViewport(viewport(width = unit(5, 'cm'), height = unit(5, 'cm')))
grid.rect()

grouped_grobs <-
    gList(textGrob(label = 'Hello',
                   x = unit(0.0, 'npc'),
                   y = unit(0.5, 'npc'),
                   just = c('left', 'center'),
                   gp = gpar(col='red')),
          textGrob(label = ',',
                   x = unit(1, 'strwidth', data = 'Hello'),
                   y = unit(0.5, 'npc'),
                   just = c('left', 'center'),
                   gp = gpar(col='black')),
          textGrob(label = 'World',
                   x = unit(1, 'strwidth', data = 'Hello, '),
                   y = unit(0.5, 'npc'),
                   just = c('left', 'center'),
                   gp = gpar(col='blue')),
          textGrob(label = '!',
                   x = unit(1, 'strwidth', data = 'Hello, World'),
                   y = unit(0.5, 'npc'),
                   just = c('left', 'center'),
                   gp = gpar(col='black')))

grid.draw(grouped_grobs)

I tried measuring the width of the gList, I also tried using gTree but somehow I am stuck on this seemingly simple task.

Thanks in advance for any kind of help!


Solution

  • Drawing colored text is much easier with the gridtext package. For example

    grid.newpage()
    pushViewport(viewport(width = unit(5, 'cm'), height = unit(5, 'cm')))
    grid.rect()
    
    grid.draw(gridtext::richtext_grob(text = '<span style="color:red">Hello</span>, <span style="color:blue">World</span>!',
                 x = unit(0.5, 'npc'),
                 y = unit(0.5, 'npc'),
                 hjust=.5))
    

    Will return

    enter image description here