如何通过 R 中的 3D 数据绘制曲面拟合?
How to plot surface fit through 3D data in R?
我有一个呈现如下的 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*ndataframes
,用rbind
组合在一起,用每个dataframe
中包含的key区分
我尝试通过各种方法拟合曲面,例如 add_surface()
、add_trace()
,将类型更改为 'mesh3D'
但是,最终的表面拟合不是我想要的,我需要通过这个散点数据进行平滑的表面拟合。我得到的错误是:z is not a numeric matrix.
有没有更好的拟合表面的方法,我在这里缺少什么?
P.S。我更喜欢用 ggplot()
, plot_ly()
, ggplotly()
.
渲染情节
您可以先使用 gam()
之类的方法拟合模型,然后绘制预测图。首先,我们可以使 GAM 适合数据。在这种情况下,hp
和 wt
是两个自变量(即上图的 x
和 y
轴)。 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
。我们要传入的 x-y 对是用于预测的 hp
和 wt
的值。该函数生成一个数据框,其中包含一个观察值和两个变量 - hp
和 wt
。它使用该新数据框使用 predict()
函数从模型生成单个预测。
predfun <- function(x,y){
newdat <- data.frame(hp = x, wt=y)
predict(mod, newdata=newdat)
}
接下来,我们将该预测函数应用于我们上面制作的数据序列。我们使用 outer()
外积函数为每个 hp.seq
和 wt.seq
的组合创建一个 25x25 的预测值矩阵。将 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))
我有一个呈现如下的 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*ndataframes
,用rbind
组合在一起,用每个dataframe
我尝试通过各种方法拟合曲面,例如 add_surface()
、add_trace()
,将类型更改为 'mesh3D'
但是,最终的表面拟合不是我想要的,我需要通过这个散点数据进行平滑的表面拟合。我得到的错误是:z is not a numeric matrix.
有没有更好的拟合表面的方法,我在这里缺少什么?
P.S。我更喜欢用 ggplot()
, plot_ly()
, ggplotly()
.
您可以先使用 gam()
之类的方法拟合模型,然后绘制预测图。首先,我们可以使 GAM 适合数据。在这种情况下,hp
和 wt
是两个自变量(即上图的 x
和 y
轴)。 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
。我们要传入的 x-y 对是用于预测的 hp
和 wt
的值。该函数生成一个数据框,其中包含一个观察值和两个变量 - hp
和 wt
。它使用该新数据框使用 predict()
函数从模型生成单个预测。
predfun <- function(x,y){
newdat <- data.frame(hp = x, wt=y)
predict(mod, newdata=newdat)
}
接下来,我们将该预测函数应用于我们上面制作的数据序列。我们使用 outer()
外积函数为每个 hp.seq
和 wt.seq
的组合创建一个 25x25 的预测值矩阵。将 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))