3D equivalent of the curve function in R?

2019-01-15 14:06发布

The curve function in R provides a simple way to plot a function. For example, this will plot a straight line

f1 <- function(x) x
curve(f1, from=-1, to=1)

Is there an equivalent function in R which takes a function with two argument (e.g., x and y) and ranges for both variables and produces a 3D plot?

For example, imagine I had the following function

f2 <- function(x, y) x + y

Is there a command similar to the following?

curve_3d(f2, x_range=c(-1, 1), y_range=c(-1, 1))

标签: r 3d rgl
4条回答
We Are One
2楼-- · 2019-01-15 14:32

You can have an interactive plot with the plot3Drgl package.

library(plot3Drgl)

f <- function(x,y) x+y
x <- y <- seq(-4,4,len=20)
z <- outer(x, y, f)

persp3Drgl(z=z)

enter image description here

查看更多
看我几分像从前
3楼-- · 2019-01-15 14:34

See curve3d() in package:emdbook, which is a wrapper for wireframe(), persp3d(), and more.

library(emdbook)
# bivariate normal density with emdbook::curve3d
curve3d(expr = dmvnorm(x=c(x,y), mu = c(0,0), Sigma = diag(2)), 
    from = c(-3,-3), to = c(3,3), n = 100, sys3d = "wireframe")
查看更多
仙女界的扛把子
4楼-- · 2019-01-15 14:41

The surface3d function in package:rgl looks like a good match. It would be very simple to create a wrapper that would take your function, create an x-y set of vectors with seq() and then pass those vectors to outer with your f2 as the FUN argument, and then call surface3d.

There is also a persp3d which the authors (Duncan Murdoch and perhaps others) say is "higher level" and it does appear to add axes by default which surface3d does not.

curve_3d <- function(f2, x_range=c(-1, 1), y_range=c(-1, 1), col=1:6 ){ 
       if (!require(rgl) ) {stop("load rgl")}
       xvec <- seq(x_range[1], x_range[2], len=15)
        yvec <- seq(y_range[1], y_range[2], len=15)
       fz <- outer(xvec, yvec, FUN=f2)
       open3d()
       persp3d( xvec, yvec, fz, col=col) }
curve_3d(f2)
snapshot3d("out3dplane.png")

Rotatable pseudo3d plot of plane

Now that I think about it further, you could have done something similar with persp() or wireframe(). The "trick" is using outer(..., FUN=fun). And as I think about it even further ... the ability to use it with outer depends on it being composed of all vectorized operations. If they were not vectorized, we would need to rewrite with Vectorize or mapply.

查看更多
别忘想泡老子
5楼-- · 2019-01-15 14:46

The persp3d() function can take a function as an argument. See ?persp3d.function.

It allows two kinds of surface to be plotted: a function of x and y as you want, and a parametric surface, where x, y and z are all functions of two other variables.

For your example, it's as simple as

f2 <- function(x, y) x + y
persp3d(f2)

but of course you can add all sorts of frills, like having the colour depend on z, changing the range of x and y, etc.

查看更多
登录 后发表回答