2

I made a grid, I drew some lines between each cell. I want text in the upper lefthand corner of a cell, but I can only get alignment relative to the cell's center.

I've spent a lot of time searching, and this is the closest I could find is What do hjust and vjust do when making a plot using ggplot?. The [0,1] values of hjust and vjust align the text in reference to the points in this example, and on a grid (using grid.text) they align the text relative to the center of the cell. I've tried values of hvjust outside of [0,1] with no luck; I've tried using decimal places when specifying the row/column (1.5 should be between row 1 and 2 right?) for text placement, but the decimals just get rounded. I can't align by hand because my script should be aligning many names of variable length.

Code to layout the grid:

grid.newpage()
pushViewport(viewport(layout=grid.layout(29+1,7, heights = unit(rep(1, 
    (29+1), "null"), widths=unit(c(1,.5,.5,.5,1,1,1), "null"))))
grid.polyline(x=c(0,0,1,1,1.5,1.5,2,2,2.5,2.5,3.5,3.5,4.5,4.5,5.5,5.5)/5.5, y=rep(c(0,1), 8), id.lengths=rep(2,8))
grid.polyline(x=rep(c(0,1), 29+2), y=sort(rep(0:(29+1), 2)/(29+1)), id.lengths=rep(2,29+2))

Assume the 29s are variable numbers, I had to change them from something more specific. If the code doesn't layout the grid, I must've deleted an extra parenthesis. The only other code I have just places text in the near center of a cell of the grid.

My goal is to place text so that the first letter is in the upper left corner next to the gridlines. Any guidance is greatly appreciated.

Community
  • 1
  • 1
Torin T
  • 59
  • 1
  • 6

1 Answers1

0

You may find it easier to work with a gtable, in which case each label can be centred within its own cell. Otherwise, with your strategy, you'd need to keep track of all x and y positions (or define as many individual viewports, but that's essentially what gtable does on top of grid).

Here's an example (I used tableGrob to set up the gtable only for convenience),

library(gtable)
library(gridExtra)
g <- tableGrob(matrix("", 29+1, 7), theme = ttheme_minimal())
g$widths <- unit(c(1,.5,.5,.5,1,1,1), "null")
g$heights <- unit(rep(1, (29+1)), "null")
vs <- replicate(ncol(g)-1,
                        segmentsGrob(x1 = unit(0, "npc"), gp=gpar(lwd=0.5)),
                        simplify=FALSE)
hs <- replicate(nrow(g)-1,
                        segmentsGrob(y1 = unit(0, "npc"), gp=gpar(lwd=0.5)),
                        simplify=FALSE)
g <- gtable::gtable_add_grob(g, grobs = vs,
                             t = 1, b = nrow(g), l = seq_len(ncol(g)-1)+1)
g <- gtable::gtable_add_grob(g, grobs = hs,
                             l = 1, r = ncol(g), t = seq_len(nrow(g)-1))
labels <- list(textGrob("l", hjust=0, x=0), 
               textGrob("c", hjust=0.5, x=0.5), 
               textGrob("r", hjust=1, x=1))
g <- gtable_add_grob(g, labels, t=c(1,2,3), l=c(2, 4, 7), z = -1)
grid.newpage()
grid.draw(g)

enter image description here

Note that this strategy is however very inefficient, because it doesn't make use of vectorised grobs (instead individual grobs are placed). For a small enough table it may not matter, and the gain in convenience can be worthwhile. See this wiki page for further examples of gtable processing.

baptiste
  • 75,767
  • 19
  • 198
  • 294