我宁愿不使用quiver,因为它不为它的输入参数X、Y、Z正确处理float128 dtypes 、U、V 和 W。事实上,它默默地将这些输入转换为 float,在我们的系统中通常是 float64。结果,float128 输入导致溢出!
相反,我想在this wonderful answer 中使用CT Zhu 的简短类Arrow3D。它与 float128 坐标完美配合,并提供各种 箭头样式。
在这个帮助下,我开发了这个函数来在图形中心绘制 X、Y 和 Z 轴:
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')
让我们使用它们:
ax = plt.figure(figsize=(7, 7)).add_subplot(projection='3d')
draw_vector(ax, np.array([2, 3, 5]))
draw_xyz_axes_at_center(ax)
ax.set_xlabel('x axis')
ax.set_ylabel('y axis')
ax.set_zlabel('z axis')
plt.show()
输出:
顺便用过Python 3,没在Python 2上测试过。