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?
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