matplotlib中的3D颤动图的“ set_UVC”等效项

刘易斯

要更新常规2D颤动图,可以使用.set_UVC()直接设置xy数据。

相当于颤抖的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并且使用空列表调用LineCollectionset_segments()方法。Line3DCollection然后在重载draw()方法中照顾自己的细分列表注意两点:

  1. 即使您遵循matplotlib示例并用于numpy.meshgrids定义颤抖坐标,坐标内_segments3d也存储在shape数组中(N,2,3),其中N是点的数量,其内容基本上是[[[x0,y0,z0],[u0,v0,w0]],[[x1,y1,z1],[u1,v1,w1]],...],因此您可能必须操纵数据以适合格式。
  2. 显然,您不能将新值直接分配给_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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章