简体   繁体   English

使用 persp3D(plot3D 包)在 3D 表面上添加网格

[英]Add grid over 3D surface using persp3D (plot3D package)

I'm trying to add a grid on top of a 3D surface created with persp3D (package plot3D ), however I can't sort a way of doing it without causing a deformation on the grid.我正在尝试在使用persp3D (包plot3D )创建的 3D 表面上添加一个网格,但是我无法在不导致网格变形的情况下进行排序。

library(plot3D)
data("volcano")

volcano is a 3D matrix that can be used to create a 3D plot by simply calling: volcano是一个 3D 矩阵,只需调用以下命令即可创建 3D plot:

persp3D(z=volcano)

What I intend to do is create a new grid using the dimensions of the 3D matrix and than add it to the 3D plot.我打算做的是使用 3D 矩阵的维度创建一个新网格,然后将其添加到 3D plot。

# new grid
x.seq <- seq(1, dim(volcano)[1], length = 20)
y.seq <- seq(1, dim(volcano)[2], length = 20)

# Visualize grid
plot(x=c(0,length(volcano[,1])), y=c(0,length(volcano[1,])), type='n')
abline(v=x.seq, h=y.seq)

I got close to it by subsetting the matrix volcano by the new sequences created and then plot the new 3D matrix over the original 3D surface.我通过创建的新序列对矩阵volcano进行子集化来接近它,然后在原始 3D 表面上创建新的 3D 矩阵 plot。

# New matrix using sequences created
mtx.sub <- volcano[time.seq, freq.seq]

# Plot new matrix on top of original surface
persp3D(z=volcano)
persp3D(z=amp.sub, border="black", facets=NA, add=T, colkey=list(plot=F))

具有重叠网格的 3D 图

Even though the result is close to what I expected, a closer look will show that the grid is not really on top of the existing surface, it is a whole new surface that do not match the original one (which is quite obvious, given that it is a different matrix).尽管结果接近我的预期,但仔细观察会发现网格并不真正位于现有表面之上,它是一个全新的表面,与原始表面不匹配(这很明显,因为它是一个不同的矩阵)。

What I'm looking for is a way to add a 2D grid that will go over the original surface, something similar to abline , but for a 3D plot.我正在寻找的是一种在原始表面上添加 go 的 2D 网格的方法,类似于abline ,但对于 3D plot。

I had a look at plot3D documentation and searched on the web, but none of the solutions apply to persp3D() .我查看了plot3D文档并在 web 上进行了搜索,但没有一个解决方案适用于persp3D()

Any thoughts on a way around this?关于解决这个问题的任何想法?

You can add the grid directly within the call to persp3D :您可以直接在对persp3D的调用中添加网格:

persp3D(z=volcano, border="black", lwd=0.3)

在此处输入图片说明

In response to your comment, you could plot at lower resolution to get wider borders, however, the surface will also be at lower resolution (see below).为了回应您的评论,您可以以较低的分辨率绘制以获得更宽的边界,但是,表面的分辨率也会较低(见下文)。 It would be nice to be able to plot the surface at full resolution and then have a sparser net of border lines that still matches the high-resolution surface, for example, by plotting the border lines only on every other facet, but I'm not sure how to do that without hacking persp3D (or one of the functions called by persp3D ).能够以全分辨率绘制表面然后有一个仍然与高分辨率表面匹配的稀疏边界线网络会很好,例如,通过仅在每个其他方面绘制边界线,但我不知道如何在不破解persp3D (或persp3D调用的函数之一)的情况下做到这persp3D

persp3D(z=volcano[seq(1,nrow(volcano),2), seq(1,ncol(volcano),2)], 
        border="black", lwd=0.4)

在此处输入图片说明

A work around is to use ribbon3D .解决方法是使用ribbon3D It requires some more lines of code and messing around with parameters, but it does work reasonable.它需要更多的代码行和乱七八糟的参数,但它确实可以正常工作。

例子

require(plot3D)

### create data from 3D plotting
###
### x1, x2 a grid
### x the value of a normal distribution
x1 <- seq(-4,4,0.025)
x2 <- seq(-4,4,0.025)
mu = 0
z <- matrix(rep(0,length(x1)*length(x2)),length(x1))
for (i in 1:length(x1)) {
  for(j in 1:length(x2)) {
    z[i,j] <- dnorm(x1[i],mu,1)*dnorm(x2[j],mu,1)
  }
}

### plot 3D
sel = 1+c(1:32)*10  ### selection of the grid lines to plot
persp3D(x1,x2,z, 
        border = NA, facets = TRUE, col = rgb(1,1,1,0.5), 
        theta = 30, phi = 30, 
        zlim = c(0,0.26))
ribbon3D(x1[sel],x2,z[sel,], 
         border = NA, facets  = NA, col = 1, width = 0.02,
         along = "y", space = 0.9, add = TRUE)
ribbon3D(x1[],x2[sel],z[,sel], 
         border = NA, facets  = NA, col = 1, width = 0.02,
         along = "x", space = 0.9, add = TRUE)

Example with the volcano data火山数据示例

火山的例子

require(plot3D)

### create data from 3D plotting
x <- 1:length(volcano[,1])
y <- 1:length(volcano[1,])
z <- volcano

### plot 3D
selx = seq(1,max(x),4)
sely = seq(1,max(y),4)
persp3D(x,y,z, 
        border = NA, facets = TRUE, lwd = 0.03,
        theta = 30, phi = 30)
ribbon3D(x[selx],y,z[selx,], 
         border = 1, facets  = 1, col = 1, width = 0.1,
         along = "y", space = 0.9, add = TRUE)
ribbon3D(x[],y[sely],z[,sely], 
         border = 1, facets  = 1, col = 1, width = 0.1,
         along = "x", space = 0.9, add = TRUE)

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

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