“set_UVC”等效于matplotlib中的3D箭袋图

时间:2018-02-21 17:08:00

标签: python matplotlib

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

与箭相当的3D是Axes3D.quiver(),但这似乎与.set_UVC()不等。如何更新数据? segments似乎确实包含来自箭头箭头的数据,但是我看不到输入数据和段如何相关。

我可以删除箭头图然后重新绘制一个新图但效率低且会影响性​​能,我想知道是否有办法直接设置数据。

2 个答案:

答案 0 :(得分:3)

如果查看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的{​​{1}}方法会调用空列表。 set_segments()然后在重载的Line3DCollection方法中处理自己的段列表。有两点需要注意:

  1. 即使您按照matplotlib示例并使用draw()来定义您的箭头坐标,在numpy.meshgrids内,坐标也会存储在形状_segments3d的数组中,其中N是点及其内容基本上是(N,2,3),因此您可能必须操纵您的数据以适应该格式。
  2. 显然您无法将新值直接分配给[[[x0,y0,z0],[u0,v0,w0]],[[x1,y1,z1],[u1,v1,w1]],...]。至少对我来说,这个数字不能正确更新 - 你必须通过_segments3d。但是,如果您只是想改变某些坐标,则可以通过读出set_segments() 访问以前的值。
  3. 这里还有一些任意的例子,我为测试我刚刚解释过的所有内容而制作了这些例子:

    _segments3d

    ......结果如下:

    result of the above code

    希望这有帮助。

答案 1 :(得分:2)

详细说明我已接受的ThomasKühn的答案,如果您有网格点和要转换为段的箭数据,您可以使用以下函数。

def quiver_data_to_segments(X, Y, Z, u, v, w, length=1):
    segments = (X, Y, Z, X+v*length, Y+u*length, Z+w*length)
    segments = np.array(segments).reshape(6,-1)
    return [[[x, y, z], [u, v, w]] for x, y, z, u, v, w in zip(*list(segments))]

然后,您可以使用输出更新绘图的片段,这种方式还允许您使用长度来指定箭头的标准化长度,通常最好将此值设置为平均值或最大值的倍数输入数据(np.sqrt(vv**2 + uu**2 + ww**2))。

segments = quiver_data_to_segments(X, Y, Z, uu, vv, ww, length=5)
quiver_plot.set_segments(segments)