Does anyone have any advice, or can point me to a resource, to help with converting a dataframe to a matrix for use in a plot_ly 3d surface graph? There are a few questions similar to this, but none of them seem to do the trick.
I have a dataframe df
with columns A, B, and C. I'd like to plot A and B on the x-y plane and have C as the z variable.
I can convert my dataframe to a matrix using dfm <- as.matrix(df, rownames.force = NA)
, then I can call plot_ly and reorder columns like so:
fig <- plot_ly(z=~dfm[,c(1,3,2)], type = "surface")
fig <- fig %>% add_surface()
fig
but this gives a very strange result:
which is not at all what the underlying data looks like.
Any advice here? My hunch is the issue is springing from the conversion to a matrix. If so any pointers on how to map a dataframe's columns onto an x-y-z surface greatly appreciated
What plotly
wants in the matrix are z
values. The rows of the matrix correspond to y
values, and the columns to x
values. If your dataframe contains x
, y
and z
values, then converting to this format strongly depends on what kinds of values you have.
The simplest case would be that your data really corresponds to the format that plotly
wants, with x
and y
values repeated. That's possible, but it's not common.
A more common case is that you have unstructured x
and y
locations, and measured z
values at each of them. Then you need to do some calculations to put them on a grid. The interp
package can do that. For example:
set.seed(123)
df <- data.frame(x = rnorm(100), y = rnorm(100, mean = 10), z = rnorm(100, mean = 20))
xyz <- with(df, interp::interp(x, y, z))
library(plotly)
with(xyz, plot_ly(x = ~x, y = ~y, z=~z, type="surface"))