I like the functionality provided by outer=TRUE, but when it comes time to place separate xlabs or ylabs, I always end up 'eyeballing' it on a case-by-case basis. For example, ##begin example require(lattice) cars.lo <- loess(dist ~ speed, cars) print(xyplot(cars.lo$residuals+cars.lo$fitted~cars.lo$x, strip=FALSE, outer=TRUE, layout=c(1,2), ylab="", scales=list(y=list(relation="free",rot=0)), panel=function(x,y,panel.number,...){ if(panel.number==1){ panel.xyplot(x,y) panel.abline(h=0) }else{ panel.xyplot(x,y=cars.lo$y) panel.xyplot(x,y,type="l") } })) require(grid) trellis.focus("panel", 1, 1, clip.off=TRUE, highlight=FALSE) grid.text("residuals", x=unit(0, "npc") + unit(-2, "lines"),rot=90) trellis.focus("panel", 1, 2, clip.off=TRUE, highlight=FALSE) grid.text("fitted", x=unit(0, "npc") + unit(-2, "lines"),rot=90) ## end example In this case, a distance of -2 lines happens to be enough, but one has to make the plot to know this. I'm interested in learning how one can place the ylabs without fear of overlapping the tick labels; i.e., how to use the exact space allocated by ylab="". I'm thinking it must involve viewports? Ben
On 6/14/06, Benjamin Tyner <btyner at gmail.com> wrote:> I like the functionality provided by outer=TRUE, but when it comes time > to place separate xlabs or ylabs, I always end up 'eyeballing' it on a > case-by-case basis. For example, > > ##begin example > require(lattice) > > cars.lo <- loess(dist ~ speed, cars) > > print(xyplot(cars.lo$residuals+cars.lo$fitted~cars.lo$x, > strip=FALSE, > outer=TRUE, > layout=c(1,2), > ylab="", > scales=list(y=list(relation="free",rot=0)), > panel=function(x,y,panel.number,...){ > if(panel.number==1){ > panel.xyplot(x,y) > panel.abline(h=0) > }else{ > panel.xyplot(x,y=cars.lo$y) > panel.xyplot(x,y,type="l") > } > })) > > require(grid) > trellis.focus("panel", 1, 1, clip.off=TRUE, highlight=FALSE) > grid.text("residuals", x=unit(0, "npc") + unit(-2, "lines"),rot=90) > trellis.focus("panel", 1, 2, clip.off=TRUE, highlight=FALSE) > grid.text("fitted", x=unit(0, "npc") + unit(-2, "lines"),rot=90) > ## end exampleFor the record, one alternative is something like with(cars.lo, xyplot(residuals + fitted ~ x, strip=FALSE, strip.left = TRUE, outer=TRUE, layout=c(1,2), ylab="", scales=list(y=list(relation="free",rot=0)), panel=function(x,y,panel.number,...){ if (panel.number==1){ panel.xyplot(x,y) panel.abline(h=0) }else{ panel.xyplot(x,y=cars.lo$y) panel.xyplot(x,y,type="l") } }))> In this case, a distance of -2 lines happens to be enough, but one has > to make the plot to know this. I'm interested in learning how one can > place the ylabs without fear of overlapping the tick labels; i.e., how > to use the exact space allocated by ylab="". I'm thinking it must > involve viewports?There is a single viewort for ylab, which you can get to with downViewport(trellis.vpname("ylab")) or trellis.focus("ylab") (the latter currently doesn't work because of a bug). This viewport spans all the panels, but you could place your labels suitably if you know how many rows of panels you have. BTW, ylab = "" may not actually create this viewport, but ylab = " " should be safe. Deepayan
Hi Benjamin Tyner wrote:> I like the functionality provided by outer=TRUE, but when it comes time > to place separate xlabs or ylabs, I always end up 'eyeballing' it on a > case-by-case basis. For example, > > ##begin example > require(lattice) > > cars.lo <- loess(dist ~ speed, cars) > > print(xyplot(cars.lo$residuals+cars.lo$fitted~cars.lo$x, > strip=FALSE, > outer=TRUE, > layout=c(1,2), > ylab="", > scales=list(y=list(relation="free",rot=0)), > panel=function(x,y,panel.number,...){ > if(panel.number==1){ > panel.xyplot(x,y) > panel.abline(h=0) > }else{ > panel.xyplot(x,y=cars.lo$y) > panel.xyplot(x,y,type="l") > } > })) > > require(grid) > trellis.focus("panel", 1, 1, clip.off=TRUE, highlight=FALSE) > grid.text("residuals", x=unit(0, "npc") + unit(-2, "lines"),rot=90) > trellis.focus("panel", 1, 2, clip.off=TRUE, highlight=FALSE) > grid.text("fitted", x=unit(0, "npc") + unit(-2, "lines"),rot=90) > ## end example > > In this case, a distance of -2 lines happens to be enough, but one has > to make the plot to know this. I'm interested in learning how one can > place the ylabs without fear of overlapping the tick labels; i.e., how > to use the exact space allocated by ylab="". I'm thinking it must > involve viewports?There is a 'ylab' viewport set up by lattice, although it is just one big one for all panels. Here's what you could do for your example (with knowledge of how many rows of panels there are) ... downViewport(trellis.vpname("ylab")) # If you want to see where the viewport is ... # grid.rect(gp=gpar(col="red"), name="temp") grid.text("residuals", y=0.25, rot=90) grid.text("fitted", y=0.75, rot=90) # If you want to remove the rect again ... # grid.remove("temp") upViewport(0) Paul -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 paul at stat.auckland.ac.nz http://www.stat.auckland.ac.nz/~paul/