[R] multiple lattice, xyplot & levelplot on same page - solved

Ky Mathews k.mathews at usyd.edu.au
Wed Sep 30 13:38:17 CEST 2009


Felix,

Thanks for your suggestions below and all the behind-the-scenes email help.

For those who come after me on this issue.
Option (1) worked best for my purpose as it retained the levelplot() legend, and meant the y-axis were exactly aligned.

The trick was the following advice:
"If you are using c(), you need to give arguments like scales only to the first object in c(); most such settings for the second object will be ignored."

The 'correct' (i.e. gives me what I want ;-) ) code is below.
Two points to note:
1) I used subscripts = TRUE in the original use of xyplot(), removing the necessity for 
    p1 <- update(p1, subscripts = TRUE) (see email below)
2) Using c() in this way did rotate the y-labels to 90degrees, so I had to specify
  scales = list(y = list(rot=0))
to ensure the y-labels were plotted as they would be with levelplot() defaults.

Many thanks and regards,
Ky

#---------------------------------------------------------------------------
#Working code, xyplot levelplot on same page
library(lattice)
library(latticeExtra)
 
 #xyplot
 x1 <- 0:10
 x2 <- x1^2
 
 p1 <- xyplot(x2 ~ x1, 
              subscripts = TRUE,       
              panel = function(x,y,...){
                 panel.xyplot(x, y, 
                              type="l",
                  			      lwd=2)})
 
 #levelplot
 y.df <- data.frame(y1 = rep(x1, times = 3),
                   y2 = rep(c('E1', 'E2', 'E3'), each = length(x1)),
                   y3 = c(x1, x1+2, x1-1))
 p2 <- levelplot(y3 ~ y1*y2, data = y.df,
                 scales = list(y = list(rot = 0)),
                 colorkey =list(space='bottom'))

 update(c(p2, p1, x.same = TRUE),
        layout = c(1, 2),
        ylab = list(c("p2", "p1"), c(1/4, 3/4)))

-----Original Message-----
From: foolish.android at gmail.com [mailto:foolish.android at gmail.com] On Behalf Of Felix Andrews
Sent: Sunday, 27 September 2009 9:00 PM
To: Ky Mathews
Cc: r-help at r-project.org
Subject: Re: [R] multiple lattice, xyplot & levelplot on same page

Ky,

The error you report is a problem with the c() method for trellis
plots: it allows for a different panel function in each panel, but
only one prepanel function. Because of this, the
prepanel.default.levelplot function is not getting what it expects to
recompute the panel dimensions. It may be possible to extend the
function to handle this, but for now you have a few options:

(1) Set subscripts = TRUE in the xyplot:
    p1 <- update(p1, subscripts = TRUE)
    update(c(p2, p1, x.same = TRUE), layout = c(1, 2))

(2) Put the xyplot first, but then re-order the panels by indexing:
    update(c(p1, p2, x.same = TRUE), layout = c(1, 2))[2:1]

(3) Take out the x.same=TRUE argument, if you can set the x scales to
be the same beforehand. In your example, the xyplot and levelplot had
the same x axis limits anyway, but presumably that is not the case in
your real problem.
    update(c(p2, p1), layout = c(1, 2))

(4) Use a completely different mechanism: draw the two plots in the
desired position (after setting the x axes to be identical beforehand,
if desired). See ?plot.trellis
     This latter mechanism was designed in to trellis from the
beginning, whereas the c() method is basically a hack. It also has the
advantage of retaining complete control over each plot independently.


By the way, I can't understand what you are trying to do with the
par.settings$layout.width argument. It doesn't seem to have any
effect. Ditto for the 'y = c(1/4, 3/4))' argument.

> Also, I seem to have lost control of par settings such as las = 1

This is a "base graphics" (?par) parameter, which does not apply to
grid or lattice graphics. The equivalent of "las" in lattice is the
scales$rot argument. See ?xyplot

Hope that helps
-Felix


2009/9/26 Ky Mathews <k.mathews at usyd.edu.au>:
> Dear R-users,
>
> I'd like to place an xyplot() at the top of a page and a levelplot() at the bottom of the same page, and have the x-axes be the same.
>
> I've come close to finding a solution through Rarchive, and can produce an upside-down version of what I'd like (levelplot() on the top - see code below).
>
> However, the following error occurs when I try and plot the xyplot() at the top:
>
> "Error in prepanel.default.function(x = 0:10, y = c(0, 1, 4, 9, 16, 25,  :
>   element 1 is empty;
>    the part of the args list of 'length' being evaluated was:
>    (subscripts)"
>
> Any pointers in the right direction would be much appreciated.
>
> #OS: Windows XP 2002 SP3; R: 2.9.2; lattice 0.17-25; latticeExtra 0.6-1
>
> Thanks and regards,
> Ky
>
> ###########################################################
> #Rcode for xyplot and lattice plot on the same page.
> library(lattice)
> library(latticeExtra)
>
>  #xyplot
>  x1 <- 0:10
>  x2 <- x1^2
>
>  p1 <- xyplot(x2 ~ x1
>           , par.settings = list(layout.width = list(panel=1,  ylab = 2
>           , axis.left =1.0, left.padding=1
>           , ylab.axis.padding=1, axis.panel=1)))
>
>
>  #levelplot
>  y.df <- data.frame(y1 = rep(x1, times = 3)
>                   , y2 = rep(c('E1', 'E2', 'E3'), each = length(x1))
>                   , y3 = c(x1, x1+2, x1-1))
>  p2 <- levelplot(y3 ~ y1*y2, data = y.df,
>                 , par.settings = list(layout.width = list(panel=1,  ylab = 2
>                 , axis.left =1.0, left.padding=1
>                 , ylab.axis.padding=1, axis.panel=1)))
>
> #Printing the plots on the same page
> #This is what I found on an Rarchive post (thank-you)
>  #it works if the levelplot (p2) is at the top of the page
>  #i.e.
>   update(c(p1, p2, x.same = TRUE)
>            , layout = c(1, 2)
>            , ylab = list(c("p1", "p2")
>            , y = c(1/4, 3/4))
>            , par.settings = list(layout.heights = list(panel = c(1, 1))))
>
>  #however, the following error appears if the order is reversed (which is what I would like)
>  update(c(p2, p1, x.same = TRUE)
>            , layout = c(1, 2)
>            , ylab = list(c("p2", "p1")
>            , y = c(1/4, 3/4))
>            , par.settings = list(layout.heights = list(panel = c(1, 1))))
>
> The following error appears:
> #Error in prepanel.default.function(x = 0:10, y = c(0, 1, 4, 9, 16, 25,  :
> #  element 1 is empty;
> #   the part of the args list of 'length' being evaluated was:
> #   (subscripts)
>
> Also, I seem to have lost control of par settings such as las = 1
>
> #-----------------------------------------------------------
> Dr Ky L. Mathews
> Co-ordinator, CIMMYT ICARDA Communications Project
> Research Fellow,
> Plant Breeding Institute, The University of Sydney, Australia
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



-- 
Felix Andrews / 安福立
Postdoctoral Fellow
Integrated Catchment Assessment and Management (iCAM) Centre
Fenner School of Environment and Society [Bldg 48a]
The Australian National University
Canberra ACT 0200 Australia
M: +61 410 400 963
T: + 61 2 6125 1670
E: felix.andrews at anu.edu.au
CRICOS Provider No. 00120C
-- 
http://www.neurofractal.org/felix/


More information about the R-help mailing list