[R] shared axes in multipanel plot

Gabor Grothendieck ggrothendieck at gmail.com
Tue Dec 15 00:15:42 CET 2009


Good observation.  In fact, panel.plot.default works because it uses
the subscripts and groups variables which are passed down to the panel
function and if not explicitly referenced in the formal argument list
of pnl are passed via ... thus we could use any of these equivalent
pnl functions though the prior solution using unique seems the
shortest:

# using groups
pick out x components corresponding to group 1
pnl <- function(x, ..., groups) {
   panel.plot.default(x, ..., groups)
   ix <- which(groups == 1)
   panel.lines(x[ix], b2, lwd = 2, col = grey(0.5))
}

# using groups and subscripts
pnl <- function(x, y, subscripts, ..., groups) {
   panel.plot.default(x, y, subscripts, ..., groups)
   tt <- x[groups[subscripts] == 1]
   panel.lines(tt, b2, lwd = 2, col = grey(0.5))
}

# trim x to length of b2
pnl <- function(x, ...) {
   panel.plot.default(x, ...)
   tt <- head(x, length(b2))
   panel.lines(tt, b2, lwd = 2, col = grey(0.5))
}

# unique
pnl <- function(x, ...) {
   panel.plot.default(x, ...)
   tt <- unique(x)
   panel.lines(tt, b2, lwd = 2, col = grey(0.5))
}


baseline <- (1:20)/20
dat1 <- matrix(baseline,20,8)
dat <- dat1+matrix(rnorm(20*8)/30, 20,8)
b2<-sqrt(baseline)
nc <- ncol(dat)
screens <- rep(1:(nc/2), each = 2)
z <- zoo(dat)
colnames(z) <- paste("Group", screens)
xyplot(z, screens = screens , layout = c(2, 2), col = "black", lty = 2,
   scales = list(y = list(relation = "same")), panel = pnl)




On Mon, Dec 14, 2009 at 5:21 PM, Jennifer Young
<Jennifer.Young at math.mcmaster.ca> wrote:
> Ah, I think i see the problem.
> The default plot recognizes there is one set of x for each set of y, but
> since there were two vectors in the default.plot, the x vector is repeated
> and loops around for the lines part.  Presumably the default plot uses
> your recursive plot automatically.
>
> At any rate, it seems that this simpler version (with your unique(x)
> solution) also works and avoids the recursion.
>
>    pnl <- function(x, y, ...) {
>
>        tt <- unique(x)
>        panel.plot.default(x,y, ...)
>        panel.lines(tt, baseline, lwd = 2, col = grey(0.5))
>
>    }
>
> Thanks for your time!!
>
>> One resolution of the need to go outside of pnl would be to use this line:
>>
>> tt <- unique(x)
>>
>> in place of tt <- time(z).  That would overcome the objection that the
>> pnl function is not self contained.
>>
>> On Mon, Dec 14, 2009 at 3:44 PM, Gabor Grothendieck
>> <ggrothendieck at gmail.com> wrote:
>>> Try this:
>>> You seem to have found a problem.  At any rate try this instead:
>>>
>>> pnl <- function(x, y, ...) {
>>>   tt <- time(z)
>>>   y <- matrix(y, length(tt))
>>>   for(j in 1:ncol(y)) panel.plot.default(tt, y[,j], ...)
>>>   panel.lines(tt, baseline, lwd = 2, col = grey(0.5))
>>>   panel.lines(tt, b2)
>>> }
>>>
>>> On Mon, Dec 14, 2009 at 3:19 PM, Jennifer Young
>>> <Jennifer.Young at math.mcmaster.ca> wrote:
>>>>> On Mon, Dec 14, 2009 at 11:30 AM, Jennifer Young
>>>>> <Jennifer.Young at math.mcmaster.ca> wrote:
>>>>>> splendid!
>>>>>>
>>>>>> This worked well, but there are two oddities that I can't resolve.
>>>>>>
>>>>>> 1. In the real data, the "baseline" is a cumulative probability plot
>>>>>> (from
>>>>>> simulations) rather than the straight line.  The panel.lines plots
>>>>>> this
>>>>>> curve, but seems to join the first and last points together.
>>>>>> panel.points(x, baseline, type="l") did the same.
>>>>>> I checked that the vector is indeed sorted properly, so I'm not sure
>>>>>> why
>>>>>> it should connect the first point to the last.
>>>>>
>>>>> I can't reproduce the problem based on this description.
>>>>
>>>> sorry that was lazy of me. If you modify the code you gave me as
>>>> follows
>>>> (with an extra line of the sqare root of "baseline", as an example) the
>>>> first and last points are joined. I didn't notice this before when
>>>> "baseline" was just a line.
>>>>
>>>> baseline <- (1:20)/20
>>>> dat1 <- matrix(baseline,20,8)
>>>> dat <- dat1+matrix(rnorm(20*8)/30, 20,8)
>>>> b2<-sqrt(baseline)
>>>> pnl <- function(x, ...) {
>>>>        panel.plot.default(x, ...)
>>>>        panel.lines(x, baseline, lwd = 2, col = grey(0.5))
>>>>        panel.lines(x, b2)
>>>> }
>>>> nc <- ncol(dat)
>>>> screens <- rep(1:(nc/2), each = 2)
>>>> z <- zoo(dat)
>>>> colnames(z) <- paste("Group", screens)
>>>> xyplot(z, screens = screens , layout = c(2, 2), col = "black", lty =
>>>> 2, scales = list(y = list(relation = "same")), panel = pnl)
>>>>
>>>>
>>>>>
>>>>>>
>>>>>> 2. The screens are correctly labeled, but in the wrong order (left to
>>>>>> right, top to bottom: 3,4,1,2). Is this easily corrected?
>>>>>
>>>>> xyplot(..., as.table = TRUE) will give one reordering.
>>>>>
>>>>> Another possibility is:
>>>>>    plt <- xplot(...)
>>>>>    plt[ix]
>>>>> where ix is a permutation of 1:4
>>>>>
>>>>>>
>>>>
>>>> as.table=TRUE did the trick thanks.
>>>>
>>>
>>
>
>




More information about the R-help mailing list