如何从文本文件中创建图的动画(例如MPEG电影),而无需单独保存到计算机



因此,我正在从单独的代码中使用一些输出(在.txt文件中(,该代码采用最终矩阵,然后将此矩阵写入文件。输出的每行文件是在一定时间步上使用的1D热方程的解决方案。该矩阵可以长达数十万行(无论我选择运行的时间段,但基于许多时间段(。例如,也许输出看起来像这样:

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值。

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

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

以下是我到目前为止尝试的:

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文档中拿出了大部分,当我运行此代码时,我不明白为什么要花这么长时间。

有更好的方法可以完成这项任务吗?还是我上面的代码有我不知道的错误?预先感谢。

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

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编写视频从来都不是很快,但是当您重用对象而不是重新创建它们时,有很大的不同。

最新更新