2

I have a 3 D array. The heads of the columns are "height", "weight", and "age". How can I plot a 3 D histogram using hist3d or any other available function ?

file<-read.csv(file.choose(),TRUE,"")
x <- file$height 
y <- file$weight
z<- file$age
xlab="Height"
ylab="Weight"
zlab="Age"

I started with this code but then I got stuck on how to draw a 3 D histogram. Thak you for your precious time

bombarder
  • 21
  • 2
  • 2
    What exactly do you think a 3D histogram would look like? You might have a 3D histogram for 2 variables (x=var1, y=var2, z=freq) but for three independent variables you'd need 4 dimensions to represent frequencies. somehow. This doesn't make a lot of sense. Also, supply some real data to make a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – MrFlick May 02 '15 at 19:16
  • @MrFlick sorry for not being that clear, and yes the variables are absolutely dependent just as the example you have just gave (x=var1, y=var2, z=freq) – bombarder May 02 '15 at 19:39
  • 1
    We really need a reproducible example, please. You haven't clarified much: do you want the height of the bars (in the z-direction) to represent age (in which case there should only be a single entry for each (height,weight) pair)? – Ben Bolker May 02 '15 at 20:43
  • @BenBolker To be sincere i have come up with this example just because i thought it was easy The real problem is that i have a network of routers each routers is represented with two coordinates X and Y and for each routers ( means for each X and Y ) i have the latency of that router ( that means the time taken by the router to submit its data to the next router) and here is my 3D array X Y Latency 0 0 461 0 1 10295 0 2 0 0 3 0 1 0 169 1 1 7089 1 2 4310 1 3 0 I hope that things are so much clearer now if it's not the case don't hesitate to ask me – bombarder May 02 '15 at 20:57

1 Answers1

0
dat <- read.table(header=TRUE,
text="
X Y Latency 
0 0 461 
0 1 10295 
0 2 0 
0 3 0 
1 0 169 
1 1 7089 
1 2 4310 
1 3 0")

What you're looking for is technically a 3D bar plot, not a histogram (which would be a summary of the number of discrete points falling within a specified (X,Y) bin).

Here's one solution:

library("epade")
with(dat,
   bar3d.ade(xticks=unique(X),yticks=unique(Y),
            matrix(Latency,ncol=2),
                 col="gray",alpha=0.5))

Or, modifying from demo("hist3d",package="rgl"):

library("rgl")
barplot3d_0 <- function(x,y,z,alpha=1,topcol="#ff0000",sidecol="#aaaaaa")
 {
   save <- par3d(skipRedraw=TRUE)
   on.exit(par3d(save))

  x1 <- c(rep(c(x[1],x[2],x[2],x[1]),3),rep(x[1],4),rep(x[2],4))
  z1 <-c(rep(0,4),rep(c(0,0,z,z),4))
  y1 <-c(y[1],y[1],y[2],y[2],rep(y[1],4),
          rep(y[2],4),rep(c(y[1],y[2],y[2],y[1]),))
  x2 <-c(rep(c(x[1],x[1],x[2],x[2]),2),
        rep(c(x[1],x[2],rep(x[1],3),rep(x[2],3)),))
  z2 <-c(rep(c(0,z),4),rep(0,8),rep(z,8) )
  y2 <-c(rep(y[1],4),rep(y[2],4),
        rep(c(rep(y[1],3),rep(y[2],3),y[1],y[2]),2) )
  quads3d(x1,z1,y1,col=rep(sidecol,each=4),alpha=alpha)
  quads3d(c(x[1],x[2],x[2],x[1]),rep(z,4),c(y[1],y[1],y[2],y[2]),
            col=rep(topcol,each=4),alpha=1) 
  lines3d(x2,z2,y2,col="#000000")
 }
 barplot3d <- function(x,y,z,aspect=c(1,1,1)) {
    dx <- diff(unique(sort(x)))[1]
    dy <- diff(unique(sort(y)))[1]
    mapply(function(x,y,z) {
               barplot3d_0(c(x-dx/2,x+dx/2),
                           c(y-dy/2,y+dy/2),
                           z)
           },x,y,z)
    aspect3d(aspect)
}
with(dat,barplot3d(X,Y,Latency))
axes3d()
##  Z/Y confusion can probably be sorted out ...
title3d(xlab="X",zlab="Y",ylab="Latency")
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • you have to look at the example data set I gave and adapt the answer to your situation. – Ben Bolker May 02 '15 at 22:44
  • It worked thanks @Ben Bolker how can i add axes label and enumeration to them and is it possible to rotate the graph because i couldn't – bombarder May 02 '15 at 22:47
  • That was great, that's what i wanted thank you very much . I am just wondering whether we can change the type of the plot to line segments just by curiosity . Thank you again – bombarder May 02 '15 at 23:40
  • I don't know what you mean. Can you give a link to a picture that shows a similar value? Check out the `scatterplot3d` package too. – Ben Bolker May 02 '15 at 23:42
  • Indeed, i have just found a code on the net that contains line segments "my.mat <- matrix(runif(25), nrow = 5) dimnames(my.mat) <- list(LETTERS[1:5], letters[11:15]) s3d.dat <- data.frame(columns = c(col(my.mat)), rows = c(row(my.mat)), value = c(my.mat)) scatterplot3d(s3d.dat, type = "h", lwd = 5, pch = " ", x.ticklabs = colnames(my.mat), y.ticklabs = rownames(my.mat), color = grey(25:1 / 40))" Is it possible that i can have something similar ? the problem is that i didn't know how to include the data i have (X,Y and Latency) in the code above – bombarder May 02 '15 at 23:49
  • Another question would be what is the command that will make a box rotate ? – bombarder May 02 '15 at 23:53
  • Thank you very much you were a real help – bombarder May 03 '15 at 00:25