[R] Positioning in xyplot

Sundar Dorai-Raj sundar.dorai-raj at pdf.com
Wed Apr 11 23:40:16 CEST 2007



Deepayan Sarkar said the following on 4/11/2007 1:55 PM:
> 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

Hi, Deepayan,

See the attached image for what your code produced. Not sure if this is 
what you intended.

Thanks,

--sundar

 > sessionInfo()
R version 2.4.1 (2006-12-18)
i386-pc-mingw32

locale:
LC_COLLATE=English_United States.1252;LC_CTYPE=English_United 
States.1252;LC_MONETARY=English_United 
States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252

attached base packages:
[1] "grid"      "stats"     "graphics"  "grDevices" "utils"     "datasets"
[7] "methods"   "base"

other attached packages:
   lattice
"0.14-17"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: positioning_in_xyplot.png
Type: image/png
Size: 28527 bytes
Desc: not available
Url : https://stat.ethz.ch/pipermail/r-help/attachments/20070411/94405e62/attachment.png 


More information about the R-help mailing list