How to graph a function of 4 variables using a grid

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[4], "=", 0)))
empty_plot(0, -0.8, expression(paste(x[4], "=", 0.5)))
empty_plot(0, -0.8, expression(paste(x[4], "=", 1)))
empty_plot(0, -0.8, expression(paste(x[4], "=", 1.5)))
empty_plot(0, -0.8, expression(paste(x[4], "=", 2)))
for (i in 1:4){
  if (i==1)
    empty_plot(0, 0, expression(paste(x[3], "=", 0)))
  else if (i==2)
    empty_plot(0, 0, expression(paste(x[3], "=", 2)))
  else if (i==3)
    empty_plot(0, 0, expression(paste(x[3], "=", 4)))
  else if (i==4)
    empty_plot(0, 0, expression(paste(x[3], "=", 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[2]*sin(x[3]*x + x[4]), ", as a function of x, for different values of ", x[2], ", ", x[3], ", and ", x[4], ".")), side=3, line=-0.5, outer=TRUE, cex=0.9)
mtext(expression(paste("(In each graph, red: ", x[2], "=0, green: ", x[2], "=0.5, blue: ", x[2], "=1.  Rows and columns show different values of ", x[3], " and ", x[4], ".)")), side=3, line=-2, outer=TRUE, cex=0.8)
dev.off()

The post How to graph a function of 4 variables using a grid appeared first on Statistical Modeling, Causal Inference, and Social Science.