如何为scatterplot3d设置指定三维纵横比(x/y=2、x/z=2、y/z=1)?
实现指定纵横比的正方形3D散点图
问题描述
想要创建类似图1的正方形3D散点图,尝试了以下方法但未达到预期:
- 设置
png(width=500, height=500)创建正方形绘图窗口 - 使用
par(pty="s")强制正方形绘图区域 - 调整
scatterplot3d的angle和asp参数
最终得到图2样式,无法实现目标纵横比:x/y=2、x/z=2、y/z=1,核心问题是scatterplot3d的asp参数仅支持单一数值输入,无法直接设置三轴间的比例关系。


原代码如下:
library(scatterplot3d) set.seed(123) pc1 <- rnorm(100) pc2 <- rnorm(100) pc3 <- rnorm(100) groups <- sample(c('Bread', 'Durum', 'Spelt'), 100, replace = TRUE) # Create a data frame with the PC values and group labels data <- data.frame(PC1 = pc1, PC2 = pc2, PC3 = pc3, Group = groups) # Define colors for each group colors <- c('Bread' = 'pink', 'Durum' = 'lightgreen', 'Spelt' = 'skyblue') # Set up a square plotting window png("test.png", width = 500, height = 500) par(c(0.5, 0.5, 0.5, 0.1), pty = "s") # Create a 3D scatter plot with square size points scatterplot3d(data$PC1, data$PC2, data$PC3, color = colors[data$Group], pch = 19, type = "p", grid = TRUE, xlab = "PC1 (11.63%)", ylab = "PC2 (7.03%)", zlab = "PC3 (4.09%)", mar=c(5,3,4,3)+0.1, angle=45, asp = 0.5) # Manually add group annotations without outside box legend("topright", legend = unique(data$Group), col = unique(colors), pch = 19, bty = "n", inset = c(0.1,0), xpd=TRUE, ncol=1) dev.off()
解决方案
由于scatterplot3d无法直接设置多轴纵横比,可通过数据缩放+参数调整的方式实现目标:
- 根据目标比例缩放y轴(PC2)和z轴(PC3)数据:因为x/y=2,所以将PC2乘以2,让视觉上x轴长度是y轴的2倍;同理PC3乘以2匹配x/z=2的比例。
- 保持绘图窗口为正方形,设置
asp=1确保缩放后的比例正确呈现。 - 调整
angle参数让视图更接近目标样式。
修改后的代码:
library(scatterplot3d) set.seed(123) pc1 <- rnorm(100) pc2 <- rnorm(100) pc3 <- rnorm(100) groups <- sample(c('Bread', 'Durum', 'Spelt'), 100, replace = TRUE) # 按目标比例缩放数据:PC2和PC3乘以2,匹配x/y=2、x/z=2的比例 scaled_pc2 <- pc2 * 2 scaled_pc3 <- pc3 * 2 data <- data.frame(PC1 = pc1, PC2 = scaled_pc2, PC3 = scaled_pc3, Group = groups) colors <- c('Bread' = 'pink', 'Durum' = 'lightgreen', 'Spelt' = 'skyblue') png("test.png", width = 500, height = 500) # 调整边距避免图例截断,保持正方形绘图区域 par(mar = c(4, 4, 3, 5) + 0.1, pty = "s") scatterplot3d(data$PC1, data$PC2, data$PC3, color = colors[data$Group], pch = 19, type = "p", grid = TRUE, xlab = "PC1 (11.63%)", ylab = "PC2 (7.03%)", zlab = "PC3 (4.09%)", angle = 60, # 调整角度更接近目标视图 asp = 1) # 结合缩放数据实现目标比例 # 调整图例位置避免遮挡 legend("topright", legend = unique(data$Group), col = unique(colors), pch = 19, bty = "n", inset = c(0.05, 0), xpd = TRUE, ncol = 1) dev.off()
关键修改说明
- 数据缩放:将PC2和PC3乘以2,等价于在绘图时将y轴和z轴的单位长度缩小为x轴的1/2,从而实现x/y=2、x/z=2的比例关系。
- 参数调整:设置
asp=1确保缩放后的数据在正方形窗口中正确呈现,调整angle=60让3D视图更接近图1的视角。 - 边距优化:调整
par(mar)参数避免图例和坐标轴标签被截断,提升绘图美观度。
内容的提问来源于stack exchange,提问作者zeno Zeng
相关产品推荐
相关产品推荐

