12
votes

I have the following 3d plot:

ro

With my data I created it with the following code:

library(rugarch)
library(rgl)
library(fGarch)

fd <- as.data.frame(modelfit, which = 'density')
color <- rgb(85, 141, 85, maxColorValue=255)

x <- seq(-0.2, 0.2, length=100)
y <-c(1:2318)

f <- function(s, t) {
 dged(s,mean=fd[t,'Mu'],sd=fd[t,'Sigma'],nu=fd[t,'Shape'])

}

z <- outer(x, y, f)
persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color,
      ticktype="detailed", xlab="", ylab="time", zlab="",axes=TRUE)

How can I get a coloring depending on the z values? I looked at different solutions, e.g. this one, but I could not create the coloring depending on the z values in this case. The solution according to this thread would be the following:

nrz <- nrow(z)
ncz <- ncol(z)
jet.colors <- colorRampPalette( c("#ffcccc", "#cc0000") ) 
# Generate the desired number of colors from this palette
nbcol <- 100
color <- jet.colors(nbcol)

# Compute the z-value at the facet centres
zfacet <- z[-1, -1] + z[-1, -ncz] + z[-nrz, -1] + z[-nrz, -ncz]
# Recode facet z-values into color indices
facetcol <- cut(zfacet, nbcol)

  persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color[facetcol],
          ticktype="detailed", xlab="", ylab="time", zlab="",axes=TRUE)

But this does not give a good result, since it does not color the plot appropriate. I want to have the spikes of my surface to be e.g. in red and the low values to be e.g. in blue with a nice smooth transition, but this kind of colors the slices, so depending on the time? So extreme large spikes should be colored at their spikes in red and values at the bottom e.g. in green. How can I get this?

Edit: I found a solution to my previous question about the date on the axis, the only problem left, is an appropriate coloring dependent on the z values.

3
Please note: I don't know why but I have to load the rgl package before opening the workspace otherwise my R crashes, I don't know why.Stat Tistician

3 Answers

25
votes

Try this:

nbcol = 100
color = rev(rainbow(nbcol, start = 0/6, end = 4/6))
zcol  = cut(z, nbcol)
persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color[zcol],
        ticktype="detailed", xlab="", ylab="time", zlab="",axes=TRUE)

theplot

If you want the coloring to be by time (so spikes are always red) you can set the coloring for each time slice:

mycut = function(x, breaks) as.numeric(cut(x=x, breaks=breaks)) # to combine different factors
zcol2 = as.numeric(apply(z,2, mycut, breaks=nbcol)) 
persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color[zcol2],
        ticktype="detailed", xlab="", ylab="time", zlab="",axes=TRUE)

theplot2

You already know how to edit the axes properly.

7
votes

To assert control over the axes, you need to set axes=FALSE (as you were told yesterday) in the persp3d call , and then use the axes3d and axis3d functions with arguments of your choosing. To specify an x axis with values displayed along the lower yz- box segment, use edge= 'x--'. To label the y-axis with rownames, use the 'labels' and 'at' arguments:

plot3d ( ..., axes=FALSE, ...)
# repositions x axis and draws default z axis
axes3d(c('x--','z'))  
# Use custom labels
axis3d(edge= 'y+-', at =seq(500,2000,by=500), 
                    labels = rownames(fd)[seq(500,2000,by=500)] )

enter image description here

(Note: To play this SO game properly, you need to give credit to others who have offered help. This is not much different from a question from yesterday and I see no positive response for the helpful contributions there. I'm wondering if people are becoming uninterested.)

4
votes

The following is a solution to answer your question on coloring the surface depending on the z values. The idea is to assign a color to each point of the surface based on its (relative) height. The code below includes the axes customization proposed by @DWin.

library(rugarch)
library(rgl)
library(fGarch)

fd <- as.data.frame(modelfit, which = 'density')
x  <- seq(-0.2, 0.2, length=100)
y  <- c(1:2318)

f <- function(s, t) {
    dged(s,mean=fd[t,'Mu'],sd=fd[t,'Sigma'],nu=fd[t,'Shape'])
}

z <- outer(x, y, f)

## Color definition of each point of the surface
height <- (z - range(z)[1]) / diff(range(z))
r.prop <- height
g.prop <- 0
b.prop <- 1 - height
color  <- rgb(r.prop, g.prop, b.prop, maxColorValue=1)

persp3d(x, y, z, theta=50, phi=25, expand=0.75, col=color,
        ticktype="detailed", xlab="", ylab="time", zlab="",axes=FALSE)
axes3d(c('x--','z'))  
# Use custom labels
axis3d(edge= 'y+-', at =seq(500,2000,by=500), 
       labels = rownames(fd)[seq(500,2000,by=500)] )

theplot