沿三维曲线移动的箭头
我想知道如何在3D图中沿着一条路径放置一个箭头。
这里有一个例子。
import matplotlib.pyplot as plt
import numpy as np
z = np.linspace(0,10,100)
x = np.sin(z)
y = np.cos(z)
ax = plt.figure().add_subplot(projection='3d')
ax.plot(x, y, z, label='parametric curve')
我尝试使用 FancyArrowPatch
来实现这个功能,具体可以查看这个链接:https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.FancyArrowPatch.html。但是,path
参数只接受 (x,y) 的输入。请问如何将这个转换到3D呢?
1 个回答
2
这里是基于@CT Zhu(来自 在3D图中给向量加箭头)和@Ruli的内容,后者解决了新版 matplotlib
中的 attribute error
问题。我们可以把 Arrow3D
的逻辑应用到一个包含 x
、y
和 z
最后两个值的 list
的 tuple
上,这样箭头的头部就能沿着路径或线条的曲线移动:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d
class Arrow3D(FancyArrowPatch):
def __init__(self, xs, ys, zs, *args, **kwargs):
super().__init__((0, 0), (0, 0), *args, **kwargs)
self._verts3d = xs, ys, zs
def do_3d_projection(self, renderer=None):
xs3d, ys3d, zs3d = self._verts3d
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)
self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
return np.min(zs)
z = np.linspace(0, 10, 100)
x = np.sin(z)
y = np.cos(z)
ax = plt.figure().add_subplot(projection='3d')
ax.plot(x, y, z, label='parametric curve', color='r')
arrow_prop_dict = dict(mutation_scale=20, arrowstyle='-|>', color='r', shrinkA=0, shrinkB=0)
arrow_head = (x[-2:], y[-2:], z[-2:])
a = Arrow3D(*arrow_head, **arrow_prop_dict)
ax.add_artist(a)
plt.show()
输出结果:
其实应该感谢@CT Zhu(和@Ruli),他们基本上完成了所有的工作。