R新手求助:Plotly绘制3D曲面图异常及替代方案咨询
Hey there! Let's break down what's going wrong with your Plotly 3D surface plot, and fix it step by step.
Why your current code isn't working
The key issue here is that plotly::add_surface() expects a 2D wide-format matrix where:
- Rows correspond to unique
xvalues - Columns correspond to unique
yvalues - Each cell holds the corresponding
zvalue (forming a regular grid)
But your d3 matrix is a long-format 3-column matrix (z, y, x in rows), so Plotly is treating the row indices as the x-axis, column indices as the y-axis, and the matrix values as z—hence the mismatched axes you're seeing.
Fixing the Plotly code
First, you need to convert your long-format data into a regular grid. Since your sample data looks like scattered points (not a pre-defined grid), we'll use interpolation to create a smooth grid. Here's how:
# Load required packages library(plotly) library(akima) # For interpolation # Use your original dataframe (no need to convert to matrix first!) # Interpolate scattered x/y/z into a regular grid interpolated_grid <- interp( x = mydataframe$x, y = mydataframe$y, z = mydataframe$z, nx = 50, ny = 50 # Adjust resolution as needed ) # Now plot the surface with the correct axes plot_ly( x = interpolated_grid$x, y = interpolated_grid$y, z = interpolated_grid$z ) %>% add_surface() %>% layout(scene = list(xaxis = list(title = "x"), yaxis = list(title = "y"), zaxis = list(title = "z")))
If your data already has a regular grid (each x pairs with every y), you can skip interpolation and use tidyr::pivot_wider to reshape directly:
library(tidyr) # Reshape to wide format wide_data <- mydataframe %>% select(x, y, z) %>% pivot_wider(names_from = y, values_from = z) # Convert to matrix for Plotly z_matrix <- as.matrix(wide_data[, -1]) rownames(z_matrix) <- wide_data$x # Plot plot_ly( x = as.numeric(rownames(z_matrix)), y = as.numeric(colnames(z_matrix)), z = z_matrix ) %>% add_surface()
Alternative 3D surface plotting methods
If you want other options beyond Plotly, here are two solid choices:
1. Base R's persp() (static plots)
Great for quick static 3D surfaces with customizable color schemes similar to regression plots:
# Use the interpolated grid from earlier persp( interpolated_grid$x, interpolated_grid$y, interpolated_grid$z, col = terrain.colors(100), # Warm/cool gradient palette theta = 30, phi = 30, # Adjust view angle xlab = "x", ylab = "y", zlab = "z" )
2. rgl package (interactive 3D plots)
For fully interactive 3D surfaces that you can rotate, zoom, and pan:
library(rgl) # Create interactive surface surface3d( interpolated_grid$x, interpolated_grid$y, interpolated_grid$z, col = heat.colors(100) # Customizable color gradient ) # Export as an interactive HTML widget (optional) rglwidget()
内容的提问来源于stack exchange,提问作者Schnabelleboom

