Search code examples
rvisualizationrgl

How to plot two 3D graphs on the same plot in R


I'm using the plot3d function in the library rgl. Suppose my data looks something like this.

    x <- c(1,2,3,4,5)
    y <- c(4,2,1,4,2)
    z <- c(2,2,4,5,1)

    x2 <- c(1,5,2,3,4)
    y2 <- c(2,3,4,1,2)
    z2 <- c(3,4,2,3,1)

    plot3d(x, y, z)
    plot3d(x2, y2, z2)

Using the commands above would give me 2 separate plots. How can I plot both datasets on the same graph? Also I would like to use different symbols for the points in the two different data sets.


Solution

  • I just wrote a function cube and an accompanying one that might be sufficient for your needs:

    require(rgl); library('magrittr')
    cube <- function(x=0,y=0,z=0, bordered=TRUE, 
                     filled = TRUE, lwd=2, scale=1,
                     fillcol = gray(.95),
                     bordercol ='black', ...) {
    
      mytetra <- cube3d()
    
      # Reduce size to unit
      mytetra$vb[4,] <- mytetra$vb[4,]/scale*2
    
      for (i in 1:length(x)) {
        # Add cube border
        if (bordered) {
          btetra <- mytetra
          btetra$material$lwd <- lwd
          btetra$material$front <- 'line'
          btetra$material$back <- 'line'
          btetra %>% translate3d(x[i], y[i], z[i]) %>% shade3d
        }
        # Add cube fill
        if (filled) {
          ftetra <- mytetra
          ftetra$vb[4,] <- ftetra$vb[4,]*1.01
          ftetra$material$col <- fillcol
          ftetra %>% translate3d(x[i], y[i], z[i]) %>% shade3d
        }
      }
    }
    
    tetra <- function(x=0,y=0,z=0, bordered=TRUE, 
                                 filled = TRUE, lwd=2, scale=1,
                                 fillcol = gray(.95),
                                 bordercol ='black', ...) {
    
      mytetra <- tetrahedron3d()
    
      # Reduce size to unit
      mytetra$vb[4,] <- mytetra$vb[4,]/scale*2
    
      for (i in 1:length(x)) {
        # Add cube border
        if (bordered) {
          btetra <- mytetra
          btetra$material$lwd <- lwd
          btetra$material$front <- 'line'
          btetra$material$back <- 'line'
          btetra %>% translate3d(x[i], y[i], z[i]) %>% shade3d
        }
        # Add cube fill
        if (filled) {
          ftetra <- mytetra
          ftetra$vb[4,] <- ftetra$vb[4,]*1.01
          ftetra$material$col <- fillcol
          ftetra %>% translate3d(x[i], y[i], z[i]) %>% shade3d
        }
      }
    }
    
    plot3d(x,y,z)
    tetra(x,y,z, scale=1/2)
    cube(x2,y2,z2, scale=1/2)
    

    Two overlapping plotted shape sets.