如何在R plotly的add_markers()中按分类变量设置标记样式并添加3D面板轮廓线?
解决方案
1. 修复分类变量的标记颜色与符号不生效问题
plotly中针对分类变量的颜色和符号映射,需使用color_discrete_map和symbol_map参数(而非colors和symbols)绑定因子水平与对应样式,确保映射关系正确生效。
2. 添加3D面板的轮廓线
通过添加多条3D线条(scatter3d类型,mode='lines'),绘制正卦限立方体的边框,实现附图中的“壁”轮廓效果。
修改后的完整代码
# Packages library(plotly) library(misc3d) # Fake data norm_vec <- function(x) sqrt(sum(x ^ 2)) X3d_norm <- data.frame(T3 = runif(100), T6 = runif(100), P4 = runif(100)) norms <- apply(X3d_norm, 1, norm_vec) X3d_norm <- X3d_norm / norms X3d_norm$cluster <- factor(sample(1:2, 100, replace = T), ordered = T) # Getting octant data f <- function(x, y, z){x ^ 2 + y ^ 2 + z ^ 2} R <- 1 x <- y <- z <- seq(0, R, length.out = 100) g <- expand.grid(x = x, y = y, z = z) voxel <- array(with(g, f(x, y, z)),dim = c(100, 100, 100)) cont <- computeContour3d(voxel, level = R ^ 2, x = x, y = y, z = z) idx <- matrix(0:(nrow(cont) - 1), ncol = 3,byrow = TRUE) # Colors and symbols pal <- c("#E69F00", "#009E73") names(pal) <- c("1", "2") # 确保与因子水平字符串匹配 symb <- c("circle", "square") names(symb) <- c("1", "2") # 生成正卦限立方体轮廓线的坐标 cube_edges <- list( # x=0平面的四条边 list(x=rep(0,2), y=c(0,1), z=c(0,0)), list(x=rep(0,2), y=c(0,1), z=c(1,1)), list(x=rep(0,2), y=c(0,0), z=c(0,1)), list(x=rep(0,2), y=c(1,1), z=c(0,1)), # y=0平面的四条边 list(x=c(0,1), y=rep(0,2), z=c(0,0)), list(x=c(0,1), y=rep(0,2), z=c(1,1)), list(x=c(0,0), y=rep(0,2), z=c(0,1)), list(x=c(1,1), y=rep(0,2), z=c(0,1)), # z=0平面的四条边 list(x=c(0,1), y=c(0,0), z=rep(0,2)), list(x=c(0,1), y=c(1,1), z=rep(0,2)), list(x=c(0,0), y=c(0,1), z=rep(0,2)), list(x=c(1,1), y=c(0,1), z=rep(0,2)) ) # Plot p <- plot_ly() %>% add_mesh( x = cont[, 1], y = cont[, 2], z = cont[, 3], i = idx[, 1], j = idx[, 2], k = idx[, 3], opacity = 0.15 ) %>% add_markers( data = X3d_norm, x = ~T3, y = ~P4, z = ~T6, color = ~cluster, color_discrete_map = pal, # 替换为分类颜色映射参数 symbol = ~cluster, symbol_map = symb, # 替换为分类符号映射参数 marker = list(size = 6) # 可选:调整标记大小 ) %>% layout( legend = list(title = list(text = 'Clusters')), scene = list( xaxis = list( title = "T3", nticks = 4, tickvals = c(0.20, 0.40, 0.60, 0.80), tickfont = list(size = 16), titlefont = list(size = 24)), yaxis = list( title = "P4", nticks = 4, tickvals = c(0.20, 0.40, 0.60, 0.80), tickfont = list(size = 16), titlefont = list(size = 24)), zaxis = list( title = "T6", nticks = 4, tickvals = c(0.20, 0.40, 0.60, 0.80), tickfont = list(size = 16), titlefont = list(size = 24)) ) ) # 添加所有立方体轮廓线 for (edge in cube_edges) { p <- p %>% add_trace( x = edge$x, y = edge$y, z = edge$z, type = 'scatter3d', mode = 'lines', line = list(color = 'black', width = 2), showlegend = FALSE ) } p
关键修改说明
- 颜色映射:将
colors替换为color_discrete_map,并确保颜色向量的名称与cluster因子的水平字符串完全匹配(因子水平默认是字符串类型,所以用"1"而非1)。 - 符号映射:将
symbols替换为symbol_map,同样确保符号向量的名称与因子水平对应。 - 轮廓线:通过循环添加12条3D线条,绘制正卦限立方体的所有边框,线条样式设置为黑色实线,不显示在图例中。
内容的提问来源于stack exchange,提问作者GuerreroAguera
相关产品推荐
相关产品推荐

