【问题标题】:How to create an animation (mpeg movie, for example) of plots, from a text file, without saving them individually to computer?如何从文本文件创建情节动画(例如 mpeg 电影),而不将它们单独保存到计算机?
【发布时间】:2019-05-12 00:54:51
【问题描述】:

所以我正在处理来自单独代码的一些输出(在 .txt 文件中),该代码采用最终矩阵并将该矩阵写入文件。输出文件的每一行都是特定时间步长的一维热方程的解。这个矩阵可以长达几十万行(基于我选择运行的时间步长)。例如,输出可能如下所示:

1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9
4 5 6 7 8 9 10

我有使用 numpy.linspace 创建的 x 值。

我的目标是创建一个基本上绘制 plt.plot(x,y) 的电影(例如 .mpeg),其中 x 在每一帧中都是相同的,y 是矩阵的每一行,从第一行开始行并在最后一行结束。

实际上,我有 6000 行和 401 个节点,在 output.txt 文件中给了我一个 6000 x 401 矩阵,但我希望当我将求解器代码中的时间步长增加到可能 1,000,000 时,矩阵会更大时间步长(这可以给我几十万行)。由于绘图的数量,我试图避免为每一行编写多个图像并将它们存储在我的计算机上然后将它们编译成一部电影的方法 - 我想将这些数据一次全部写入文件。

以下是我目前尝试过的:

import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as manimation


FFMpegWriter = manimation.writers['ffmpeg']
metadata = dict(title='Movie Test', artist='Matplotlib',
                comment='Movie support!')
writer = FFMpegWriter(fps=15, metadata=metadata)

fig = plt.figure()
l, = plt.plot([], [], 'k-o')

solverlist = ["explicit", "implicit", "crank-nicolson"]
filename = f"{solverlist[2]}-solver/cn_output_400_nodes.txt"
loaded_matrix = np.loadtxt(filename, dtype='f', delimiter=' ')

with writer.saving(fig, f"{solverlist[2]}_400_node_solution.mp4", 100):    
    x = np.linspace(0.0, 2.0, len(loaded_matrix[1]))
    for i in range(len(loaded_matrix)):
        y = loaded_matrix[i]
        plt.plot(x,y)
        plt.title("Time Evolution of Heat Equation Solver")
        writer.grab_frame()

我从MatPlotLib MovieWriter documantation 中获取了大部分内容,当我运行这段代码时,我不明白为什么需要这么长时间。

有没有更好的方法来完成这项任务?还是我上面的代码有一些我不知道的错误?提前致谢。

【问题讨论】:

    标签: python python-3.x numpy animation movie


    【解决方案1】:

    您可以通过重复使用相同的绘图对象来节省时间,而不是在每次迭代时都创建一个新对象。您的代码中有以下行:

    l, = plt.plot([], [], 'k-o')
    

    您似乎创建了一个情节以供以后重用,但之后不使用l。试试这样的:

    import numpy as np
    import matplotlib
    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    import matplotlib.animation as manimation
    
    
    FFMpegWriter = manimation.writers['ffmpeg']
    metadata = dict(title='Movie Test', artist='Matplotlib',
                    comment='Movie support!')
    writer = FFMpegWriter(fps=15, metadata=metadata)
    
    fig = plt.figure()
    l, = plt.plot([], [], 'k-o')
    l.set_title("Time Evolution of Heat Equation Solver")
    
    solverlist = ["explicit", "implicit", "crank-nicolson"]
    filename = f"{solverlist[2]}-solver/cn_output_400_nodes.txt"
    loaded_matrix = np.loadtxt(filename, dtype='f', delimiter=' ')
    
    with writer.saving(fig, f"{solverlist[2]}_400_node_solution.mp4", 100):
        x = np.linspace(0.0, 2.0, len(loaded_matrix[0]))
        for i in range(len(loaded_matrix)):
            y = loaded_matrix[i]
            l.set_data(x, y)
            writer.grab_frame()
    

    根据我的经验,使用 Matplotlib 和 ffmpeg 编写视频从来都不是很快,但是当你重用对象而不是重新创建对象时,会有很大的不同。

    【讨论】:

      猜你喜欢
      • 2011-05-04
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      相关资源
      最近更新 更多