\documentclass[a4paper]{article} %\VignetteIndexEntry{Non-finite values} %\VignettePackage{grid} \newcommand{\pkg}[1]{{\normalfont\fontseries{b}\selectfont #1}} \newcommand{\grid}{\pkg{grid}} \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, \texttt{NA}, \texttt{NaN}, {\tt Inf}, and \texttt{-Inf}, in specifications of locations and sizes in \grid{} functions. This document describes how \grid{} responds to non-finite values in different cases. \textbf{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. \textbf{lines}, \textbf{segments}, \textbf{rectangles}, \textbf{text}, \textbf{points}, \textbf{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 \texttt{"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 \textbf{lineTo} {~} \\ A line segment is only drawn if the previous location and the new location are both not non-finite. \textbf{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. \textbf{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} \end{document}