如何在R的rgl窗口中创建3D极坐标树状图
实现3D极坐标树状图(rgl环境)
1. 核心思路:坐标转换
普通树状图的笛卡尔坐标(x, y, z)转3D极坐标的逻辑:
- 把树状图的水平轴(原x轴)映射为极角θ(绕z轴旋转的弧度值)
- 垂直轴(原y轴)映射为径向距离r
- 高度轴z保持不变,作为树状图的层级高度
转换公式:new_x = r * cos(θ)new_y = r * sin(θ)new_z = z
2. 完整可复现代码
步骤1:准备数据并生成普通树状图结构
library(rgl) library(ape) library(dendextend) library(scales) # 生成示例聚类数据 set.seed(123) data <- matrix(rnorm(50), ncol = 5) hc <- hclust(dist(data)) dend <- as.dendrogram(hc) # 提取普通笛卡尔坐标的树状图节点信息 dend_coords <- get_nodes_xy(dend) # 补充z轴坐标(用节点层级高度,这里简化为深度的倒数映射) dend_coords <- cbind(dend_coords, z = rev(seq(0, 1, length.out = nrow(dend_coords))))
步骤2:笛卡尔坐标转3D极坐标
# 设置极坐标范围 theta_range <- c(0, 2*pi) # 0到360度(弧度) r_range <- c(0, max(dend_coords[,2])) # 径向范围匹配原y轴最大值 # 映射原坐标到极坐标参数 theta <- rescale(dend_coords[,1], to = theta_range) r <- rescale(dend_coords[,2], to = r_range) # 计算最终3D极坐标 polar_coords <- data.frame( x = r * cos(theta), y = r * sin(theta), z = dend_coords[,3] )
步骤3:在rgl窗口绘制3D极坐标树状图
# 初始化rgl窗口 open3d(windowRect = c(100, 100, 800, 800)) # 遍历绘制树状图连线 edges <- get_edges_xy(dend) for(i in 1:nrow(edges)){ # 匹配边的起始/结束节点索引 start_idx <- match(edges[i,1], dend_coords[,1]) end_idx <- match(edges[i,3], dend_coords[,1]) start_p <- polar_coords[start_idx,] end_p <- polar_coords[end_idx,] # 绘制单条边 lines3d( x = c(start_p$x, end_p$x), y = c(start_p$y, end_p$y), z = c(start_p$z, end_p$z), col = "darkgray", lwd = 2 ) } # 绘制节点标记 points3d(polar_coords$x, polar_coords$y, polar_coords$z, col = "red", size = 3)
步骤4:添加可平移的3D网格
# 创建平面网格作为示例 grid <- mesh3d( x = seq(-max(r), max(r), length.out = 10), y = seq(-max(r), max(r), length.out = 10), z = rep(0, 100) ) # 使用translate3d平移网格到指定位置(比如z=0.5处) translated_grid <- translate3d(grid, x=0, y=0, z=0.5) shade3d(translated_grid, col = "lightblue", alpha = 0.3)
3. 关键细节说明
- 用
scales::rescale()确保坐标映射后符合极坐标的范围要求,避免图形溢出 - 树状图的边/节点提取依赖
dendextend包,需提前安装 - 任意
mesh3d格式的3D模型都可通过translate3d平移,不会影响树状图的坐标系统
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

