[R] controlling panel.width and panel.height in viewports
Deepayan Sarkar
deepayan.sarkar at gmail.com
Sun Mar 25 21:34:41 CEST 2007
On 3/25/07, mike townsley <m.townsley at ucl.ac.uk> wrote:
> Dear all,
>
> I'm trying to get a series of lattice levelplots to appear in
> viewports in a particular way but struggling to exert fine control
> over their appearence. There are two conditions: (a) I only want the
> levelplot to appear (I don't want axes, colour key, etc) in the
> viewport and (b) I want the levelplot to expand to the maximum
> allowable space in the viewport while observing the aspect ratio of the plot.
>
> Condition (a) is OK, but (b) is giving me trouble. A toy example is:
>
> library(lattice)
> library(grid)
>
> x <- 1:10
> y <- 1:10
> grid <- expand.grid(x=x, y=y)
> grid$z <- grid$x*grid$y
>
> asp.ratio.1 <- 2
> asp.ratio.2 <- .5
> asp.ratio.3 <- 1
>
> test.1 <- levelplot(z~x*y, grid, cuts = 5, xlab="", axes = FALSE,
> aspect = asp.ratio.1, ylab="", main='', sub="",
> colorkey = FALSE, region = TRUE, scales =
> list(draw = FALSE))
> test.2 <- levelplot(z~x*y, grid, cuts = 5, xlab="", axes = FALSE,
> aspect = asp.ratio.2, ylab="", main='', sub="",
> colorkey = FALSE, region = TRUE, scales =
> list(draw = FALSE))
> test.3 <- levelplot(z~x*y, grid, cuts = 5, xlab="", axes = FALSE,
> aspect = asp.ratio.3, ylab="", main='', sub="",
> colorkey = FALSE, region = TRUE, scales =
> list(draw = FALSE))
>
> # so the three basic types of plot I will have
>
>
> toy.vp <- viewport(width = .8, height = .8, just = 'centre',
> name = 'toy') # this is for my levelplot
>
> X11()
> pushViewport(toy.vp)
> grid.rect(gp = gpar(col = 'grey'))
> print(test.1, newpage = FALSE)
>
> X11()
> pushViewport(toy.vp)
> grid.rect(gp = gpar(col = 'grey'))
> print(test.2, newpage = FALSE)
>
> X11()
> pushViewport(toy.vp)
> grid.rect(gp = gpar(col = 'grey'))
> print(test.3, newpage = FALSE)
>
>
> I want to get rid of the space (margins) around the longest axis for
> each variety of levelplot. So I tried to capture the viewport height
> and width and print the levelplot within a region which reflects the
> aspect ratio of the plot. I run into an error message as below:
>
> width.vp <- convertWidth(grobWidth(grid.rect()), 'cm')
> height.vp <- convertWidth(grobHeight(grid.rect()), 'cm')
>
> width.vp;height.vp # this works
>
> if(asp.ratio.1 < 1) {height.vp <-
> unit(as.numeric(height.vp)*asp.ratio.1, "cm")}
> if(asp.ratio.1 > 1) {width.vp <- unit(as.numeric(width.vp)/asp.ratio.1, "cm")}
>
> width.vp;height.vp # this also work (ie returns expected results)
>
> print(test.1, panel.width = list(width.vp), panel.height=list(height.vp))
>
> the above command returns this error message:
>
> Error in Ops.unit(panel.height[[1]], panel.width[[1]]) :
> Operator '/' not meaningful for units
>
> What have I missed?
The part in ?print.trellis which says:
panel.width, panel.height: lists with 2 components, that should be
valid 'x' and 'units' arguments to 'unit()'
You are specifying "unit" objects directly, which is not supported.
You probably wanted to do something like the following:
######
toy.vp <- viewport(width = .8, height = .8, just = 'centre',
name = 'toy') # this is for my levelplot
grid.newpage()
pushViewport(toy.vp)
grid.rect(gp = gpar(col = 'grey'))
width.vp <- convertWidth(grobWidth(grid.rect(draw = FALSE)), 'cm',
valueOnly = TRUE)
height.vp <- convertWidth(grobHeight(grid.rect(draw = FALSE)), 'cm',
valueOnly = TRUE)
if(asp.ratio.1 < 1) height.vp <- as.numeric(height.vp) * asp.ratio.1
if(asp.ratio.1 > 1) width.vp <- as.numeric(width.vp)/asp.ratio.1
width.vp;height.vp
print(test.1,
panel.width = list(width.vp, "cm"),
panel.height=list(height.vp, "cm"),
newpage = FALSE)
######
This runs, but doesn't give you what you want (I haven't tried to
figure out why).
I think you are taking the wrong approach to your problem. levelplot()
is a high level function, it's not supposed to be used this way. On
the other hand, you do have the ``low-level'' function
panel.levelplot, which _is_ designed to do things inside a grid
viewport. You could even avoid the necessary setup steps by getting
the relevant information by querying your "trellis" object, e.g.:
######
grid.newpage()
toy.vp <-
viewport(width = .8, height = .8,
just = 'centre',
layout = # necessary to fix aspect ratio
grid.layout(1, 1,
widths = 1,
heights = asp.ratio.1,
respect = TRUE),
name = 'toy')
pushViewport(toy.vp)
grid.rect(gp = gpar(col = 'grey'))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1,
xscale = test.1$x.limits,
yscale = test.1$y.limits))
do.call("panel.levelplot", trellis.panelArgs(test.1, 1))
upViewport(2)
######
Hope that helps,
-Deepayan
More information about the R-help
mailing list