[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):


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 <-
               function(lab) unit(1, "grobheight",
    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)

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


More information about the R-help mailing list