[R] Lattice: shifting strips to left of axes

deepayan.sarkar at gmail.com deepayan.sarkar at gmail.com
Tue Jul 3 19:53:34 CEST 2007


On 7/3/07, Michael Hoffman <b3i4old02 at sneakemail.com> wrote:
> deepayan.sarkar at gmail.com wrote:
> > On 7/2/07, Michael Hoffman <b3i4old02 at sneakemail.com> wrote:
> >> Consider this plot:
> >>
> >> xyplot(mpg ~ disp | cyl, mtcars, strip=F, strip.left=T, layout=c(1, 3),
> >>         scales=list(relation="free"),
> >>         par.settings=list(strip.background=list(col="transparent")))
> >>
> >> I want to have the "cyl" strip labels on the left side of the axis. Is
> >> this possible?
> >
> > No. (It's possible to have a legend there, which could be used to put
> > row-specific ylab-s, for example, but it will be hard to make it look
> > like strips)
>
> Thanks for the response.
>
> Not looking like a real strip is fine. What I want is essentially a
> secondary ylab for each row, and don't care about niceties such as
> shingle markings (I should have made the conditional factor(cyl) in the
> above plot).

I thought this might be the case.

> But it looks like the legend goes to the left of the plot's ylab, and
> what I really want is for the secondary ylab to be between the primary
> ylab and the panel. So looks like I would have to eliminate the primary
> ylab from being drawn automatically and draw it myself in the legend?
> And I think I would have to manually calculate the panel heights as
> well, right? I don't see a way for the legend to get this out of the
> trellis object.

It's possible, although it requires some advanced grid features.
Luckily, this has come up before (search the r-help archives for
"myXlabGrob"). Basically, you can use the fact that 'ylab' can be a
"grob" to get what you want (I think). Here is a modified version of
the original function (adapted to include a 'primary' ylab):


library(grid)
library(lattice)

myYlabGrob <-
    function(..., main.ylab = "") ## ...is lab1, lab2, etc
{
    ## you can add arguments to textGrob for more control
    ## in the next line
    labs <- lapply(list(...), textGrob, rot=90)
    main.ylab <- textGrob(main.ylab, rot = 90)
    nlabs <- length(labs)
    lab.heights <-
        lapply(labs,
               function(lab) unit(1, "grobheight",
                                  data=list(lab)))
    unit1 <- unit(1.2, "grobheight", data = list(main.ylab))
    unit2 <- do.call(max, lab.heights)
    lab.layout <-
        grid.layout(ncol = 2, nrow = nlabs,
                    heights = unit(1, "null"),
                    widths = unit.c(unit1, unit2),
                    respect = TRUE)
    lab.gf <- frameGrob(layout=lab.layout)
    for (i in seq_len(nlabs))
    {
        lab.gf <- placeGrob(lab.gf, labs[[i]], row = i, col = 2)
    }
    lab.gf <- placeGrob(lab.gf, main.ylab, col = 1)
    lab.gf
}

xyplot(mpg ~ disp | cyl, mtcars, strip=F, strip.left=F, layout=c(1, 3),
       scales=list(relation="free"),
       ylab = myYlabGrob("4", "6", "8", main.ylab = "mpg"))

-Deepayan



More information about the R-help mailing list