I'm interested in this too, so I studied a bit and came up with an incomplete answer. This will produce an ellipsoid and mark its radii, but I haven't figured out how to rotate it using the eigenvectors.

Loading the `rgl`

package and running `demo(shapes3d)`

will give you this `ellipsoid3d`

function:

```
ellipsoid3d <- function(rx=1,ry=1,rz=1,n=30,ctr=c(0,0,0),
qmesh=FALSE,
trans = par3d("userMatrix"),...) {
if (missing(trans) && !rgl.cur()) trans <- diag(4)
degvec <- seq(0,pi,length=n)
ecoord2 <- function(p) {
c(rx*cos(p[1])*sin(p[2]),ry*sin(p[1])*sin(p[2]),rz*cos(p[2])) }
v <- apply(expand.grid(2*degvec,degvec),1,ecoord2)
if (qmesh) v <- rbind(v,rep(1,ncol(v))) ## homogeneous
e <- expand.grid(1:(n-1),1:n)
i1 <- apply(e,1,function(z)z[1]+n*(z[2]-1))
i2 <- i1+1
i3 <- (i1+n-1) %% n^2 + 1
i4 <- (i2+n-1) %% n^2 + 1
i <- rbind(i1,i2,i4,i3)
if (!qmesh)
quads3d(v[1,i],v[2,i],v[3,i],...)
else return(rotate3d(qmesh3d(v,i,material=list(...)),matrix=trans))
}
```

For demonstration, I'll use this covariance matrix:
$$\left(\begin{array} {cc}2.2&.4&.2\\.4&2.8&.3\\.2&.3&2.4\end{array}\right)$$

```
Covariance.Matrix=matrix(c(2.2,.4,.2,.4,2.8,.3,.2,.3,2.4),3)
Eigenvalue.Roots=eigen(Covariance.Matrix)$values^.5->X
require(rgl)
wire3d(ellipsoid3d(X[1],X[2],X[3],qmesh=T),col='lightgreen')
axes3d("x",pos=c(0,0,0),at=c(0,X[1]),labels='',lwd=2,col='maroon')
axes3d("y",pos=c(0,0,0),at=c(0,X[2]),labels='',lwd=2,col='maroon')
axes3d("z",pos=c(0,0,0),at=c(0,X[3]),labels='',lwd=2,col='maroon')
```

Rotating the `ellipsoid3d`

object is possible by using `rotate3d()`

inside `wire3d()`

, but I'm not sure how to find the angles $\phi,\theta,\psi$ from the eigenvectors. This is my best guess so far (based on this):

```
Phi=with(eigen(Covariance.Matrix),atan(vectors[3,2]/vectors[3,1]))
Theta=acos(eigen(Covariance.Matrix)$vectors[3,3])
Psi=with(eigen(Covariance.Matrix),atan(vectors[2,3]/-vectors[1,3]))
```

If these are known, the `euler`

function given here may help produce a matrix for `rotate3d`

's `matrix`

argument...but I'm not sure it works. With sample data, I seem to get a different rotation using John Fox's `scatter3d`

function. If you have a dataset of observation trios, not just a covariance matrix, `scatter3d`

seems to work well.

## Best Answer

`pnorm(z)`

will do it.Or if you insist on a percentile, boom. Then try