Re: [Rd] Two submitted packages

From: Deepayan Sarkar <deepayan.sarkar_at_gmail.com>
Date: Wed 06 Sep 2006 - 03:28:57 GMT

On 9/5/06, Richard M. Heiberger <rmh@temple.edu> wrote:
> Deepayan wrote:
>
> > > xyplot(y ~ x | a,
> > > data=tmp, ylim=c(1.5,4.5),
> > > par.settings = list(clip = list(panel = "off")),
> > > layout=c(2,2))
> >
> > I'm curious to know why this functionality is not enough.
>
>
> ## 1. Here is a more realistic example.
>
> tmp <- data.frame(x=1:5, y=1:5, a=factor(c(1,1,1,1,1), levels=1:4))
>
> ## This gives what I want.
> ## It looks like the upViewport/downViewport sequence is the control I
> ## should be using. If this is a stable sequence, it answers my needs.
> xyplot(y ~ x,
> data=tmp, ylim=c(1.5,4.5),
> panel=function(...) {
> panel.xyplot(...)
> upViewport()
> downViewport(trellis.vpname("panel",
> row = 1, column = 1, clip.off = TRUE))
> panel.axis(side="right", outside=TRUE)
> },
> layout=c(2,2),
> main="right axis visible by control, points clipped by default")
>
> ## If I turned off clipping at the top, I would get the unwanted points
> ## plotted outside the figure region.
> xyplot(y ~ x,
> data=tmp, ylim=c(1.5,4.5),
> par.settings = list(clip = list(panel = "off")),
> panel=function(...) {
> panel.xyplot(...)
> panel.axis(side="right", outside=TRUE)
> },
> layout=c(2,2),
> main="right axis visible by control, points not clipped")

I see.

> ## This doesn't work, but it illustrates the syntax I would like.
> xyplot(y ~ x,
> data=tmp, ylim=c(1.5,4.5),
> panel=function(...) {
> panel.xyplot(...)
> panel.axis(side="right", outside=TRUE, clip="off")
> },
> layout=c(2,2),
> main="right axis visible by control, points clipped by default")

This might be possible, but there is a potential for unanticipated problems. On the other hand, it's easy to achieve the equivalent of this with a couple of extra lines, e.g.

xyplot(y ~ x,

       data=tmp, ylim=c(1.5,4.5),
       panel=function(...) {
           cpl <- current.panel.limits()
           panel.xyplot(...)
           pushViewport(viewport(xscale = cpl$xlim,
                                 yscale = cpl$ylim,
                                 clip = "off"))
           ## put anything you want unclipped inside this:
           panel.axis(side="right", outside=TRUE)
           ## end of unclipped part
           upViewport()
       },
       layout=c(2,2))

This already works, and should be stable, but I'm not sure; Paul has previously mentioned this feature that an unclipped viewport inside a clipped viewport allows plotting outside the clipped one, but I don't know if that's intentional. Even if this behaviour does change, the opposite should be stable: turn off clipping globally and then insert the part of the panel function you want clipped into a clipped viewport, e.g.:

xyplot(y ~ x,

       data=tmp, ylim=c(1.5,4.5),
       par.settings = list(clip = list(panel = "off")),
       panel=function(...) {
           cpl <- current.panel.limits()
           pushViewport(viewport(xscale = cpl$xlim,
                                 yscale = cpl$ylim,
                                 clip = "on"))
           panel.xyplot(...)
           upViewport()
           panel.axis(side="right", outside=TRUE)
       },
       layout=c(2,2))

> ## 2
> > Unfortunately, there is currently no easy way to find out which column
> > and row the current panel occupies. I plan to make some changes before
> > R 2.4.0 is released that should expose that information, so please try
> > again in a few weeks.
>
> The way I have been using is to back up the calling sequence and
> use statements like
> {
> ## This loop is needed because
> ## console usage has i=2,
> ## Rcmdr script window has i=5,
> ## Rcmdr justDoIt has i=20
> for (i in seq(2, length=30)) {
> sf2 <- sys.frame(i)
> column.tmp <- try(get("column", pos=sf2), silent=TRUE)
> if (class(column.tmp) != "try-error") break
> }
> if (class(column.tmp) == "try-error")
> stop("panel.interaction2wt is too deeply nested in the system stack.")
> row <- get("row", pos=sf2)
> column <- get("column", pos=sf2)
> cols.per.page <- get("cols.per.page", pos=sf2)
> rows.per.page <- get("rows.per.page", pos=sf2)
> }
>
> ## A cleaner way would be preferable. Will the above stay valid? The
> ## need for a loop to find out how far up the calling sequence to go
> ## caught me by surprise. I don't understand why generating commands
> ## the way Rcmdr does it should have an effect on the depth of the
> ## calling sequence.

I hope to add 3 new features before R 2.4.0, two of which are relevant for you: (1) more control over axis annotation and (2) an API to access auxiliary information (like row/column/layout) from inside a panel function. I should have a testable version in a week or so, after which I'll be happy to consider suggestions for further additions.

Deepayan



R-devel@r-project.org mailing list

https://stat.ethz.ch/mailman/listinfo/r-devel Received on Wed Sep 06 13:34:01 2006

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Wed 06 Sep 2006 - 11:39:30 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.