嗨!
我正在尝试使用matplotlib quiver
函数以3D方式绘制矢量。为了使它们可视化,我还想绘制以原点为中心的正交轴。
理想情况下,我想移动所谓的棘刺,但根据this SO post,对此没有简单的解决方法。
我最终沿x,y和z将轴绘制为三个向量(请参见下面的代码),但我忍不住认为这是一个糟糕的解决方案……任何输入将不胜感激。>
代码如下:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
f = plt.figure(1)
ax=plt.gca()
soa = np.array([[0, 0, 0, 1, 0, 0],[0, 0, 0, 0, 1, 0],[0, 0, 0, 0, 0, 1]])
X, Y, Z, U, V, W = zip(*soa)
soa2 = np.array([[0,0,0,np.sqrt(2)/2,np.sqrt(2)/2,np.sqrt(2)/2]])
I, J, K, F, G, H = zip(*soa2)
fig = plt.figure()
ax=Axes3D(fig)
ax.quiver(X, Y, Z, U, V, W, color='black')
ax.quiver(I, J, K, F, G, H)
ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
f.show()
这是此脚本返回的图像:
答案 0 :(得分:1)
我宁愿不使用 quiver
,因为它不能正确处理 float128 dtypes 的输入参数 X
、{{1 }}、Y
、Z
、U
和 V
。事实上,它会默默地将这些输入转换为 float,在我们的系统中通常是 float64。结果,float128 输入导致溢出!
相反,我想在 CT Zhu 中使用 this wonderful answer 的简短课程 W
。它与 float128 坐标完美配合,并提供各种箭头样式。
在此帮助下,我开发了此函数以在图形中心绘制 X、Y 和 Z 轴:
Arrow3D
绘制矢量:
import numpy as np
import matplotlib.pyplot as plt
from Arrow3D import Arrow3D
def draw_xyz_axes_at_center(mpl_ax):
# Compute max_lim based on plotted data
x_lim = abs(max(mpl_ax.get_xlim(), key=abs))
y_lim = abs(max(mpl_ax.get_ylim(), key=abs))
z_lim = abs(max(mpl_ax.get_zlim(), key=abs))
max_lim = max(x_lim, y_lim, z_lim)
# Position xyz axes at the center
mpl_ax.set_xlim(-max_lim, max_lim)
mpl_ax.set_ylim(-max_lim, max_lim)
mpl_ax.set_zlim(-max_lim, max_lim)
# Draw xyz axes
axes = ['x', 'y', 'z']
for i, axis in enumerate(axes):
start_end_pts = np.zeros((3, 2))
start_end_pts[i] = [-max_lim, max_lim]
# Draw axis
xs, ys, zs = start_end_pts[0], start_end_pts[1], start_end_pts[2]
a = Arrow3D(xs, ys, zs,
mutation_scale=20, arrowstyle='-|>', color='black')
mpl_ax.add_artist(a)
# Add label
end_pt_with_padding = start_end_pts[:, 1] * 1.1
mpl_ax.text(*end_pt_with_padding,
axis,
horizontalalignment='center',
verticalalignment='center',
color='black')
让我们使用它们:
def draw_vector(mpl_ax, v):
xs = [0, v[0]]
ys = [0, v[1]]
zs = [0, v[2]]
a = Arrow3D(xs, ys, zs,
mutation_scale=20, arrowstyle='->', color='#1f77b4')
mpl_ax.add_artist(a)
# Axes limits automatically include the coordinates of all plotted data
# but not Arrow3D artists. That's actually why this point is plotted.
mpl_ax.plot(*v, '.', color='#1f77b4')
顺便说一下,我使用了 Python 3 并且没有在 Python 2 上测试它。