[R] Second y-axis in xyplot (lattice) where y1 and y2 have different ranges

Deepayan Sarkar deepayan.sarkar at gmail.com
Tue Jun 19 00:09:22 CEST 2007


On 6/18/07, Andy Bunn <Andy.Bunn at wwu.edu> wrote:
> Hi all,
>
> I realize this is asking a lot of lattice, but I want to add a second y
> axis inside a xyplot and have y1 and y2 have different ranges. Given dat
> below, I can add a second y axis by overlaying a new plot with
> par(new=T) and label axis 4 with standard graphics. I've seen an example
> for doing something similar in xyplot even though Deepayan has indicated
> that lattice isn't the right tool for the job.
>
> However, is there a way to gracefully add a second y-axis to a xyplot
> where y1 and y2 have different scales as in the example below? I've seen
> the experimental tools to focus and modify lattice graphics but do not
> know if these are applicable.

You could use those, but one drawback there is that you don't get the
usual benefit of automatic allocation of space. Here is a ``better''
solution (as long as you realize that this is still a hack):

[Note: this won't work if scales="free" or "sliced"]

[...]

>   dat2 <- data.frame(Year = rep(1751:2000,2),
>                      Stuff = rep(rnorm(250),2),
>                      Samples = rep(floor(seq(5,30,length.out=250)+
>                        rnorm(250,5)),2),
>                      Grp = c(rep('SiteOne',250),
>                              rep('SiteTwo',250)))



scale.pars <- function(x)
{
    c(mx = min(x), dx = diff(range(x)))
}

rescale <- function(x, pars = scale.pars(x))
{
    (x - pars["mx"]) / pars["dx"]
}

pars.Stuff <- scale.pars(dat2$Stuff)
pars.Samples <- scale.pars(dat2$Samples)

rng.Stuff <- range(dat2$Stuff)
rng.Samples <- range(dat2$Samples)


my.yscale.components <- function(lim, ...)
{
    ## template we will modify
    ans <- yscale.components.default(lim, ...)
    ## labels for Stuff in original scale
    Stuff <- yscale.components.default(rng.Stuff, ...)
    Stuff$left$ticks$at <-
        rescale(Stuff$left$ticks$at, pars.Stuff)
    Stuff$left$labels$at <-
        rescale(Stuff$left$labels$at, pars.Stuff)
    ## labels for Samples in original scale
    Samples <- yscale.components.default(rng.Samples, ...)
    Samples$left$ticks$at <-
        rescale(Samples$left$ticks$at, pars.Samples)
    Samples$left$labels$at <-
        rescale(Samples$left$labels$at, pars.Samples)
    ## modified 'components'
    ans$left <- Stuff$left
    ans$right <- Samples$left
    ans
}


xyplot(rescale(Stuff, pars.Stuff) +
           rescale(Samples, pars.Samples) ~ Year | Grp,
       data=dat2,
       panel = panel.superpose.2,

       ## newlay added:
       yscale.components = my.yscale.components,
       scales = list(alternating = 3),

       ylab = "Stuff",
       legend = list(right =
       list(fun = grid::textGrob("Samples", rot = 90))),
       type = c('l', 'l'))


-Deepayan



More information about the R-help mailing list