tags:

views:

95

answers:

3

Hello

Could you give me an example on how to use rgl to plot 3 variables at the axes x, y and z and a fourth one with different colours?

thanks

+1  A: 

Take a look at example(points3d).

The r3d help page shows you how to draw axes.

x <- c(0, 10, 0, 0)
y <- c(0, 0, 100, 0)
z <- c(0, 0, 0, 1)
i <- c(1,2,1,3,1,4)
labels <- c("Origin", "X", "Y", "Z")
text3d(x,y,z,labels)
segments3d(x[i],y[i],z[i])

Now you add some points

dfr <- data.frame(x = 1:10, y = (1:10)^2, z = runif(10), col = rainbow(10))
with(dfr, points3d(x, y, z, col = col))
Richie Cotton
I don't get any result with your code
@user425895: You should see 3 labelled axes and some points. Check that you can display *anything* with `rgl`. Then check that you copied and pasted correctly.
Richie Cotton
+1  A: 

There is an example in ?plot3d if you are talking about plotting points in a 3d space and colouring them:

x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x,y)
plot3d(x, y, z, col=rainbow(1000))

But if you mean to colour the points by a 4th variable, say a grouping variable, then we can modify the example above to do this by creating a grouping variable

grp <- gl(5, 200) ## 5 groups 200 members each
## now select the colours we want
cols <- 1:5

## Now plot
plot3d(x, y, z, col=cols[grp])

OK, is this more what you want?

X <- 1:10
Y <- 1:10
## Z is now a 100 row object of X,Y combinations
Z <- expand.grid(X = X, Y = Y)
## Add in Z1, which is the 3rd variable
## X,Y,Z1 define the surface, which we colour according to
## 4th variable Z2
Z <- within(Z, {
    Z1 <- 1.2 + (1.4 * X) + (-1.9 * Y)
    Z2 <- 1.2 + (1.4 * X) - (1.2 * X^2) + (1.9 * Y) + (-1.3 * Y^2)
    Z3 <- 1.2 + (1.4 * X) + (-1.9 * Y) + (-X^2) + (-Y^2)})
## show the data
head(Z)
## Set-up the rgl device
with(Z, plot3d(X, Y, Z1, type = "n"))
## Need a scale for Z2 to display as colours
## Here I choose 10 equally spaced colours from a palette
cols <- heat.colors(10)
## Break Z2 into 10 equal regions
cuts <- with(Z, cut(Z2, breaks = 10))
## Add in the surface, colouring by Z2
with(Z, surface3d(1:10,1:10, matrix(Z1, ncol = 10),
                   color = cols[cuts], back = "fill"))
with(Z, points3d(X, Y, Z1, size = 5)) ## show grid X,Y,Z1

Here's a modification where the plane surface Z1 is curved (Z3).

## Set-up the rgl device plotting Z3, a curved surface
with(Z, plot3d(X, Y, Z3, type = "n"))
with(Z, surface3d(1:10,1:10, matrix(Z3, ncol = 10),
                   color = cols[cuts], back = "fill"))

The detail of what I did to get Z2 probably doesn't matter, but I tried to get something like the graph you linked to.

If I've still not got what you want, can you edit your Q with some example data and give us a better idea of what you want?

HTH

Gavin Simpson
something like this. http://addictedtor.free.fr/graphiques/graphcode.php?graph=90 but it's a little bit confusing
@user425895: I've edited my answer to try to get something like the graph you linked to. Is this effort more like what you want?
Gavin Simpson
Hi, last line doesn't work, it says Z2 not found.
Apologies; I was tidying my code prior to commenting and `Z2` was the old name for the object I was using. I have edited the example in my comment, but the last line was superfluous, just there to show where the X,Y,Z1 points were.
Gavin Simpson
Hi. Thank you very much for your dedication. Your example produces a plane and I was looking for a plot similar to the one provided by csgillespie.
Well, that's only because I didn't generate dummy data for `Z1` that was curved. The principle is the same.
Gavin Simpson
+2  A: 

You use a combination of persp and colour according to a separate function. Here's some example code:

## Create a simple surface  f(x,y) = -x^2 - y^2
## Colour the surface according to x^2 only
nx = 31; ny = 31
x = seq(-1, 1, length = nx)
y = seq(-1, 1, length = ny)
z = outer(x, y, function(x,y) -x^2  -y^2)
## Fourth dim
z_col = outer(x, y, function(x,y) x^2)

## Average the values at the corner of each facet
## and scale to a value in [0, 1].  We will use this
## to select a gray for colouring the facet. 
hgt = 0.25 * (z_col[-nx,-ny] + z_col[-1,-ny] + z_col[-nx,-1] + z_col[-1,-1])
hgt = (hgt - min(hgt))/ (max(hgt) - min(hgt))

##  Plot the surface with the specified facet colours.
persp(x, y, z, col = gray(1 - hgt))
persp(x, y, z, col=cm.colors(31)[floor(31*hgt+1)], theta=-35, phi=10)

This gives:

Sample output

RGL

It's fairly straightforward to use the above technique with the rgl library:

library(rgl)
## Generate the data using the above commands
## New window
open3d()

## clear scene:
clear3d("all")

## setup env:
bg3d(color="#887777")
light3d()

surface3d(x, y, z, color=cm.colors(31)[floor(31*hgt+1)], alpha=0.5)
csgillespie
I like your example, How do you do it with rgl?
I've added a brief rgl example.
csgillespie