2016-07-05 90 views
1

我想用箭頭連接3D散點圖中的兩點。我試着用quiver用下面的代碼如何在三維散點圖中用箭頭連接兩個點?

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

fig = plt.figure(figsize=(20, 15)) 
ax = fig.add_subplot(111, projection='3d') 

xs1 = [40,50,34] 
ys1 = [30,30,30] 
zs1 = [98,46,63] 

ax.scatter(xs1, ys1, zs1, s=100, c='g', marker='o') 

ax.text(xs1[0], ys1[0], zs1[0], '(%s,%s,%s)' % (str(xs1[0]), str(ys1[0]), str(zs1[0])), size=30, zorder=5, color='k') 
ax.text(xs1[1], ys1[1], zs1[1], '(%s,%s,%s)' % (str(xs1[1]), str(ys1[1]), str(zs1[1])), size=30, zorder=5, color='k') 
ax.text(xs1[2], ys1[2], zs1[2], '(%s,%s,%s)' % (str(xs1[2]), str(ys1[2]), str(zs1[2])), size=30, zorder=5, color='k') 


ax.quiver(xs1[0], ys1[0], zs1[0], (xs1[0]-xs1[2]), (ys1[0]-ys1[2]), (zs1[0]-zs1[2]), length=30) 


ax.set_xlabel('X', fontsize=30, labelpad=20) 
ax.set_ylabel('Y', fontsize=30, labelpad=20) 
ax.set_zlabel('Z', fontsize=30, labelpad=20) 

plt.show() 
fig.canvas.draw() 
fig.canvas.flush_events() 

它看起來像這樣

enter image description here

我能夠在兩個點連接的唯一途徑是通過增加quiverlength,但如果length超過了要求,它只是通過另一點。

有沒有更好的方式來連接它們而不調整長度?

回答

1

構建基於FancyArrow自己的階級在三維尺寸繪製:

import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
from mpl_toolkits.mplot3d import proj3d 
from matplotlib.patches import FancyArrowPatch 

class Arrow3D(FancyArrowPatch): 
    def __init__(self, xs, ys, zs, *args, **kwargs): 
     FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs) 
     self._verts3d = xs, ys, zs 

    def draw(self, renderer): 
     xs3d, ys3d, zs3d = self._verts3d 
     xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M) 
     self.set_positions((xs[0],ys[0]),(xs[1],ys[1])) 
     FancyArrowPatch.draw(self, renderer) 

fig = plt.figure(figsize=(20, 15)) 
ax = fig.add_subplot(111, projection='3d') 

xs1 = [40,50,34] 
ys1 = [30,30,30] 
zs1 = [98,46,63] 

ax.scatter(xs1, ys1, zs1, s=100, c='g', marker='o') 

ax.text(xs1[0], ys1[0], zs1[0], '(%s,%s,%s)' % (str(xs1[0]), str(ys1[0]), str(zs1[0])), size=30, zorder=5, color='k') 
ax.text(xs1[1], ys1[1], zs1[1], '(%s,%s,%s)' % (str(xs1[1]), str(ys1[1]), str(zs1[1])), size=30, zorder=5, color='k') 
ax.text(xs1[2], ys1[2], zs1[2], '(%s,%s,%s)' % (str(xs1[2]), str(ys1[2]), str(zs1[2])), size=30, zorder=5, color='k') 

arw = Arrow3D([xs1[0],xs1[2]],[ys1[0],ys1[2]],[zs1[0],zs1[2]], arrowstyle="->", color="purple", lw = 3, mutation_scale=25) 
ax.add_artist(arw) 

ax.set_xlabel('X', fontsize=30, labelpad=20) 
ax.set_ylabel('Y', fontsize=30, labelpad=20) 
ax.set_zlabel('Z', fontsize=30, labelpad=20) 

plt.show() 

enter image description here

上面的代碼是在此基礎上answer閱讀更多細節。