\documentclass[a4paper]{article} %\VignetteIndexEntry{Non-finite values} %\VignettePackage{grid} \newcommand{\grid}{{\tt grid}} \newcommand{\R}{{\tt R}} \setlength{\parindent}{0in} \setlength{\parskip}{.1in} \setlength{\textwidth}{140mm} \setlength{\oddsidemargin}{10mm} \title{How Grid Responds to Non-Finite Values} \author{Paul Murrell} \begin{document} \maketitle <>= library(grDevices) library(grid) ps.options(pointsize=12) options(width=60) @ It is possible to include non-finite values, {\tt NA}, {\tt NaN}, {\tt Inf}, and {\tt -Inf}, in specifications of locations and sizes in \grid{} functions. This document describes how \grid{} responds to non-finite values in different cases. {\bf viewports} {~} \\ Non-finite values are not permitted in the location, size, or scales of a viewport. Viewport scales are checked when a viewport is created. It is very hard to be certain that locations and sizes are not non-finite when the viewport is created so this is only checked when the viewport is pushed. Non-finite values result in error messages. {\bf lines}, {\bf segments}, {\bf rectangles}, {\bf text}, {\bf points}, {\bf circles} {~} \\ For all of these primitives, non-finite values for locations or sizes result in the corresponding primitive not being drawn. The following image provides a simple demonstration. Each primitive is drawn at seven x-locations, with the fourth location made non-finite (as indicated by a grey {\tt "NA"}). <>= pushViewport(viewport(layout=grid.layout(1, 2, widths=unit(c(1, 1), c("inches", "null"))))) grid.rect(gp=gpar(col="grey")) pushViewport(viewport(layout.pos.col=1)) grid.text(c("segments", "text", "lines", "rectangles", "circles", "points"), x=1, just="right", y=c(0.75, 6:2/10), gp=gpar(col="grey")) popViewport() pushViewport(viewport(layout.pos.col=2)) x <- 1:7/8 x[4] <- NA grid.lines(x, 0.5) grid.text(letters[1:5], x, 0.6) grid.segments(x, 0.7, x, 0.8) grid.points(x, rep(0.2, 7)) grid.rect(x, 0.4, 0.02, 0.02) grid.circle(x, 0.3, 0.02) grid.text("NA", 0.5, 2:8/10, gp=gpar(col="grey")) popViewport(2) @ \vspace{.5in} \includegraphics{nonfinite-prim1} \newpage {\bf lineTo} {~} \\ A line segment is only drawn if the previous location and the new location are both not non-finite. {\bf polygon} {~} \\ A non-finite value breaks the polygon into two separate polygons. NOTE that this break happens within the current polygon as specified by the {\tt id} argument. All polygons with the same {\tt id} receive the same {\tt gp} settings. {\bf arrows} {~} \\ An arrow head is only drawn if the first or last line segment is drawn. The following image demonstrates the behaviour of these primitives where x- and y-locations are seven equally-spaced locations around the perimeter of a circle. In the top-left figure, all locations are not non-finite. In each of the other figures, two locations have been made non-finite (indicated in each case by grey text). <>= n <- 7 primtest2 <- function(nas, na) { t <- seq(0, 2*pi, length=n+1)[-(n+1)] y <- 0.5 + 0.4*sin(t) x <- 0.5 + 0.4*cos(t) if (any(nas)) grid.text(paste("NA", (1:n)[nas], sep=""), x[nas], y[nas], gp=gpar(col="grey")) x[nas] <- na y[nas] <- na grid.move.to(x[1], y[1]) for (i in 2:n) { grid.line.to(x[i], y[i], gp=gpar(lty="dashed", lwd=5)) } grid.polygon(x, y, gp=gpar(fill="grey", col=NULL)) grid.lines(x, y, arrow=arrow()) } celltest <- function(r, c, nas, na) { pushViewport(viewport(layout.pos.col=c, layout.pos.row=r)) primtest2(nas, na) grid.rect(gp=gpar(col="grey")) popViewport() } cellnas <- function(i) { temp <- rep(FALSE, n) temp[i] <- TRUE temp[n-3+i] <- TRUE temp } pushViewport(viewport(layout=grid.layout(2, 2))) celltest(1, 1, rep(FALSE, n), NA) celltest(1, 2, cellnas(1), NA) celltest(2, 1, cellnas(2), NA) celltest(2, 2, cellnas(3), NA) popViewport() @ \vspace{.5in} \includegraphics{nonfinite-prim2} % Start a new page % Not echoed, not evaluated % ONLY here for checkVignettes so that all output doesn't % end up on one enormous page <>= grid.newpage() @ \end{document}