要更新常规2D颤动图,可以使用.set_UVC()
直接设置x
和y
数据。
相当于颤抖的3D是Axes3D.quiver()
,但似乎没有等同于.set_UVC()
。数据如何更新?在segments
似乎确实包含来自箭的箭袋中的数据,但是我没有看到输入数据和段相关因素如何。
我可以删除颤动图,然后重新绘制一个新图,但这效率低下并且会影响性能,我想知道是否有一种直接设置数据的方法。
如果看一下Line3DCollection
代码,您会发现LineCollection
该类中没有太多的方法被重载。对您来说重要的是set_segments()
,它看起来像这样:
def set_segments(self, segments):
'''
Set 3D segments
'''
self._segments3d = np.asanyarray(segments)
LineCollection.set_segments(self, [])
因此,在set_segments()
调用时,实际上将存储段,self._segments3d
并且使用空列表调用LineCollection
的set_segments()
方法。Line3DCollection
然后在重载draw()
方法中照顾自己的细分列表。注意两点:
numpy.meshgrids
定义颤抖坐标,坐标内_segments3d
也存储在shape数组中(N,2,3)
,其中N是点的数量,其内容基本上是[[[x0,y0,z0],[u0,v0,w0]],[[x1,y1,z1],[u1,v1,w1]],...]
,因此您可能必须操纵数据以适合格式。_segments3d
。至少对我来说,这导致图形无法正确更新-您必须仔细检查set_segments()
。但是,例如,如果您只想更改某些坐标,则可以通过读出来访问先前的值_segments3d
。这里还有一些我用来测试我刚才解释的所有事情的任意示例:
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib.animation import FuncAnimation
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
num_frames = 50
theta = np.linspace(0,2*np.pi, 10, endpoint=False)
r = np.arange(1,2.1)
z = np.arange(-2,2.1,1)
def compute_segs(i):
offset = 2*i*np.pi/num_frames
theta2,r2, z2 = np.meshgrid(theta+offset,r,z)
x = r2*np.cos(theta2)
y = r2*np.sin(theta2)
u = x+0.2*np.cos(4*theta2)
v = y
w = z2+0.2*np.sign(z2)*np.sin(4*theta2)
return x,y,z2,u,v,w
segs = compute_segs(0)
cols = ['b' for x in segs[0].ravel()]
cols[0] = 'r'
quivers = ax.quiver(*segs, length=0.1, colors = cols, normalize=True)
ax.set_xlim([-3,3])
ax.set_ylim([-3,3])
ax.set_zlim([-3,3])
def animate(i):
segs = np.array(compute_segs(i)).reshape(6,-1)
new_segs = [[[x,y,z],[u,v,w]] for x,y,z,u,v,w in zip(*segs.tolist())]
quivers.set_segments(new_segs)
return quivers
ani = FuncAnimation(fig, animate, frames = num_frames, interval = 30, blit=False)
ani.save('update_3d_quiver.gif', writer='imagemagick')
plt.show()
...结果看起来像这样:
希望这可以帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句