Rev 61993 | Rev 85828 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/grid/vignettes/grid.Rnw% Part of the R package, https://www.R-project.org% Copyright 2001-13 Paul Murrell and the R Core Team% Distributed under GPL 2 or later\documentclass[a4paper]{article}\usepackage{Rd}% \VignetteIndexEntry{Introduction to grid}% \VignettePackage{grid}% \VignetteDepends{lattice}% Definitions\newcommand{\slan}{{\sffamily S}}\newcommand{\rlan}{{\sffamily R}}\newcommand{\grid}{\pkg{grid}}\newcommand{\lattice}{\CRANpkg{lattice}}\setlength{\parindent}{0in}\setlength{\parskip}{.1in}\setlength{\textwidth}{140mm}\setlength{\oddsidemargin}{10mm}\title{\grid{} Graphics}\author{Paul Murrell}\begin{document}\maketitle<<echo=FALSE, results=hide>>=library(grDevices)library(graphics) # for parlibrary(stats) # for rnormlibrary(grid)ps.options(pointsize = 12)options(width = 60)@\grid{} is a low-level graphics system which provides a great dealof control and flexibility in the appearance and arrangement ofgraphical output. \grid{} does not provide high-level functions whichcreate complete plots. What it does provide is a basis for developingsuch high-level functions (e.g., the \lattice{} and \CRANpkg{ggplot2}packages), the facilities for customising and manipulating \lattice{}output, the ability to produce high-level plots or non-statisticalimages from scratch, and the ability to add sophisticated annotationsto the output from base graphics functions (see the \CRANpkg{gridBase}package).This document provides an introduction to the fundamental conceptsunderlying the \grid{} package: {\bf viewports}, {\bf units}, and{\bf graphical parameters}. There are also several examples todemonstrate what can be achieved and how to achieve it.The description of the fundamental \grid{} concepts is predicated on thefollowing approach to constructing a statistical graphic(plot). You must be able to:\begin{enumerate}\item create and control different graphical regionsand coordinate systems.\item control which graphical region andcoordinate system graphical output goes into.\item produce graphical output (lines, points, text, \ldots{})including controlling its appearance (colour, line type, line width, \ldots{}).\end{enumerate}\section{Creating and Controlling Graphics Regions and Coordinate Systems}In \grid{} there can be any number of graphics regions. A graphicsregion is referred to as a \emph{viewport} and is created using the\code{viewport()} function. A viewport can be positioned anywhere ona graphics device (page, window, \ldots{}), it can be rotated, and it canbe clipped to. The following code describes a viewport which iscentred within the page, and is halfthe width of the page, one quarter of the height of the page,and rotated $45^{\circ}$; Figure \ref{figure:viewport}shows a diagram of this viewport.<<eval=FALSE>>=viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.25, angle=45)<<viewport, echo=FALSE, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.show.viewport(viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.25,angle = 45))@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-viewport}}\end{center}\caption{\label{figure:viewport}A diagram of a simple \grid{} viewport (produced using the\code{grid.show.viewport()} function.}\end{figure}The object returned by the \code{viewport()} function is only a\emph{description} of a graphics region. A graphics region is onlycreated on a graphics device when a viewport is ``pushed'' onto thatdevice. This is achieved using the \code{pushViewport()} function.Each device has only one ``current viewport'' (by default this is theentire device surface), but it maintains a ``tree'' of viewports thathave been pushed. The current viewport is a node on the viewporttree. The \code{pushViewport()} function adds a viewport as a leaf ofthe tree -- the previous ``current viewport'' becomes the parent ofthis leaf and the new leaf becomes the current viewport. The\code{popViewport()} function prunes the current viewport (and all itschildren) from the tree -- the parent of the pruned leaf becomes thecurrent viewport. The function \code{upViewport()} acts like\code{popViewport()} in terms of setting the current viewport, butdoes not prune the previous ``current viewport''. The\code{downViewport()} function navigates down the tree to a viewportwhich has been specified by name (it adds no new viewports to thetree). This means that there is always only one graphics regionselected to draw into, but it is possible to return to a previousgraphics region through the appropriate set of push/pop/up/downoperations.As an example, the following code creates a graphicsregion in the top-left corner of the page using \code{pushViewport()}.This viewport is given the name \code{"vp1"}.It then does some drawing and calls \code{upViewport()} to returnto the root of the viewport tree. Next, itcreates another region in the bottom-right corner of the page(again using \code{pushViewport()}) and doessome drawing there. Finally, it performs an \code{upViewport()}to the root of the tree and a \code{downViewport()} toreturn to the first graphics region anddoes some more drawing there (see Figure \ref{figure:viewports}).<<pushviewports, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.rect(gp = gpar(lty = "dashed"))vp1 <- viewport(x = 0, y = 0.5, w = 0.5, h = 0.5,just = c("left", "bottom"), name = "vp1")vp2 <- viewport(x = 0.5, y = 0, w = 0.5, h = 0.5,just = c("left", "bottom"))pushViewport(vp1)grid.rect(gp = gpar(col = "grey"))grid.text("Some drawing in graphics region 1", y = 0.8)upViewport()pushViewport(vp2)grid.rect(gp = gpar(col = "grey"))grid.text("Some drawing in graphics region 2", y = 0.8)upViewport()downViewport("vp1")grid.text("MORE drawing in graphics region 1", y = 0.2)popViewport()@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-pushviewports}}\end{center}\caption{\label{figure:viewports}Defining and drawing in multiple graphics regions.}\end{figure}@When several viewports are pushed onto the viewport tree, leafviewports are located and sized within the context of their parentviewports. The following code gives an example; a viewport is definedwhich is one-quarter the size of its parent (half the width and half theheight), and this viewport is pushed twice. The first time itgets pushed the parent is the root of the viewport tree (which is theentire device) so it is quarter of the size of the page.The second time the viewport is pushed,it is quarter of the size of \emph{its parent viewport}.Figure \ref{figure:vpstack} shows the output of thesecommands.<<vpstack, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.rect(gp = gpar(lty = "dashed"))vp <- viewport(width = 0.5, height = 0.5)pushViewport(vp)grid.rect(gp = gpar(col = "grey"))grid.text("quarter of the page", y = 0.85)pushViewport(vp)grid.rect()grid.text("quarter of the\nprevious viewport")popViewport(2)@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-vpstack}}\end{center}\caption{\label{figure:vpstack}The result of pushing the same viewport onto the viewportstack twice.}\end{figure}@Each viewport has a number of coordinate systems available. The fullset is described in Table \ref{table:coords}, but there are four maintypes: absolute coordinates (e.g., \code{"inches"}, \code{"cm"}) allowlocations and sizes in terms of physical coordinates -- there is nodependence on the size of the page; normalised coordinates (e.g.,\code{"npc"}) allow locations and sizes as a proportion of the pagesize (or the current viewport); relative coordinates (i.e.,\code{"native"}) allow locations and sizes relative to a user-definedset of x- and y-ranges; referential coordinates (e.g.,\code{"strwidth"}) where locations and sizes are based on the size ofsome other graphical object.It is possible to specify the coordinate systemfor relative coordinates, but all other coordinate systemsare implicitly defined based on the location and size of the viewportand/or the size of other graphical objects.\begin{table}[p]\begin{center}\begin{tabular}{l l} \hline{\bf Coordinate} & \\{\bf System Name} & {\bf Description} \\ \hline\code{"npc"} & \parbox[t]{3in}{Normalised Parent Coordinates. Treatsthe bottom-left corner of the currentviewport as the location $(0, 0)$ and the top-right corneras $(1,1)$. } \\\code{"native"} & \parbox[t]{3in}{Locations and sizes are relativeto the x- and y-scales for the current viewport.} \\\code{"inches"} & \parbox[t]{3in}{Locations and sizes are in termsof physical inches. For locations, $(0,0)$ is at the bottom-leftof the viewport.} \\\code{"cm"} & \parbox[t]{3in}{Same as \code{"inches"}, except incentimetres.} \\\code{"mm"} & \parbox[t]{3in}{Millimetres.} \\\code{"points"} & \parbox[t]{3in}{Points. There are 72.27 points per inch.} \\\code{"bigpts"} & \parbox[t]{3in}{Big points. There are 72 big points per inch.} \\\code{"picas"} & \parbox[t]{3in}{Picas. There are 12 points per pica.} \\\code{"dida"} & \parbox[t]{3in}{Dida. 1157 dida equals 1238 points. } \\\code{"cicero"} & \parbox[t]{3in}{Cicero. There are 12 dida per cicero. } \\\code{"scaledpts"} & \parbox[t]{3in}{Scaled points. There are 65536 scaledpoints per point. } \\\code{"char"} & \parbox[t]{3in}{Locations and sizes are specified interms of multiples of the current nominal \code{fontheight}.} \\\code{"lines"} & \parbox[t]{3in}{Locations and sizes are specified interms of multiples of the height of a line of text(dependent on both the current \code{fontsize} andthe current \code{lineheight}).} \\\code{"snpc"} & \parbox[t]{3in}{Square Normalised Parent Coordinates.Locations and size are expressed as a proportion of the \emph{smaller}of thewidth and height of the current viewport.} \\\code{"strwidth"} & \parbox[t]{3in}{Locations and sizes areexpressed as multiples of the width of a given string (dependenton the string and the current \code{fontsize}).} \\\code{"strheight"} & \parbox[t]{3in}{Locations and sizes areexpressed as multiples of the height of a given string (dependenton the string and the current \code{fontsize}).} \\\code{"grobwidth"} & \parbox[t]{3in}{Locations and sizes areexpressed as multiples of the width of a given graphical object(dependent on the current state of the graphical object). } \\\code{"grobheight"} & \parbox[t]{3in}{Locations and sizes areexpressed as multiples of the height of a given graphical object(dependent on the current state of the graphical object). } \\\hline\end{tabular}\end{center}\caption{\label{table:coords}The full set of coordinate systems available in \grid{}viewports.}\end{table}\section{Directing Graphics Output into Different \\Graphics Regionsand Coordinate Systems}Graphics output is always relative to the current viewport (on thecurrent device). Selecting which region you want is a matter ofpush/pop/up/downing the appropriate viewports. However, that is notall; every viewport has a number of coordinate systems associated withit, so it is also necessary to select the coordinate system that youwant to work with.The selection of which coordinate system to use within the currentviewport is made using the \code{unit()} function. The\code{unit()} function creates an object which is a combinationof a value and a coordinate system (plus some extrainformation for certain coordinate systems). Here are some examplesfrom the \code{help(unit)} page:<<units>>=unit(1, "npc")unit(1:3/4, "npc")unit(1:3/4, "npc")[2]unit(1:3/4, "npc") + unit(1, "inches")min(unit(0.5, "npc"), unit(1, "inches"))unit.c(unit(0.5, "npc"), unit(2, "inches") + unit(1:3/4, "npc"),unit(1, "strwidth", "hi there"))@Notice that unit objects are treated much like numeric vectors. Youcan index a unit object, it is possible to do simple arithmetic(including \code{min} and \code{max}), and there are severalunit-versions of common functions (e.g., \code{unit.c},\code{unit.rep}, and \code{unit.length}; \code{unit.pmin}, and\code{unit.pmax})).\grid{} functions that have arguments specifying locations and sizestypically assume a default coordinate system is being used. Mostoften this default is \code{"npc"}. In other words, if a raw numericvalue, \code{x}, is specified this is implicitly taken to mean\code{unit(x, "npc")}. The \code{viewport()} function is one thatassumes \code{"npc"} coordinates, so in all of the viewport examplesto this point, we have only used \code{"npc"} coordinates to positionviewports within the page or within each other. It is also possibleto position viewports using any of the coordinate systems described inTable \ref{table:coords}.As an example, the following code makes use of \code{"npc"},\code{"native"}, \code{"inches"}, and \code{"strwidth"}coordinates. It first pushes a viewport with a user-definedx-scale, then pushes another viewport which is centred at the x-value60 and half-way up the first viewport, andis 3 inches high\footnote{If you want to check the figure, the scalingfactor is $3.5/6$ (i.e., the rectangle in the figure should be 1.75\code{"} or3.94cm high).} and as wide as the text ``coordinates for everyone''.Figure \ref{figure:vpcoords} shows the resulting output.<<vpcoords, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=pushViewport(viewport(y = unit(3, "lines"), width = 0.9, height = 0.8,just = "bottom", xscale = c(0, 100)))grid.rect(gp = gpar(col = "grey"))grid.xaxis()pushViewport(viewport(x = unit(60, "native"), y = unit(0.5, "npc"),width = unit(1, "strwidth", "coordinates for everyone"),height = unit(3, "inches")))grid.rect()grid.text("coordinates for everyone")popViewport(2)@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-vpcoords}}\end{center}\caption{\label{figure:vpcoords}A viewport positioned using a variety of coordinate systems.}\end{figure}\clearpage\subsection{Layouts}\grid{} provides an alternative method for positioning viewportswithin each other based on \emph{layouts}\footnote{The primary referencefor layouts is \cite{murrell:1999}. Layouts in \grid{} representan extension of the idea to allow a greater range of units forspecifying row heights and column widths. \grid{} also differs in theway that children of the layout specify their location within the layout.}.A layout may be specifiedfor any viewport. Any viewport pushed immediately after a viewportcontaining a layout may specify its location with respect to thatlayout. In the following simple example, a viewport is pushedwith a layoutwith 4 rows and 5 columns, then another viewport is pushed whichoccupies the second and third columns of the third row of the layout.<<vplayout, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=pushViewport(viewport(layout = grid.layout(4, 5)))grid.rect(gp = gpar(col = "grey"))grid.segments(c(1:4/5, rep(0, 3)), c(rep(0, 4), 1:3/4),c(1:4/5, rep(1, 3)), c(rep(1, 4), 1:3/4),gp = gpar(col = "grey"))pushViewport(viewport(layout.pos.col = 2:3, layout.pos.row = 3))grid.rect(gp = gpar(lwd = 3))popViewport(2)@\begin{figure}[tbp]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-vplayout}}\end{center}\caption{\label{figure:vplayout}A viewport positioned using a layout.}\end{figure}Layouts introduce a special sort of unit called \code{"null"}. Thesecan be used in layouts to specify relative column-widths orrow-heights. In the following, slightly more complex, example, thelayout specifies something similar to a standard plot arrangement;there are bottom and left margins 3 lines of text wide, top and rightmargins 1cm wide, and two rows and columns within these margins wherethe bottom row is twice the height of the top row (see Figure\ref{figure:vplayoutcomplex}).<<layoutcomplex, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.show.layout(grid.layout(4, 4, widths = unit(c(3, 1, 1, 1),c("lines", "null", "null", "cm")),heights = c(1, 1, 2, 3),c("cm", "null", "null", "lines")))@\begin{figure}[tbp]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-layoutcomplex}}\end{center}\caption{\label{figure:vplayoutcomplex}A more complex layout.}\end{figure}\clearpage\section{Producing Graphics Output}\grid{} provides a standard set of graphical primitives: lines,text, points, rectangles, polygons, and circles. There are alsotwo higher level components: x- and y-axes. Table \ref{table:primitives}lists the \grid{} functions that produce these primitives.{\bf NOTE:} all of these graphical primitives are available inall graphical regions and coordinate systems.There used to be (prior to R 2.3.0) a separate \code{grid.arrows()}function, but this has been superseded by an \code{arrow} argumentto the line-drawing primitives (lines, segments, line-to).\begin{table}[h!]\begin{center}\begin{tabular}{l l} \hline\code{grid.text} & Can specify angle of rotation. \\\code{grid.rect} & \\\code{grid.circle} & \\\code{grid.polygon} & \\\code{grid.points} & Can specify type of plotting symbol. \\\code{grid.lines} & \\\code{grid.segments} & \\\code{grid.grill} & Convenience function for drawing grid lines \\\code{grid.move.to} & \\\code{grid.line.to} & \\& \\\code{grid.xaxis} & Top or bottom axis \\\code{grid.yaxis} & Left or right axis \\\hline\end{tabular}\end{center}\caption{\label{table:primitives}\grid{} graphical primitives.}\end{table}\subsection{Controlling the Appearance of Graphics Output}\grid{} recognises a fixed set of graphical parameters for modifyingthe appearance of graphical output (see Table \ref{table:gpars}).\begin{table}[h!]\begin{center}\begin{tabular}{l l} \hline\code{col} & colour of lines, text, \ldots{} \\\code{fill} & colour for filling rectangles, circles, polygons, \ldots{} \\\code{lwd} & line width \\\code{lty} & line type \\\code{fontsize} & The size of text (in points) \\\code{fontface} & The font face (bold, italic, \ldots{}) \\\code{fontfamily} & The font family \\\hline\end{tabular}\end{center}\caption{\label{table:gpars}\grid{} graphical parameters.}\end{table}Graphical parameter settings may be specified for both viewportsand graphical objects. A graphical parameter setting for a viewportwill hold for all graphical output within that viewport {\em and} forall viewports subsequently pushed onto the viewport stack, {\em unless}the graphical object or viewport specifies a different parametersetting.A description of graphical parameter settings is created usingthe \code{gpar()} function, and this description is associated with aviewport or a graphical object via the \code{gp} argument.The following code demonstrates the effect of graphical parametersettings (see Figure \ref{figure:gpar}).<<gpar, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=pushViewport(viewport(gp = gpar(fill = "grey", fontface = "italic")))grid.rect()grid.rect(width = 0.8, height = 0.6, gp = gpar(fill = "white"))grid.text(paste("This text and the inner rectangle","have specified their own gpar settings", sep = "\n"),y = 0.75, gp = gpar(fontface = "plain"))grid.text(paste("This text and the outer rectangle","accept the gpar settings of the viewport", sep = "\n"),y = 0.25)popViewport()@\begin{figure}[tbp]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-gpar}}\end{center}\caption{\label{figure:gpar}The effect of different graphical parameter settings.}\end{figure}\clearpage\section{Examples}The remaining sections provide some code examples of the useof \grid{}.The first example constructs a simple scatterplot from firstprinciples.Just like in base graphics, it is quite straightforwardto create a simple plot by hand. The following code produces the equivalentof a standard \code{plot(1:10)} (see Figure \ref{figure:simpleplot}).<<simpleplot, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.rect(gp = gpar(lty = "dashed"))x <- y <- 1:10pushViewport(plotViewport(c(5.1, 4.1, 4.1, 2.1)))pushViewport(dataViewport(x, y))grid.rect()grid.xaxis()grid.yaxis()grid.points(x, y)grid.text("1:10", x = unit(-3, "lines"), rot = 90)popViewport(2)@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-simpleplot}}\end{center}\caption{\label{figure:simpleplot}The grid equivalent of \code{plot(1:10)}.}\end{figure}Now consider a more complex example, where we create a barplotwith a legend (see Figure \ref{figure:barplot}).There are two main parts to this becausegrid has no predefined barplot function; the construction of thebarplot will itself be instructive, so we will start with just that.The data to be plotted are as follows: we have four measures torepresent at four levels; the data are in a matrix with the measuresfor each level in a column.<<bpdata>>=barData <- matrix(sample(1:4, 16, replace = TRUE), ncol = 4)@We will use colours to differentiatethe measures.<<barconstraint>>=boxColours <- 1:4@We create the barplot within a function so that we can easilyreproduce it when we combine it with the legend.<<bpfun>>=bp <- function(barData) {nbars <- dim(barData)[2]nmeasures <- dim(barData)[1]barTotals <- rbind(rep(0, nbars), apply(barData, 2, cumsum))barYscale <- c(0, max(barTotals)*1.05)pushViewport(plotViewport(c(5, 4, 4, 1),yscale = barYscale,layout = grid.layout(1, nbars)))grid.rect()grid.yaxis()for (i in 1:nbars) {pushViewport(viewport(layout.pos.col = i, yscale = barYscale))grid.rect(x = rep(0.5, nmeasures),y = unit(barTotals[1:nmeasures, i], "native"),height = unit(diff(barTotals[,i]), "native"),width = 0.8, just = "bottom", gp = gpar(fill = boxColours))popViewport()}popViewport()}@Now we turn our attention to the legend. We need some labelsand we will enforce the constraint that the boxes in the legend shouldbe 0.5\code{"} square:<<legendlabels>>=legLabels <- c("Group A", "Group B", "Group C", "Something Longer")boxSize <- unit(0.5, "inches")@The following draws the legend elements in a column, with eachelement consisting of a box with a label beneath.<<legfun>>=leg <- function(legLabels) {nlabels <- length(legLabels)pushViewport(viewport(layout = grid.layout(nlabels, 1)))for (i in 1:nlabels) {pushViewport(viewport(layout.pos.row = i))grid.rect(width = boxSize, height = boxSize, just = "bottom",gp = gpar(fill = boxColours[i]))grid.text(legLabels[i], y = unit(0.5, "npc") - unit(1, "lines"))popViewport()}popViewport()}@Now that we have the two components, we can arrange them together toform a complete image. Notice that we can perform some calculationsto make sure that we leave enough room for the legend, including1 line of text as left and right margins. We also impose top and bottommargins on the legend to match the plot margins.<<barplot, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=grid.rect(gp = gpar(lty = "dashed"))legend.width <- max(unit(rep(1, length(legLabels)),"strwidth", as.list(legLabels)) +unit(2, "lines"),unit(0.5, "inches") + unit(2, "lines"))pushViewport(viewport(layout = grid.layout(1, 2,widths = unit.c(unit(1,"null"), legend.width))))pushViewport(viewport(layout.pos.col = 1))bp(barData)popViewport()pushViewport(viewport(layout.pos.col = 2))pushViewport(plotViewport(c(5, 0, 4, 0)))leg(legLabels)popViewport(3)@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-barplot}}\end{center}\caption{\label{figure:barplot}A barplot plus legend from first principles using \grid{}.}\end{figure}\section{\grid{} and \lattice{}}The \lattice{} package is built on top of \grid{} and provides aquite sophisticated example of writing high-level plotting functionsusing \grid{}. Because \lattice{} consists of \grid{} calls, it ispossible to both add \grid{} output to \lattice{} output, and\lattice{} output to \grid{} output.\subsection*{Adding \grid{} to \lattice{}}Panel functions in \lattice{} can include \grid{} calls.The following example adds a horizontal line at 0 to a standard\code{xyplot} (see Figure \ref{figure:trellispanel}):<<echo=FALSE, results=hide>>=library(lattice)<<trellisdata, echo=FALSE, eval=FALSE>>=x <- rnorm(100)y <- rnorm(100)g <- sample(1:8, 100, replace = TRUE)@% This is the code the reader sees% This WILL get run by checking code, but by then lattice will be% installed so it will be ok<<trellispanelplot, eval=FALSE>>=xyplot(y ~ x | g, panel = function(x, y) {panel.xyplot(x, y);grid.lines(unit(c(0, 1), "npc"), unit(0, "native"),gp = gpar(col = "grey"))})@% This generates the actual plot<<trellispanel, echo=FALSE, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=<<trellisdata>><<trellispanelplot>>@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-trellispanel}}\end{center}\caption{\label{figure:trellispanel}A \lattice{} panel function using \grid{}.}\end{figure}@The following example writes a left-justified label in each strip(see Figure \ref{figure:trellisstrip}):<<trellisstripplot, eval=FALSE>>=xyplot(y ~ x | g, strip = function(which.given, which.panel, ...) {grid.text(paste("Variable ", which.given, ": Level ",which.panel[which.given], sep = ""),unit(1, "mm"), .5, just = "left")})<<trellisstrip, echo=FALSE, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=<<trellisdata>><<trellisstripplot>>@\begin{figure}[p]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-trellisstrip}}\end{center}\caption{\label{figure:trellisstrip}A \lattice{} strip function using \grid{}.}\end{figure}\subsection*{Adding \lattice{} to \grid{}}It is also possible to use a \lattice{} plot as an element ofa \grid{} image. The following example splits up the pageso that there is an \code{xyplot} beside a panel of text(see Figure \ref{figure:trellisgrid}). First of all, thelattice plot is created, butnot drawn. \grid{} is used to create some regions and the latticeplot is drawn into one of those regions.<<trellisgridplot, eval=FALSE>>=someText <- paste("A panel of text", "produced using", "raw grid code","that could be used", "to describe","the plot", "to the right.", sep = "\n")latticePlot <- xyplot(y ~ x | g, layout = c(2, 4))grid.rect(gp = gpar(lty = "dashed"))pushViewport(viewport(layout = grid.layout(1, 2,widths = unit.c(unit(1, "strwidth", someText) +unit(2, "cm"),unit(1, "null")))))pushViewport(viewport(layout.pos.col = 1))grid.rect(gp = gpar(fill = "light grey"))grid.text(someText,x = unit(1, "cm"), y = unit(1, "npc") - unit(1, "inches"),just = c("left", "top"))popViewport()pushViewport(viewport(layout.pos.col = 2))print(latticePlot, newpage = FALSE)popViewport(2)<<trellisgrid, echo=FALSE, results=hide, fig=TRUE, width=6, height=6, include=FALSE>>=<<trellisdata>><<trellisgridplot>>@\begin{figure}[tbp]\begin{center}{\includegraphics[width=3.5in, height=3.5in]{grid-trellisgrid}}\end{center}\caption{\label{figure:trellisgrid}A \lattice{} plot used as a component of a larger \grid{} image.}\end{figure}\bibliographystyle{plain}\bibliography{grid}\end{document}