首页 > 解决方案 > 如何通过 R 中的 3D 数据绘制曲面拟合?

问题描述

我有一个 3D 散点图,呈现如下:

在此处输入图像描述

3D 数据集非常大,所以我不能在这里包含它。mtcars可以尝试使用标准数据集(如或)来回答这个问题iris

我尝试绘制这个 3D 散点图:

x <- rbind(A_0,A_1,A_2,A_3) 
fig1 <- x %>% plot_ly(x= ~x,y=~y,z = ~z, color= ~key,type="scatter3d", size = 0.5)
fig1 

A_0, A_1, A_2, A_3是不同的 3*n dataframes,它们使用组合在一起,rbind并使用每个包含的键进行区分dataframe

我尝试通过各种方法拟合曲面,例如add_surface()add_trace()将类型更改为'mesh3D'

但是,得到的表面拟合不是我想要的,我需要通过这个散点数据进行平滑的表面拟合。我得到的错误是:z is not a numeric matrix.

有没有更好的拟合表面的方法,我在这里错过了什么?

PS我更喜欢用ggplot(), plot_ly(),来渲染情节ggplotly()

标签: rggplot2shiny3dplotly

解决方案


您可以先使用类似的东西拟合模型gam(),然后绘制预测。首先,我们可以将 GAM 拟合到数据中。在这种情况下,hpwt是两个自变量(即上图的xy轴)。 qsec是绘制在 z 轴上的变量,是模型中的因变量。

data(mtcars)
library(mgcv)
mod <- gam(qsec ~ te(hp) + te(wt) + ti(hp, wt), data=mtcars)

接下来,我们需要在hp和的不同组合下对模型进行一些预测wt。最简单的方法是为每个变量创建一个从最小值到最大值的值序列。这就是下面的命令所做的。它生成了一系列 25 个均匀间隔的值,从每个自变量的最小值到最大值。

hp.seq <- seq(min(mtcars$hp, na.rm=TRUE), max(mtcars$hp, na.rm=TRUE), length=25)
wt.seq <- seq(min(mtcars$wt, na.rm=TRUE), max(mtcars$wt, na.rm=TRUE), length=25)

接下来,我们可以创建一个生成预测的函数。因为我们将在outer()下面使用,我们应该让函数接受两个输入x和一个y。我们要传入的 xy 对是用于预测hp的值。wt该函数创建一个具有一个观察值和两个变量的数据框 -hpwtpredict()它使用该新数据框从使用该函数的模型生成单个预测。

predfun <- function(x,y){
  newdat <- data.frame(hp = x, wt=y)
  predict(mod, newdata=newdat)
}

接下来,我们将该预测函数应用于我们上面制作的数据序列。我们使用outer()外积函数为hp.seq和的每个组合制作一个 25x25 的预测值矩阵wt.seq。包裹可防止有关替换长度问题predfun的错误。Vectorize()

fit <- outer(hp.seq, wt.seq, Vectorize(predfun))

最后,我们可以将所有内容放在一起plot_ly。我们使用add_marker()添加点和add_surface添加预测。

plot_ly() %>% 
  add_markers(x = ~mtcars$hp, y=mtcars$wt, z=mtcars$qsec) %>% 
  add_surface(x = ~hp.seq, y = ~wt.seq, z = t(fit))

在此处输入图像描述


推荐阅读