在R中绘制3D数据

R_U*_*ser 45 3d plot r

我有一个3D数据集:

data = data.frame(
    x = rep( c(0.1, 0.2, 0.3, 0.4, 0.5), each=5),
    y = rep( c(1, 2, 3, 4, 5), 5)
)

data$z = runif(
    25,
    min = (data$x*data$y - 0.1 * (data$x*data$y)),
    max = (data$x*data$y + 0.1 * (data$x*data$y))
)

data
str(data)
Run Code Online (Sandbox Code Playgroud)

我想绘制它,但R alwyas的内置函数给出了错误

增加'x'和'y'值预期

# ### 3D Plots ######################################################
# built-in function always give the error
#    "increasing 'x' and 'y' values expected"
demo(image)
image(x = data$x, y = data$y, z = data$z)

demo(persp)
persp(data$x,data$y,data$z)

contour(data$x,data$y,data$z)
Run Code Online (Sandbox Code Playgroud)

当我在互联网上搜索时,我发现当X和Y值的组合不唯一时会发生此消息.但在这里他们是独一无二的

我尝试了一些其他的库,它没有问题.但我不喜欢这些图的默认样式(内置函数应该满足我的期望).

# ### 3D Scatterplot ######################################################
# Nice plots without surface maps?
install.packages("scatterplot3d", dependencies = TRUE)
library(scatterplot3d)
scatterplot3d(x = data$x, y = data$y, z = data$z)

# ### 3D Scatterplot ######################################################
# Only to play around?
install.packages("rgl", dependencies = TRUE)
library(rgl)
plot3d(x = data$x, y = data$y, z = data$z)
lines3d(x = data$x, y = data$y, z = data$z)
surface3d(x = data$x, y = data$y, z = data$z)
Run Code Online (Sandbox Code Playgroud)

为什么我的数据集不被内置函数接受?

谢谢你的帮助,

斯文

Bac*_*lin 54

我使用的lattice包几乎是我在R中绘制的所有内容,它有一个相应的情节来persp调用wireframe.让我们data按照Sven的定义.

wireframe(z ~ x * y, data=data)
Run Code Online (Sandbox Code Playgroud)

线框图

或者这个怎​​么样(在Deepanyan Sarkar的书中修改图6.3 ):

p <- wireframe(z ~ x * y, data=data)
npanel <- c(4, 2)
rotx <- c(-50, -80)
rotz <- seq(30, 300, length = npanel[1]+1)
update(p[rep(1, prod(npanel))], layout = npanel,
    panel = function(..., screen) {
        panel.wireframe(..., screen = list(z = rotz[current.column()],
                                           x = rotx[current.row()]))
    })
Run Code Online (Sandbox Code Playgroud)

使用面板和更新的多个线框图

更新:使用OpenGL绘制曲面

由于这篇文章继续引起人们的注意,我想添加OpenGL方法来制作3-d图(如下面的@tucson所示).首先,我们需要将数据集从xyz-tripplet重新格式化为轴向量xy矩阵z.

x <- 1:5/10
y <- 1:5
z <- x %o% y
z <- z + .2*z*runif(25) - .1*z

library(rgl)
persp3d(x, y, z, col="skyblue")
Run Code Online (Sandbox Code Playgroud)

RGL :: persp3d

此图像可以使用鼠标自由旋转和缩放,或使用其他命令进行修改,当您满意时,可以使用它保存rgl.snapshot.

rgl.snapshot("myplot.png")
Run Code Online (Sandbox Code Playgroud)


hat*_*rix 23

如果您正在使用"实际"数据,其网格间隔和序列无法保证增加或唯一(希望(x,y,z)组合至少是唯一的,即使这些三元组是重复的),我建议使用akima包来进行插值不规则网格到常规网格.

使用您的定义data:

library(akima)
im <- with(data,interp(x,y,z))
with(im,image(x,y,z))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这不仅适用于image类似功能,也适用于类似功能.

请注意,数据映射到的默认网格akima::interp由跨越范围xy值的40个相等间隔定义:

> formals(akima::interp)[c("xo","yo")]
$xo
seq(min(x), max(x), length = 40)

$yo
seq(min(y), max(y), length = 40)
Run Code Online (Sandbox Code Playgroud)

但当然,这可以通过传递参数覆盖xoyoakima::interp.


Meg*_*ron 19

添加到其他人的解决方案,我想建议使用该plotlyR,因为这对我来说效果很好.

下面,我使用上面建议的重新格式化的数据集,从xyz-tripplets到轴向量x和y以及矩阵z:

x <- 1:5/10
y <- 1:5
z <- x %o% y
z <- z + .2*z*runif(25) - .1*z

library(plotly)
plot_ly(x=x,y=y,z=z, type="surface")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

可以使用鼠标旋转和缩放渲染表面.这在RStudio中运行得相当好.

您还可以使用以下内置volcano数据集进行尝试R:

plot_ly(z=volcano, type="surface")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Hen*_*nry 9

我认为以下代码接近你想要的

x    <- c(0.1, 0.2, 0.3, 0.4, 0.5)
y    <- c(1, 2, 3, 4, 5)
zfun <- function(a,b) {a*b * ( 0.9 + 0.2*runif(a*b) )}
z    <- outer(x, y, FUN="zfun")
Run Code Online (Sandbox Code Playgroud)

它提供了这样的数据(注意x并且y都在增加)

> x
[1] 0.1 0.2 0.3 0.4 0.5
> y
[1] 1 2 3 4 5
> z
          [,1]      [,2]      [,3]      [,4]      [,5]
[1,] 0.1037159 0.2123455 0.3244514 0.4106079 0.4777380
[2,] 0.2144338 0.4109414 0.5586709 0.7623481 0.9683732
[3,] 0.3138063 0.6015035 0.8308649 1.2713930 1.5498939
[4,] 0.4023375 0.8500672 1.3052275 1.4541517 1.9398106
[5,] 0.5146506 1.0295172 1.5257186 2.1753611 2.5046223
Run Code Online (Sandbox Code Playgroud)

和图表一样

persp(x, y, z)
Run Code Online (Sandbox Code Playgroud)

persp(x,y,z)

  • 我认为问题是你是否可以重新排列你的真实数据,所以`z`是一个矩阵和`x`和`y`向量. (2认同)