Reputation: 1737
I am making a graphic using grid, and want to draw some text. I ran into an issue when specifying the coordinates of the text.
Specifically, I found out that I can use both a straight unit, such as unit(1, "native")
and an expression that evaluates to a unit, such as unit(1, "native") + unit(1, "mm")
. But as soon as I have two native units in the expression, the text is plotted not where I expect it, but in a position which might be using npc units.
In the following MWE, I would expect "3" to be printed to the right of the middle (0 in native units), but it is printed far to the left.
require(grid)
grid.newpage()
vp.data.region <- viewport(x = unit(0.5, "npc"), y = unit(0.5, "npc"), width = unit(0.8, "npc"), height = unit(0.8, "npc"), xscale=c(-1,1), yscale=c(-1,1), name = "data region")
pushViewport(vp.data.region)
grid.xaxis()
grid.yaxis()
grid.text("1", unit(0, "native"),unit(0, "native")) #places the text where it should be
grid.text("2", unit(0, "native") + unit(10, "mm"), unit(0, "native")) # it is possible to use an expression adding mixed units
grid.text("3", unit(0.6, "native") - unit(0.5, "native") + unit(1, "mm") , unit(0, "native")) # suddenly, it looks like the unit expression is being interpreted as npc?
What causes this problem, and how can I avoid it? Note that it would be very difficult to specify the unit with a single expression, because I start with a point already specified as native units plus some millimeters, and have to position the text a certain distance from it, which I have to again calculate using both native units and millimeters.
Upvotes: 1
Views: 68
Reputation: 206177
Basically the primary units for the calculation are the npc
units. When addition/subtraction occurs, each value is convert to npc
units. We can use the convertX
function to see how these values pan out. When you use native units, those values are mapped to npc
units via the xscale=
values. Note that
convertX(unit(0.6, "native"), "npc")
# [1] 0.8npc
convertX(unit(0.5, "native"), "npc")
# [1] 0.75npc
convertX(unit(0.6, "native") - unit(0.5, "native"), "npc")
# [1] 0.0499999999999999npc
compared to
convertX(unit(0.1, "native"), "npc")
# [1] 0.55npc
You can't do atritmetic in native space using npc
coordinates. If you need to calculate 0.5 native units to the left of 0.6, then you need to do that arithmatic in native space
convertX(unit(0.6 - 0.5, "native"), "npc")
# [1] 0.55npc
If for some reason you can't do that, then you can make a function that takes a unit and a shift and does the arithmetic on that scale. For example
nativeShift <- function(unit, shift) {
stopifnot(class(unit)=="unit")
stopifnot(attr(unit, "unit")=="native")
stopifnot(is.numeric(shift))
unit(unclass(unit) + shift, "native")
}
convertX(nativeShift(unit(.6, "native"), -.5), "npc")
# [1] 0.55npc
With your plotting example that would look like
grid.text("3", nativeShift(unit(0.6, "native"), -0.5) + unit(1, "mm") , unit(0, "native"))
Upvotes: 1