Skip to content

Custom axis function in lattice:::xyplot

4 messages · Gavin Simpson, Peter Ehlers, Deepayan Sarkar

#
Dear List,

I have been writing a Lattice function to draw what we call
stratigraphic diagrams, these are diagrams with a panel for each species
showing a time series of abundance, but drawn vertically to represent
time passing from bottom of plot towards to top.

I am most of the way there with this now, but I want to do away with the
strip on each panel and instead draw a custom top axis with a single
tick mark (situated at the panel midpoint) with label equal to that
which would be used for the strip text. I can do all of this except get
the correct label. How do I get access to the factor level being plotted
in each panel within my custom axis function?

It may be easier to illustrate than explain, so here is a dummy example,
including a version of my custom axis function.

require(lattice)

## custom axis function
axis.VarLabs <- function(side, ...) {
    if(isTRUE(all.equal(side, "top"))) {
        M <- function(lims) min(lims) + (diff(lims) / 2)
        xlim <- current.panel.limits()$xlim
        panel.axis(side = side, outside = TRUE, at = M(xlim),
                   tck = 1, line.col = "black",
                   text.col = "black", rot = 45)
    } else {
        axis.default(side = side, ...)
    }
}

## demo data
set.seed(123)
dat <- data.frame(X = rnorm(1000), Y = rpois(1000, 2),
                  fac = sample(gl(4, 500, labels = LETTERS[1:4])))
head(dat)
str(dat)

## xyplot with custom axis --- note I leave the strip on here to show
## that I want the labels to be A, B, C, D on the top axis ticks...
xyplot(Y ~ X | fac, data = dat, axis = axis.VarLabs, layout = c(4,1,1))

Notice how in this plot, because I have not specified a label the 'at'
value for this point is used. Is there a way to get at the factor levels
from within an axis function? If so, how?

Secondly, how do you ensure there is enough space around the plot to
draw the axis labels without truncation - as can be seen on the example
xyplot.

Thanks in advance,

Gavin
#
On 2010-05-26 4:03, Gavin Simpson wrote:
# There must a better way, but this works; add

   labels = levels(dat$fac)[panel.number()],

# to your panel.axis() call in axis.VarLabs.
# Look at the settings for layout.heights, especially
# axis.top and top.padding:

  xyplot(....,
     par.settings = list(layout.heights =
         list(axis.top = xxx,
              top.padding = xxx)))

# (Shouldn't need both; I don't know which is more
# suitable for you.)

   -Peter Ehlers
#
On Wed, May 26, 2010 at 10:20 AM, Peter Ehlers <ehlers at ucalgary.ca> wrote:
More generally, which.packet() will give you the current indices of
all the conditioning variables. There is no direct access to the
levels, so you need to pass that in separately.

You might also consider this alternative:

set.seed(123)
## longer labels
dat <- data.frame(X = rnorm(1000), Y = rpois(1000, 2),
                  fac = sample(gl(4, 500, labels = month.name[1:4])))

require(grid)

xyplot(Y ~ X | fac, data = dat, strip = FALSE,
       scales = list(x = list(alternating = FALSE, tck = c(1, 0))),
       legend = list(top = list(fun = textGrob(levels(dat$fac),
                                               x = seq(0.125, 0.875,
length = 4),
                                               rot = 45))),
       layout = c(4,1,1))


-Deepayan
#
<snip />
Thanks Peter. I had tried that but it didn't work. Now just realised I
was hitting a scoping problem and that my example was subtly different
to the real world problem. In the real world situation I had
axis.VarLabs defined outside of the actual plotting function and the
xyplot call was being arranged by the plotting function. Hence I was
getting an error with the suggestion you sent along lines of

Error in levels(dat$fac) : object 'dat' not found

Moving axis.VarLabs to be defined locally within my plotting function
solves this problem and is goo enough for me.

So many thanks Peter; I've been banging my head on this one for a couple
of days now [although I have taken the opportunity to read a lot more of
Deepayan's excellent Lattice book whilst trying to sort this all out].

<snip />
Will take a look at this and Deepayan's legend suggestion to see which
suits best.

Cheers,

All the best,

G