John G. Bullock
2013-Aug-25 17:58 UTC
[R] centering text across panels of an annotated lattice figure
I have a multi-panel lattice figure. It has an even number of equal-width columns. I would like to center text across the columns. The xlab argument often handles this job nicely. But I want a more flexible solution. (I have many strings and want to position them at different heights, but always centered across the columns.) grid.text("Label", x = unit(.5, "npc")) will work when the figure has no annotations outside the panel. But when it does -- for example, when I use the scales argument to create row labels -- using grid.text() in this way doesn't center the text. Here is a minimal example: dataToPlot <- data.frame(x = 1:2, y = 1:2, panel = c('a', 'b')) plot1 <- xyplot( y ~ x | panel, data = dataToPlot, layout = c(2,1), ylab = '', xlab = '', scales = list( x = NULL, y = list( draw = TRUE, labels = c("Label 1", "Label 2"), at = c(1.8, 1.4)))) print(plot1) grid.text("XXX", x = unit(.5, "npc")) In this example, I can fix the problem by seeking the top-level viewport and then placing a grob in the grid layout: seekViewport("plot_01.toplevel.vp") grid.text( "XXX", vp = viewport(layout.pos.row=9, layout.pos.col=9:13)) But in that code, centering depends on the specific arguments to layout.pos.row and layout.pos.col. And when I have figures with more columns or rows, I don't know what those arguments should be. How can I find out? That is, how can I learn the layout of "plot_01.toplevel.vp"? trellis.par.get("layout.widths") and trellis.par.get("layout.heights") are suggestive of the layout. But I don't have a clear idea of how to use them to infer the viewport layout, especially when the viewport contains multiple panels. I've read through the grid and Lattice documentation, e.g., for grid.show.layout() and showViewport(). I've also read the Sarkar and Murrell (1st ed.) books. They're helpful, but I haven't found any passages that speak to exactly this point. John
John G. Bullock
2013-Aug-31 05:05 UTC
[R] centering text across panels of an annotated lattice figure
>> I have a multi-panel lattice figure. It has an even number of >> equal-width columns. I would like to center text across the columns. >> >> The xlab argument often handles this job nicely. But I want a more >> flexible solution. (I have many strings and want to position them at >> different heights, but always centered across the columns.) >> >> grid.text("Label", x = unit(.5, "npc")) will work when the figure has >> no annotations outside the panel. But when it does -- for example, >> when I use the scales argument to create row labels -- using >> grid.text() in this way doesn't center the text. > Paul Murrell wrote, On 8/26/2013 3:07 PM: > > I think if you downViewport("plot_01.figure.vp") you get what you want, for example, take a look at ... > > downViewport("plot_01.figure.vp") > grid.rect(gp=gpar(col="red"))Paul Murrell's downViewport()-based solution works beautifully. Thanks, Paul. John