R: 4D plot, x, y, z, colours

前端 未结 3 1195
抹茶落季
抹茶落季 2020-11-28 10:53

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

相关标签:
3条回答
  • 2020-11-28 11:16

    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

    0 讨论(0)
  • 2020-11-28 11:16

    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))
    
    0 讨论(0)
  • 2020-11-28 11:29

    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(32)[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(32)[floor(31*hgt+1)], alpha=0.5)
    
    0 讨论(0)
提交回复
热议问题