You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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参数仅支持单一数值输入,无法直接设置三轴间的比例关系。

图1:目标正方形3D散点图
图2:当前得到的散点图

原代码如下:

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无法直接设置多轴纵横比,可通过数据缩放+参数调整的方式实现目标:

  1. 根据目标比例缩放y轴(PC2)和z轴(PC3)数据:因为x/y=2,所以将PC2乘以2,让视觉上x轴长度是y轴的2倍;同理PC3乘以2匹配x/z=2的比例。
  2. 保持绘图窗口为正方形,设置asp=1确保缩放后的比例正确呈现。
  3. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 00:23:21