如果我不知道多项式函数,如何从列数据框中绘制 3D 表面

How to plot a 3D surface out of columns data frames if I do not know the polynomial function

我有一些经纬度数据。我的第三个变量是电动汽车在一个城市的普及率。因此,我有稀疏数据,我不知道 f(long,lat) -> MS_Year 的映射。我有以下数据

long              lat              MS_Year
<dbl>             <dbl>              <dbl>
 1 -66.0436169857389 50.3417726256247  0.0122
 2 -66.1704063635085 48.168838536499   0.0115
 3 -67.1376617834163 48.9202603958534  0.0136
 4 -67.474931686395  48.8025438021711  0.0108
 5 -67.5756670981796 48.5194066352801  0.0111
 6 -67.6273066949175 48.429540936994   0.0167

我已经能够毫无问题地绘制 3D 散点图。

scatterplot3d(Plot_Me_Tot_2019_grouped)

[在此处输入图片描述][1]

但是,我花了一整天的时间试图了解如何制作曲面。据我了解,这特别困难,因为我需要使用非参数估计器来显示拓扑的复杂程度。 (这个想法是为了证明非参数回归的合理性,我刚刚了解但从未使用过;它可能解释了我的全部斗争)。

因此,我需要创建一个输出为 MS_Year.

的多项式函数 f(long,lat)

我尝试按如下方式应用它:

library(predict3d)
library(rgl)

fit5=lm(MS_Year ~polym(long, lat,degree=5, raw=T),data=Plot_Me_Tot_2019_grouped)
predict3d(fit5,radius=0.05)

我这样做了,导致它将此 [多项式回归][2] 与此 [3D 绘图][3] 相结合。 彻底失败了。

有人遇到过类似的问题吗?

我觉得我的问题是创建链接函数 AKA f(long,lat),然后使用 expand.grid(long,lang) 创建一个曲面并绘制它。

你应该明白,我对从 DF 到 3D 表面所需的矩阵格式的转换没有很好的理解。

非常感谢您的宝贵时间 [1]: https://i.stack.imgur.com/6ceJj.png [2]: Polynomial regression with two variables with R [3]: https://cran.r-project.org/web/packages/predict3d/vignettes/predict3d.html

我认为您不需要整个表面的多项式:这可能非常不稳定,点之间存在大量变化。

但是,您可能需要低阶局部多项式拟合或一些低阶插值。

你没有发布你的真实数据,所以我用假数据来演示。首先,我们在点之间进行插值:

set.seed(123)
df <- data.frame(long = rnorm(100, -66, 1),
                 lat = rnorm(100, 49, 1))
df$MS_Year <- 0.015 + df$long/1000 + df$lat/1000 + rnorm(100, 0.01, 0.0005)
head(df)
#>        long      lat     MS_Year
#> 1 -66.56048 48.28959 0.007828523
#> 2 -66.23018 49.25688 0.008682913
#> 3 -64.44129 48.75331 0.009179444
#> 4 -65.92949 48.65246 0.007994563
#> 5 -65.87071 48.04838 0.006970499
#> 6 -64.28494 48.95497 0.009431914

library(interp)
surf <- interp(df$long, df$lat, df$MS_Year,
               xo = sort(df$long), yo = sort(df$lat))

library(rgl)
plot3d(df, type = "s", size = 0.5)
persp3d(surf, col = "gray", add = TRUE)

这在点之间做了双线性插值;它最终变得非常粗糙。您可能更喜欢将某种表面拟合到点而不是对它们进行插值。这适合局部平滑:

library(mgcv)
#> Loading required package: nlme
#> This is mgcv 1.8-38. For overview type 'help("mgcv-package")'.
fit <- gam(MS_Year ~ s(long, lat), data = df)
xo <- sort(df$long)
yo <- sort(df$lat)
grid <- expand.grid(long = xo, lat = yo)
pred <- predict(fit, newdata = grid)
plot3d(df, type = "s", size = 0.5)
persp3d(xo, yo, matrix(pred, 100,100), col = "gray", add = TRUE)

reprex package (v2.0.1)

于 2022-01-23 创建

那是同一个数据集,但是更平滑的人设法看到它在 longlat 中或多或少是线性的。您的数据可能不会以如此简单的形状结束。