我想按照我们在学校绘制情节的风格来绘制情节。这是一个例子:
总结:
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()
我怎样才能使它看起来像立方体?
您正在寻找的投影是斜骑士投影的修改版本。在典型的骑士投影中,xy 平面平行于屏幕,z 轴是对角线,正方向指向屏幕外。该投影的变换矩阵可以在这个维基百科页面上找到,更多信息可以在这些讲义中找到。
听起来您希望 x 轴对角指向屏幕,yz 平面平行于屏幕。只要更改
transform
矩阵,您的代码就可以实现。当 alpha
为对角线角度时,正确的变换矩阵为:
左上角的 -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()