Search code examples
rggplot2gtable

Absolute positioning of rasterGrobs in gtable cells


I have been attempting to specify absolute positions for rasterGrobs in gtable cells without success. I would like to be able to have the extents of an image align to values on the y axis. The script aligns drill-core images alongside multi-sensor data plotted in ggplot2 facets. For example, a particular radiograph core image needs to have its top at 192 mm, and bottom at 1482 mm, but I want the scale to go from 0 to 1523 mm. Please see the included link for an example of what I am doing, but for simplicity I have only posted an MWE here. Is it possible to specify an absolute position for a rasterGrob inside a gtable cell?

sample of intended output

In terms of the MWE below, my only solution thus far has been to move Rlogo.png around using relative positions set when using rasterGrob(). Using "native" coordinates does not appear to be what I need either. Similarly, I can't make sense of the position parameters called in gtable_add_grob().

library(png)
library(ggplot2)
library(gtable)

# read Image
img <- readPNG(system.file("img", "Rlogo.png", package = "png"))

# convert to rastergrob                 
g <- rasterGrob(img, y = unit(0.5, "npc"), x = unit(0.5, "npc"))

# create plot
tp <- qplot(1:5, 1:5, geom="blank") + scale_y_reverse()

# convert plot to gtable
tt <- ggplot_gtable(ggplot_build(tp))

# add column to gtable to hold image
tt <- gtable_add_cols(tt, tt$width[[.5*4]], 3)

# add grob to cell 3, 4
tt <- gtable_add_grob(tt,g,3,4)

# render
grid.draw(tt)

Plot produced by code above

Did a lot of searching before coming up with this solution of using rasterGrob to add images to panels in a ggplot. Perhaps though there is a more elegant solution someone can suggest?


Solution

  • The grob can set its position within a cell, as illustrated below

    library(gridExtra)
    library(grid)
    library(gtable)
    
    # quick shortcut to create a 2x2 gtable filled with 4 rectGrobs
    tg <- arrangeGrob(grobs=replicate(4, rectGrob(), FALSE))
    
    # red rect of fixed size with default position (0.5, 0.5) npc
    rg1 <- rasterGrob("red", width=unit(1,"cm"), height=unit(1,"cm"))
    # blue rect with specific x position (0) npc, left-justified
    rg2 <- rasterGrob("blue", width=unit(1,"cm"), height=unit(1,"cm"), 
                      x = 0, hjust=0)
    # green rect at x = 1cm left-justified, y=-0.5cm from middle, top-justified
    rg3 <- rasterGrob("green", width=unit(1,"cm"), height=unit(1,"cm"), 
                      x = unit(1,"cm"), y=unit(0.5, "npc") - unit(0.5, "cm"), 
                      hjust=0, vjust=1)
    
    # place those on top 
    tg <- gtable_add_grob(tg, rg1, 1, 2, z = Inf, name = "default")
    tg <- gtable_add_grob(tg, rg2, 1, 2, z = Inf, name = "left")
    tg <- gtable_add_grob(tg, rg3, 1, 2, z = Inf, name = "custom")
    grid.newpage()
    grid.draw(tg)
    

    enter image description here