Home > Net >  Generalizing a 2D plot to 3D in R
Generalizing a 2D plot to 3D in R

Time:11-22

I have a problem where I have data with (x,y) coordinates that I want to plot in the x-y plane. Furthermore, I have some box constraints such that -7 < x < 7 and -5 < y < 5 need to be drawn and checked. All points that fall outside of this box constraint I would like to color red. To do this I have the following code in R:

library(rgl)

x <- 7
y <- 5

data.x <- rnorm(10,0,5)
data.y <- rnorm(10,0,5)


plot(data.x, data.y, xlim = c(min(-x,data.x),max(x,data.x)), 
     ylim = c(min(-y,data.y),max(y,data.y)), pch = 19)
rect(-x, -y, x, y, col = "lightgrey")

idx <- abs(data.x) > x | abs(data.y) > y
points(data.x[idx], data.y[idx], col = "red", pch = 19)
points(data.x[!idx], data.y[!idx], col = "deepskyblue", pch = 19)

Now, where I am stuck, is on how to plot this type of data picture when I have a third group of data and a third constraint. I.e.,

### How to generalize when I have a third axis and constraint, i.e., a 3D cube
z <- 4
data.z <- rnorm(10, 0, 5)

So essentially I want to plot a box constraint as a cube in the x-y-z plane, and to color the points that fall outside the box constraint red again.

Also, I should say I understand there are functions for plottig 3d scatter plots in R, however, what I am struggling with is how to draw the 3D cube that defines the constraints.

CodePudding user response:

The difficulty with a 3D plot such as this is being able to interpret the "depth" of the points in the image. An animated 3D image might be helpful here:

library(plot3D)

x <- 7
y <- 5
z <- 6

set.seed(123)

data.x <- rnorm(10, 0, 5)
data.y <- rnorm(10, 0, 5)
data.z <- rnorm(10, 0, 5)

in_out <- abs(data.x) > x | abs(data.y) > y | abs(data.z) > z

for(i in seq(0, 358, 2)) {

  png(paste0("box", sprintf("d", i), ".png"))
  box3D(-x, -y, -z, x, y, z, col = NA, border = "gray50", theta = i, phi = 15,
        xlim = c(-10, 10), ylim = c(-10, 10), zlim = c(-10, 10),
        axes = TRUE, ticktype = "detailed")

  points3D(data.x, data.y, data.z, colvar = in_out, pch = 16, cex = 3, 
           add = TRUE, colkey = FALSE, col = c("lightblue", "red"))
  dev.off()
}

library(magick)

list.files(pattern = 'box\\d \\.png', full.names = TRUE) %>% 
  image_read() %>% 
  image_join() %>% 
  image_animate(fps=50) %>% 
  image_write("box.gif") 

box.gif enter image description here

  • Related