Plotting a wireframe AND a cloud with lattice in R
Asked Answered
K

2

10

I have a nice surface that represents nonlinear multi-part regression results on a regression with two independent variables. I would like to plot the regression predicted values as a nice 3D surface and then show the actual values as point that bounce around the surface. This would be the 3D version of plotting a regression line and showing the actuals as points around the line. I can't figure out how to do this with lattice. I'm happy to use another graphing library in R, but I don't know of others that do 3D plots.

Here's a simplified version of what I want to do:

library(lattice)
#set up some simplified data
x <- seq(-.8, .8, .1)
y <- seq(-.8, .8, .1)
myGrid <- data.frame(expand.grid(x,y))
colnames(myGrid) <- c("x","y")
myGrid$z <- myGrid$x + myGrid$y
noise <- rnorm(length(myGrid$z),.3,.2)
myGrid$z2 <- myGrid$x + myGrid$y + noise

z is my smooth surface and z2 are my noisy points mostly slightly above the surface. So the surface looks like this:

wireframe(myGrid$z ~ myGrid$x * myGrid$y, xlab="X", ylab="Y", zlab="Z")

enter image description here

and the cloud of points looks like this:

cloud(myGrid$z2 ~ myGrid$x * myGrid$y, xlab="X", ylab="Y", zlab="Z")

enter image description here

Is it possible to get both of these in one lattice panel?

Kaiser answered 10/9, 2009 at 16:5 Comment(0)
F
8

I do love rgl! But there are times when 3-D plots in lattice are useful too - you can write your own function which you can pass to the 'panel' argument to lattice functions. For instance,

mypanel <- function(x,y,z,...) {
  panel.wireframe(x,y,z,...)
  panel.cloud(x,y,z,...)
}
wireframe(myGrid$z ~ myGrid$x * myGrid$y, xlab="X", ylab="Y", zlab="Z",
          panel=mypanel)

The last function you call can be wireframe() or cloud(); in either case since panel.wireframe() and panel.cloud() are called within the panel function the result should be the same.

Edit: Thanks for pointing that out, Aaron, then probably you can pass z2 as another variable:

mypanel <- function(x,y,z,z2,...) {
  panel.wireframe(x,y,z,...)
  panel.cloud(x,y,z2,...)
}
wireframe(z ~ x * y, data=myGrid, xlab="X", ylab="Y", zlab="Z",
          panel=mypanel, z2=myGrid$z2)
Fishbein answered 15/9, 2009 at 9:2 Comment(3)
Nice! But to use the points from z2 instead of z for the cloud, use panel.cloud(x,y,myGrid$z2) in the mypanel function.Squally
Oh, and how to draw the cloud, but for different x's and y's?Torero
You can probably 1) rbind() another set of x,y,z's to myGrid, 2) add a categorical value to myGrid, and 3) pass this categorical variable (factor) to the groups argument.Fishbein
F
0

If memory serves, Rcmdr already does this for you using rgl. That may be limited to the models that Rcmdr fits, though.

On the other hand, it gives you (fast !) scrolling, zooming, ... which lattice cannot do.

Fanfaronade answered 10/9, 2009 at 16:12 Comment(2)
I skimped on my Linux box graphics card because "I don't play games" but I think RGL would certainly benefit if I had decided otherwise!Fishbein
I also keep it simple ("no games") but OpenGL often works on really simple hardware. Give it a shot -- as I recall you only need 2d support.Fanfaronade

© 2022 - 2024 — McMap. All rights reserved.