R语言scatterplot3d绘制3D散点图如何添加椭圆/多边形与图例
解决scatterplot3d 3D K-Means聚类图加图例和聚类边界的方案
首先修正原代码的小疏漏:你在给df添加cluster列后,用df[,-1]作为3D绘图输入,会把新增的cluster列也作为数值维度代入绘图,需要明确指定3个主成分列作为绘图输入。
以下是完整可运行的修改后代码,同时支持添加中文聚类图例和聚类投影边界:
library(scatterplot3d) # 你提供的示例数据集 df = structure(list(Station = c(91L, 92L, 94L, 95L, 96L, 97L, 98L, 99L, 103L, 105L, 106L, 107L, 112L, 113L, 114L, 115L, 116L, 117L, 119L, 122L, 123L), PC1 = c(-1.12015813, -0.162603353, -0.691170969, 1.290790838, -1.544758302, -0.027602401, -0.614168423, -0.495333696, 1.279949324, -0.63809094, -0.122668147, 0.744142235, -0.778789917, -2.633418969, 0.758488847, -1.066042887, -0.721002477, 1.079359567, -0.175695907, 5.318351482, 0.320422224), PC2 = c(0.415530088, 0.666545002, 0.695404632, -0.554688073, 0.222592134, 0.697855329, 1.242555625, 0.64505761, 0.702722431, 0.86363373, 0.827648227, 1.204083925, -4.232859175, -1.636251717, -0.685291914, 1.16637059, -0.122979187, -1.485372609, 0.079916797, -0.402557579, -0.309915867 ), PC3 = c(0.698238358, -0.071855245, -0.563762392, -0.382756976, 0.224635711, -0.786947583, -1.983627389, -0.032803567, -0.465769148, -0.076804882, -1.775067301, -0.203906481, -0.419354014, -0.121035409, -1.171532233, 3.578306494, 0.91365978, 0.951076125, 0.516367241, 0.770666924, 0.402271986)), row.names = c(NA, -21L), class = "data.frame") # 聚类计算 避免重复运行kmeans set.seed(137) km = kmeans(df[,c("PC1","PC2","PC3")], 4, nstart=25) df$cluster = factor(km$cluster) # 绘图参数设置 cluster_col = rainbow(4) cluster_shape = c(15, 17, 18, 19) point_col = cluster_col[as.numeric(df$cluster)] point_shape = cluster_shape[as.numeric(df$cluster)] # 绘制3D散点图 zz <- scatterplot3d(df[,c("PC1","PC2","PC3")], pch = point_shape, grid = F, color = point_col) # 添加每个聚类的凸包边界(当前投影视角下) for (i in 1:4) { # 提取当前聚类的所有点 sub_df = df[df$cluster == i, c("PC1","PC2","PC3")] # 转成投影后的2D坐标 sub_coords = zz$xyz.convert(sub_df) # 计算凸包顶点 hull_idx = chull(sub_coords$x, sub_coords$y) # 绘制半透明多边形边界 alpha调整透明度 polygon(sub_coords$x[hull_idx], sub_coords$y[hull_idx], col = adjustcolor(cluster_col[i], alpha.f = 0.15), border = cluster_col[i], lwd = 1.2) } # 添加站点标签 zz.coords <- zz$xyz.convert(df[,c("PC1","PC2","PC3")]) text(zz.coords$x, zz.coords$y, labels = df$Station, cex = .5, pos = 4) # 添加聚类图例 legend("topright", legend = paste0("聚类", 1:4), pch = cluster_shape, col = cluster_col, bty = "n", # 去掉图例边框 cex = 0.9)
核心调整说明
- 修正了原代码重复运行kmeans、错误将cluster列作为绘图维度的问题
- 聚类边界采用当前3D投影下的凸多边形实现:scatterplot3d本质是将3D坐标投影到2D平面渲染,无法生成真正的3D椭球边界,凸多边形边界可以清晰区分当前视角下的聚类范围,可通过
adjustcolor的alpha.f参数调整填充透明度 - 图例直接调用R基础绘图的
legend函数实现,可调整legend第一个参数修改图例位置,可选值包括"bottomleft"、"topright"、"right"等,也可以传入坐标向量自定义位置
内容的提问来源于stack exchange,提问作者Kazi
相关产品推荐
相关产品推荐

