R Plotly How to Get 3D Surface with Lat, Long and Z

r plotly how to get 3d surface with lat, long and z

Sometimes writing a question helps to find the answer to it. The manipulation needed is a spatial interpolation (kriging) program of some kind. This stackoverflow Q and A explains the basics and gives specific examples. With the data set described in the question above, the following lines provide a solution. The link also has other approaches as well.

library(akima)
library(plotly)
s = interp(x = df$x, y = df$y, z = df$z)
p <- plot_ly(x = s$x, y = s$y, z = s$z) %>% add_surface()

How to return matrix of z values along x-y coordinates to make 3D surface plot by plot_ly in R?

As far as I can see, this isn't possible with predict_gam, but you can do it with the standard predict function as follows. I'll use some fake data, since you didn't provide a reproducible example (or even one with two predictors):

library(mgcv)
x <- runif(100)
y <- runif(100)
z <- x^2 + y + rnorm(100)
df <- data.frame(x, y, z)
gam_fit <- gam(z ~ s(x) + s(y), data = df)

newx <- seq(0, 1, len=20)
newy <- seq(0, 1, len=30)
newxy <- expand.grid(x = newx, y = newy)
z <- matrix(predict(gam_fit, newdata = newxy), 20, 30)
library(plotly)
plot_ly(x = newx, y = newy, z = z) %>% add_surface()

This produces this output:

screenshot

plotting 3D surface with plotly (matrix transformation with akima::interp)

It appears the meanings of x and y are swapped in the add_surface versus the meanings in interp. The example that worked had x and y appear symmetrically. So swap them back by transposing the z matrix:

fig <- plot_ly()%>% 
add_surface(x = s$x, y = s$y, z = t(s$z))%>%
add_markers(data=df,x = ~x, y = ~y, z = ~z,
marker = list(color = "blue",
showscale = TRUE))

fig

This is just a guess because the documentation in plotly is so weak. akima::interp clearly documents that rows of z correspond to different x values.

Problem in Plotting and Adding Surface in Plotly

z should be a matrix. You can use outer, as follows:

x <- seq(0, 8, length.out=100)
y <- seq(0, 3, length.out=30)
z <- t(outer(x, y, FUN=function(x,y) 5/3*y + 4*exp(-(x-4)^2)))

library(plotly)
plot_ly(x=x, y=y, z=z) %>%
add_surface() %>%
layout(
scene = list(
xaxis= list(title="X"),
yaxis= list(title="Y"),
aspectmode = 'manual',
aspectratio = list(x=1, y=1, z=.5)
)
)

Sample Image



Related Topics



Leave a reply



Submit