使用Plotly绘制多层3D曲面图异常:仅显示空白图且Z轴受限
解决Plotly 3D曲面图空白及Z轴异常问题
核心问题
- Plotly的
surface类型要求Z数据为矩阵格式(对应X、Y的网格点),而非一维向量,你传入的一维RMSE向量无法生成曲面。 - 数据中RMSE数值跨度极大(26k~19M),默认缩放后小数值被压缩,导致Z轴显示异常。
- 未按
gamma分组生成独立曲面。
修正代码及步骤
1. 加载依赖包
先安装并加载所需工具包:
install.packages(c("dplyr", "tidyr", "plotly")) library(dplyr) library(tidyr) library(plotly)
2. 数据格式转换
将长格式数据按gamma分组,转换为曲面图要求的网格矩阵:
# 按gamma分组,将数据转成宽表(行=alpha,列=lambda,值=RMSE) surface_data <- data %>% group_by(gamma) %>% pivot_wider(names_from = lambda, values_from = RMSE, id_cols = alpha) %>% ungroup() # 提取gamma=2.1的X/Y/Z数据 gamma_2.1 <- surface_data %>% filter(gamma == 2.1) x_2.1 <- gamma_2.1$alpha %>% as.numeric() y_2.1 <- colnames(gamma_2.1)[-c(1,2)] %>% as.numeric() z_2.1 <- gamma_2.1 %>% select(-gamma, -alpha) %>% as.matrix() # 提取gamma=2.0的X/Y/Z数据 gamma_2.0 <- surface_data %>% filter(gamma == 2.0) x_2.0 <- gamma_2.0$alpha %>% as.numeric() y_2.0 <- colnames(gamma_2.0)[-c(1,2)] %>% as.numeric() z_2.0 <- gamma_2.0 %>% select(-gamma, -alpha) %>% as.matrix()
3. 绘制多曲面3D图
添加两个gamma对应的曲面,用对数刻度适配RMSE的大数值跨度:
fig <- plot_ly() %>% # 添加gamma=2.1的曲面 add_surface( x = x_2.1, y = y_2.1, z = z_2.1, name = "gamma=2.1", colorscale = "Viridis" ) %>% # 添加gamma=2.0的曲面 add_surface( x = x_2.0, y = y_2.0, z = z_2.0, name = "gamma=2.0", colorscale = "Plasma" ) %>% # 设置轴标签与Z轴对数刻度 layout( scene = list( xaxis = list(title = "alpha"), yaxis = list(title = "lambda"), zaxis = list(title = "RMSE", type = "log") ), title = "不同gamma下的RMSE 3D曲面图" ) fig
可选:补全缺失网格(解决曲面断层)
若数据存在网格缺失值,可使用akima包插值补全密集网格:
install.packages("akima") library(akima) # 对gamma=2.1的数据插值生成50x50密集网格 interp_2.1 <- interp( x = data$alpha[data$gamma == 2.1], y = data$lambda[data$gamma == 2.1], z = data$RMSE[data$gamma == 2.1], nx = 50, ny = 50 ) # 同理处理gamma=2.0的数据 interp_2.0 <- interp( x = data$alpha[data$gamma == 2.0], y = data$lambda[data$gamma == 2.0], z = data$RMSE[data$gamma == 2.0], nx = 50, ny = 50 ) # 用插值后的数据绘图 fig <- plot_ly() %>% add_surface(x = interp_2.1$x, y = interp_2.1$y, z = interp_2.1$z, name = "gamma=2.1") %>% add_surface(x = interp_2.0$x, y = interp_2.0$y, z = interp_2.0$z, name = "gamma=2.0") %>% layout(scene = list(xaxis=list(title="alpha"), yaxis=list(title="lambda"), zaxis=list(title="RMSE", type="log")))
内容的提问来源于stack exchange,提问作者Joe94
相关产品推荐
相关产品推荐

