简体   繁体   English

R中的“切出” 3D表面图

[英]“Cut out” 3D Surface Plot in R

I've created a 3d surface plot in R using persp() - though I'm not wed to that package by any means if something else would solve this problem better. 我已经使用persp()在R中创建了一个3d表面图-尽管如果有其他方法可以更好地解决此问题,则无论如何我都不会嫁给该程序包。 My variables on the x and y axis, respectively, are temperature and precipitation. 我在x和y轴上的变量分别是温度和降水量。 I've created a grid that extends from my min-max temp, and min-max precip, and predicted values from my function for the z-axis. 我已经创建了一个网格,该网格从我的最小-最大温度和最小-最大降水量开始,并从我的函数中为z轴预测了值。

However, realistically, my data does not truly "extend that far" (ie I don't have data at the tails [eg a combination of the lowest precip and the lowest temp]) so the extrapolation is a little misleading. 但是,实际上,我的数据并没有真正“延伸那么远”(即我没有数据的尾部(例如最低降水量和最低温度的组合)),因此外推有点误导。

I'm wondering if there's an easy way to "bound" my plot, and I'm open to many types of suggestions. 我想知道是否有一种简单的方法可以“约束”我的情节,并且我愿意接受许多类型的建议。 I could color-code values that are out of the range of observed weather conditions, or if there's a way to "cut out" the surface, that would be great too. 我可以用颜色编码超出观察到的天气条件范围的值,或者如果有一种方法可以“切出”表面,那也很棒。 For example, I've found the "bounds" (eg the highest and lowest observed precip for each rounded temp value). 例如,我找到了“界限”(例如,每个舍入温度值的最高和最低观测值)。 I could use the bounds as a "jagged cookie cutter," but I have also fit a Gaussian-like curve using scatter.smooth() from which I think I can get a smoothed function to describe the boundary. 我可以将边界用作“锯齿曲奇切割器”,但是我还使用scatter.smooth()拟合了类似高斯的曲线,从中我可以得到一个平滑的函数来描述边界。

Please let me know if you have any suggestions; 如果您有任何建议,请告诉我; I'm finding a solution hard to come by but maybe I'm just looking in the wrong place. 我发现很难找到解决方案,但也许我只是在错误的地方寻找。 Thanks! 谢谢!

Take a look at the exclude.too.far() function in the mgcv package, which was designed for the exact same plotting purpose you describe but in relation to 2-d splines. 看一下mgcv软件包中的exclude.too.far()函数,该函数是为与您描述的完全相同的绘图目的而设计的,但与二维样条曲线有关。

An illustration of what this function does is given below, taken from the example of ?exclude.too.far 下面以?exclude.too.far为例,给出了此功能的说明。

library("mgcv")
x <- rnorm(100)
y <- rnorm(100) # some "data"
n <- 40 # generate a grid....
mx <- seq(min(x), max(x), length = n)
my <- seq(min(y), max(y), length = n)
gx <- rep(mx, n)
gy <- rep(my, rep(n, n))
tf <- exclude.too.far(gx, gy, x, y, 0.1)
plot(gx[!tf], gy[!tf], pch = ".")
points(x, y, col=2)

在此处输入图片说明

In the figure, the black points are the grid locations within 0.1 distance (after translating the grid to the unit square; so think of the 0.1 as being about 10% of the range of the data) of the observations, which are shown as large red points. 在图中,黑点是观测值在0.1距离之内的栅格位置(将栅格转换为单位正方形后,因此将0.1视为数据范围的10%),这些观测值显示为较大红点。

In the persp() setting, you have x , y , and z . persp()设置中,您具有xyz Proceed as above to define the grid (the same grid that you used to create the persp() plot) and then use exclude.too.far() to identify which grid points lie too far from the data. 按上述步骤进行操作以定义网格(用于创建persp()图的网格),然后使用exclude.too.far()来识别哪些网格点与数据相距太远。 Set the values in z to NA where exclude.too.far() returns TRUE . z的值设置为NA ,其中exclude.too.far()返回TRUE Then plot the modified z using persp() . 然后使用persp()绘制修改后的z

If you want to do your "cookie-cutter" approach, you could do something like this with the sp library and point.in.polygon function. 如果要使用“ cookie-cutter”方法,则可以使用sp库和point.in.polygon函数执行类似的point.in.polygon You would need the points specifying the perimeter you were interested in to contruct the polygon. 您将需要指定要构建多边形的周长的点。

## Make some data
f <- function(theta) (1+1.5*cos(9*theta)) * (1+sin(theta)) + (1+0.5*cos(100*theta)) + (1+0.3*cos(50*theta))
x <- seq(-pi, pi, len=100)
dat <- data.frame(x=cos(x), y=sin(x)) * f(x)  # points for edges of polygon

library(sp)
d <- function(a, b) {  # density function to get z values
    ifelse(point.in.polygon(a, b, dat$x, dat$y) > 0, 1, 0)  # only points in range
}
ps <- outer(seq(min(dat$x), max(dat$x), len=100), 
             seq(min(dat$y), max(dat$y), len=100), d)
persp(ps, zlim=c(0, 3), theta=35, xlab="x", ylab="y", phi=25)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM