Search code examples
rlatticer-grid

adding grid units in the native coordinate system


I am creating lattice figures and annotating them with the grid package. To set coordinates for my figures, I use unit() and related functions from the grid package. It often helps to add units together, and this is typically no problem. But I find that a strange problem arises when I try to add native units and the x- and y-scales for the current viewport don't have a lower bound of 0. Here is a small example:

library(grid)
library(lattice)

# Expected result
xyplot(0:10 ~ 0:10, ylim=c(0,10))
myVP <- seekViewport("plot_01.panel.1.1.vp")  
y1   <- unit(5, "native") + unit(2.5, "native")
convertY(y1, "native")  # 7.5native, as expected

# Strange result
xyplot(10:20 ~ 0:10, ylim = c(10:20))
myVP <- seekViewport("plot_01.panel.1.1.vp")  
y2   <- unit(10, "native") + unit(5, "native")
convertY(y2, "native")  # 5native (why not 15native?)

# Other results with same lattice plot are as expected
convertY(unit(10, "npc")    + unit(5, "npc"), "npc")     # 15npc
convertY(unit(10, "mm")     + unit(5, "mm"),  "mm")      # 15mm
convertY(unit(10, "native") + unit(5, "mm"),  "native")  # ~10.35native

Further investigation reveals that unit() is subtracting min(ylim) when it does addition in native units. So, in this example, I expect that unit(10, "native") + unit(5, "native") will yield a unit of 15native, but it really yields a unit of (15-10)native.

Why does unit addition work this way with the native coordinate system, and why does it work a different way with other coordinate systems?


Solution

  • Josh O'Brien points to the answer in his comments, and Paul Murrell's "locndimn" vignette (run vignette("locdimn") provides the details. A quantity like unit(5, "native") has one meaning if refers to a location in the coordinate system, and a different meaning if it refers to a dimension. Murrell's rule is that "locations are added like vectors and dimensions are added like lengths," and this seems to account for the results that I got when adding units in the native coordinate system.

    Specifically, in my example, using convertHeight produces the result that I expected:

    library(lattice)
    xyplot(10:20 ~ 0:10, ylim = c(10:20))
    myVP <- seekViewport("plot_01.panel.1.1.vp")  
    y2   <- unit(10, "native") + unit(5, "native")
    convertY(y2, "native")       #  5native 
    convertHeight(y2, "native")  # 15native