This came up in response to a student’s question.

I wrote that, in general, you can plot a function y(x) on a simple graph. You can plot y(x,x2) by plotting y vs x and then having several lines showing different values of x2 (for example, x2=0, x2=0.5, x2=1, x2=1.5, x2=2, etc). You can plot y(x,x2,x3,x4) by making a two-dimensional grid of plots, where the rows show different values of x3 and the columns show different values of x4.

Then I thought I should illustrate with a graph: It took me about an hour to make this in R (or maybe half an hour, as I was doing other things at the same time). The code is really ugly; see below. Among other things, I had difficulty with the expression() function in R. I expect it should be much easier and more effective to do this in ggplot2.

[Check out the comments, which include several excellent implementations of this idea in ggplot2. If this doesn’t induce me to switch to ggplot2, I don’t know what will! — ed.]

Anyway, below is my code, which I include not out of pride but out of honesty. I could clean it up a bit but I might as well show you what I did. In any case, the grid of graphs illustrates the general point of how to plot a function of many variables, a point which I don’t think is as well known as it should be.

```pdf("2waygrid.pdf", height=6, width=8)
par(mfrow=c(5,6))
par(mar=c(3,3,0,0), tck=-.01, mgp=c(1.5,.5,0))
par(oma=c(0,0,3,0))
x2_grid <- seq(0, 1, 0.5)
x3_grid <- seq(0, 6, 2)
x4_grid <- seq(0, 2, 0.5)
empty_plot <- function(x=0, y=0, a="") { plot(c(-1, 1), c(-1, 1), xlab="", ylab="", xaxt="n", yaxt="n", bty="n", type="n") text(x, y, a, cex=1.2)
}
curve_to_plot <- function(x, x2, x3, x4){ return(x2*sin(x3*x + x4))
}
x_min <- 0
x_max <- 5
empty_plot()
empty_plot(0, -0.8, expression(paste(x, "=", 0)))
empty_plot(0, -0.8, expression(paste(x, "=", 0.5)))
empty_plot(0, -0.8, expression(paste(x, "=", 1)))
empty_plot(0, -0.8, expression(paste(x, "=", 1.5)))
empty_plot(0, -0.8, expression(paste(x, "=", 2)))
for (i in 1:4){ if (i==1) empty_plot(0, 0, expression(paste(x, "=", 0))) else if (i==2) empty_plot(0, 0, expression(paste(x, "=", 2))) else if (i==3) empty_plot(0, 0, expression(paste(x, "=", 4))) else if (i==4) empty_plot(0, 0, expression(paste(x, "=", 6))) x3 <- x3_grid[i] for (j in 1:5){ x4 <- x4_grid[j] plot(c(x_min, x_max), c(-1, 1), xlab=if (i==4) "x" else "", ylab=if (j==1) "y" else "", xaxt="n", yaxt="n", bty="l", type="n") if (i==4) axis(1, c(0,4,2)) if (j==1) axis(2, c(-1,0,1)) for (k in 1:3){ x2 <- x2_grid[k] curve(curve_to_plot(x, x2, x3, x4), from=x_min, to=x_max, add=TRUE, col=(k+1)) } }
}
mtext("How to graph a function of 4 variables using a grid:", side=3, line=1.5, outer=TRUE)
mtext(expression(paste("Graphing ", x*sin(x*x + x), ", as a function of x, for different values of ", x, ", ", x, ", and ", x, ".")), side=3, line=-0.5, outer=TRUE, cex=0.9)
mtext(expression(paste("(In each graph, red: ", x, "=0, green: ", x, "=0.5, blue: ", x, "=1. Rows and columns show different values of ", x, " and ", x, ".)")), side=3, line=-2, outer=TRUE, cex=0.8)
dev.off()
```  