【问题标题】:How to update 3D arrow animation in matplotlib如何在 matplotlib 中更新 3D 箭头动画
【发布时间】:2016-02-10 22:24:09
【问题描述】:

我正在尝试使用 matplotlib 在 python 中重现 this animation 的左侧图。

我可以使用 3D quiver 函数生成矢量箭头,但正如我 read here 一样,似乎无法设置箭头的长度。所以,我的情节看起来不太对:

所以,问题是:如何生成多个不同长度的 3D 箭头?重要的是,我能否以这样一种方式生成它们,以便我可以轻松地为动画的每一帧进行修改?

到目前为止,这是我的代码,采用不太有前途的 3D 箭袋方法:

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d

ax1 = plt.subplot(111,projection='3d')

t = np.linspace(0,10,40)

y = np.sin(t)
z = np.sin(t)
line, = ax1.plot(t,y,z,color='r',lw=2)

ax1.quiver(t,y,z, t*0,y,z)
plt.show() 

【问题讨论】:

  • 你的数据中是否有长度变量
  • 为了匹配另一个图,向量的长度应该足以将它们扩展到 x(或 t 这种情况下)轴。我在想,绘制箭头实际上可能不需要长度,但如果是的话,它可以很容易地计算为 length = np.sqrt(y**2 + z**2)。
  • 不幸的是,它似乎不是(目前):github.com/matplotlib/matplotlib/issues/4211
  • 问题是 mplot3d 总是标准化箭头长度。我知道这很不雅,但是如果您手动编辑 mpl_toolkits/mplot3d/axes3d.py 并将这一行 norm = math.sqrt(u ** 2 + v ** 2 + w ** 2) 更改为 norm = 1 它将适用于您当前的代码。我不知道为什么开发人员不会添加标志以仅在需要时执行规范化。

标签: python animation matplotlib 3d


【解决方案1】:

正如 Azad 所建议的,一个不雅但有效的解决方案是简单地编辑 mpl_toolkits/mplot3d/axes3d.py 以删除规范化。由于我不想弄乱我的实际 matplotlib 安装,我只是将 axes3d.py 文件复制到与我的其他脚本相同的目录并修改了行

norm = math.sqrt(u ** 2 + v ** 2 + w ** 2)

norm = 1

(请务必更改正确的行。“norm”还有另一种用法,高几行。)另外,为了让 axes3d.py 在 mpl 目录之外正常运行,我更改了

from . import art3d
from . import proj3d
from . import axis3d

from mpl_toolkits.mplot3d import art3d
from mpl_toolkits.mplot3d import proj3d
from mpl_toolkits.mplot3d import axis3d

这是我能够生成的漂亮动画(不确定颜色出了什么问题,在我上传到 SO 之前看起来还不错)。

以及生成动画的代码:

import numpy as np
import matplotlib.pyplot as plt
import axes3d_hacked

ax1 = plt.subplot(111,projection='3d')
plt.ion()
plt.show()

t = np.linspace(0,10,40)

for index,delay in enumerate(np.linspace(0,1,20)):
    y = np.sin(t+delay)
    z = np.sin(t+delay)

    if delay > 0:
        line.remove()
        ax1.collections.remove(linecol)

    line, = ax1.plot(t,y,z,color='r',lw=2)
    linecol = ax1.quiver(t,y,z, t*0,y,z)

    plt.savefig('images/Frame%03i.gif'%index)
    plt.draw()

plt.ioff()
plt.show()

现在,如果我能让那些箭头看起来更漂亮,头部填充得很好。但这是一个单独的问题......

编辑:将来,matplotlib 将不会根据 pull request 自动标准化 3D 箭袋中的箭头长度。

【讨论】:

  • 您不必使用任何额外的导入,但如果您的解释器在编辑之前打开,您应该关闭它并再次打开它
  • 我更改了导入,因为我将 axes3d.py 文件的位置移动到与我的脚本相同的目录。我想避免实际更改我的 matplotlib 发行版的源代码。
  • 不用担心 - 只要确保我正确理解了您。再次感谢您的帮助!
【解决方案2】:

另一种解决方案是在每个箭头上单独调用ax.quiever - 每个调用都有自己的length 属性。这不是很有效,但它会让你继续前进。

而且无需更改 MPL 代码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-27
    • 2017-08-09
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 2013-06-22
    • 2016-10-13
    • 1970-01-01
    相关资源
    最近更新 更多