[R] Positioning in xyplot
Deepayan Sarkar
deepayan.sarkar at gmail.com
Wed Apr 11 22:55:30 CEST 2007
On 4/11/07, Sundar Dorai-Raj <sundar.dorai-raj at pdf.com> wrote:
> Seems like you may get a workaround (albeit kludgey) by using
> ?print.trellis. Here's another example:
>
> library(lattice)
> z <- expand.grid(x = 1:10, p = 1:5, r = 1:10)
> z$y <- rnorm(nrow(z))
> z$p <- factor(z$p, levels = c(1, 5, 2, 4, 3))
> bot <- xyplot(y ~ x | p, z, groups = r,
> layout = c(2, 2), type = "l",
> scales = list(alternating = 1),
> subset = p != 3)
> top <- xyplot(y ~ x | p, z, groups = r,
> type = "l", xlab = "",
> scales = list(alternating = 2),
> subset = p == 3)
>
> print(bot, c(0, 0, 1, 11/16))
> print(top, c(1/5, 7/12, 4/5, 1), newpage = FALSE)
Here's another hack (thanks to Sundar for the reproducible example):
library(grid)
## this is a safer version of current.panel.limits()
current.limits <-
function ()
{
xlim <- convertX(unit(c(0, 1), "npc"), "native", valueOnly = TRUE)
ylim <- convertY(unit(c(0, 1), "npc"), "native", valueOnly = TRUE)
if (any(!is.finite(xlim))) xlim <- c(0, 1)
if (any(!is.finite(ylim))) ylim <- c(0, 1)
list(xlim = xlim, ylim = ylim)
}
## this calls 'fun' after moving its viewport if panel.number() == 5
callAfterMoving <-
function(fun, border = TRUE, move.x = 1, ...)
{
if (panel.number() == 5) {
fun(...)
if (border) grid.rect()
}
else {
cpl <- current.limits()
pushViewport(viewport(x = move.x,
width = unit(1, "npc"),
xscale = cpl$xlim,
yscale = cpl$ylim,
clip = "off"))
fun(...)
if (border) grid.rect()
upViewport()
}
}
## this almost works, except for the axes on the left, because in the
## context in which it is drawn (the strip on the left, invisible in
## this example), information about how much to move right is not
## available.
xyplot(y ~ x | p, z, groups = r,
layout = c(2, 3), type = "l",
par.settings =
list(axis.line = list(col = "transparent"),
strip.border = list(col = "transparent")),
panel = function(...) {
callAfterMoving(panel.xyplot, ...)
},
strip = function(...) {
callAfterMoving(strip.default, ...)
},
axis = function(..., line.col) {
callAfterMoving(axis.default,
border = FALSE,
line.col = 'black',
...)
})
## one way to bail out is simply not draw the left axes. It can also be
## added back explicitly by adding a call to panel.axis inside the
## panel function (see below)
xyplot(y ~ x | p, z, groups = r,
layout = c(2, 3), type = "l",
par.settings =
list(axis.line = list(col = "transparent"),
strip.border = list(col = "transparent")),
panel = function(...) {
callAfterMoving(panel.xyplot, ...)
},
strip = function(...) {
callAfterMoving(strip.default, ...)
},
axis = function(..., line.col, side) {
if (side != "left" || panel.number() != 5) {
callAfterMoving(axis.default,
border = FALSE,
line.col = 'black',
side = side,
...)
}
})
## panel function with axes on the left:
panel.leftaxes <- function(...)
{
if (panel.number() == 5)
panel.axis("left", outside = TRUE,
line.col = "black")
panel.xyplot(...)
}
xyplot(y ~ x | p, z, groups = r,
layout = c(2, 3), type = "l",
par.settings =
list(axis.line = list(col = "transparent"),
strip.border = list(col = "transparent")),
panel = function(...) {
callAfterMoving(panel.leftaxes, ...)
},
strip = function(...) {
callAfterMoving(strip.default, ...)
},
axis = function(..., line.col, side) {
if (side != "left" || panel.number() != 5) {
callAfterMoving(axis.default,
border = FALSE,
line.col = 'black',
side = side,
...)
}
})
-Deepayan
More information about the R-help
mailing list