1

I used stat_function in ggplot2 in order to plot a straight line. So within the range of -20 to 20, it plots y = x * 1.

ggplot(data.frame(x = c(-20, 20)), aes(x)) +
  stat_function(fun = function(x) { x**1 },
                geom = "line", color = '#1e466e') 

enter image description here

I'd like to figure out a way to create a plane and not just a line. I tried building out the process using the ggplot workflow by adding a variable and making stat_function report a z in relation to x and y. But this just gives me a blank plot.

ggplot(data.frame(x = c(-20, 20), y = c(-20, 20)), aes(x, y)) +
  stat_function(fun = function(z) { x**1 + y },
                geom = "line", color = '#1e466e') 

enter image description here

I'm seeing that this is a lot cause without a ggplot2 extension. But when I find examples using plotly or something else, I only see examples where the x and y and z are reported as columns of a dataframe and the plane is a regression plane through the points, such as in this stackoverflow example: But I don't want to plot points that exist in three coordinates but rather a plane that lives within two parallel lines that exist in three coordinates.

Is there a way to create planes to represent different linear equations, for example these equations?

x + 2y + z = 2
3x + 8y + z = 12
4y + z = 12

These planes should intersect at this point: (x = 2, y = 1, z = -2)

The inspiration for my small project was watching Gilbert Strang's linear algebra video at this link and wondering if it's possible to re-create in R.

hachiko
  • 671
  • 7
  • 20

1 Answers1

1

As you have discovered, ggplot2 is a 2-D plotting library. There are a few ways to represent planes, but not in a 3D perspective, unless you use a 3D extension library. Mostly, planes will be represented as lines representing slices of a plane. Another option is to represent the z value with a colour on the x, y plane.

The following function shows how this can be achieved for arbitrary functions of 3 variables:

library(ggplot2)

map_z <- function(f, xlim = c(-20, 20), ylim = c(-20, 20)) {
  xvals <- seq(xlim[1], xlim[2], length = 100)
  yvals <- seq(ylim[1], ylim[2], length = 100)
  df <- expand.grid(y = yvals, x = xvals)
  df$z <- f(df$x, df$y)
  df
}

The functions need to return the z value given an x and y. I have translated your equations into appropriate formats here:

# x + 2y + z = 2 
f1 <- function(x, y) 2 - x - 2 * y

# 3x + 8y + z = 12
f2 <- function(x, y) 12 - 3 * x - 8 * y

# 4y + z = 12
f3 <- function(x, y) 12 - 4 * y

And plotting them is very straightforward

ggplot(map_z(f1)) + geom_raster(aes(x, y, fill = z))

ggplot(map_z(f2)) + geom_raster(aes(x, y, fill = z))

ggplot(map_z(f3)) + geom_raster(aes(x, y, fill = z))

Created on 2022-04-04 by the reprex package (v2.0.1)

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Hi Allan, thank you for your post. I've read a lot of your answers on this website and they are always full of interesting ideas like this. After re-reading, I think I didn't make my question as clear as I could have. To add a little more context, I was watching Gilbert Strang's linear algebra video here: https://youtu.be/J7DzL2_Na80?t=1268 and I was wondering how to recreate his visual of three planes intersecting at one point. So I think my question is more specific - how do I create this in a 3D plot or else make ggplot give the appearance of 3D in this respect? – hachiko Apr 05 '22 at 01:10