matplotlib 带有对角轴的正交样式的3D打印

yv5phkfx  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(142)

我想用我们在学校里习惯的方式来绘制一个情节。下面是一个例子:

总结:

  • 3D图
  • y-z平面平行于屏幕(水平y,垂直z)
  • x轴是对角线

Y-Z轴与屏幕平行(水平y,垂直z。通常X轴现在指向屏幕。但我想改变它,使其斜向下(就像人们有时会在一张纸上画它)。不幸的是,我不知道这种投影是如何命名的(倾斜图像),但我很确定它是正交的,我需要某种额外的投影。
我已经尝试过使用轴的自定义投影,如下所示:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', proj_type='ortho')

# Some sample data
x, y, z = np.random.rand(3, 100)
ax.scatter(x, y, z)

# Apply the transformation
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), transform)

# Set labels and view
ax.view_init(elev=0, azim=0)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

# Manual transformation matrix
c = np.cos(np.deg2rad(30))
s = np.sin(np.deg2rad(30))
transform = np.array([
[1,  0,  0, 0],
[0,  c, -s, 0],
[0,  s,  c, 0],
[0,  0,  0, 1]
])

# Apply the transformation
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), transform)

plt.show()

这是我的结果(到目前为止不是很令人印象深刻:)

我怎样才能把它修复成立方体的样子?

rkue9o1l

rkue9o1l1#

输出示例

解决方案

您要查找的投影是斜
这听起来像是你希望x轴对角指向屏幕,yz平面平行于屏幕。只要你改变transform矩阵,你的代码就可以实现。当alpha是对角线的Angular 时,正确的变换矩阵是:

左上角的-1翻转了对角线x轴。在cos()sin()项上使用负号将向您展示如何操作图形。

代码

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', proj_type='ortho')

# Some sample data
x = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1]
y = [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1]
z = [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1]

# display data
ax.scatter(x, y, z)
ax.plot(x, y, z)

# set angle of the diagonal (63.4 = arctan(2))
alpha = 63.4 

# Set labels and view and lims
ax.view_init(elev=alpha, azim=(90-alpha))
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

ax.set_xlim(-0.5,1.5)
ax.set_ylim(-0.5,1.5)
ax.set_zlim(-0.5,1.5)

# Manual transformation matrix
c = np.cos(np.deg2rad(alpha))
s = np.sin(np.deg2rad(alpha))
transform = np.array([
[-1, 0,  0, 0],
[0,  1,  0, 0],
[-c, s,  1, 0],
[0,  0,  0, 1]
])

# Apply the transformation
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), transform)
ax.set_aspect('equal')
plt.show()

相关问题