如何从文本文件创建情节动画(例如 mpeg 电影),而不将它们单独保存到计算机?
How to create an animation (mpeg movie, for example) of plots, from a text file, without saving them individually to computer?
所以我正在处理来自单独代码的一些输出(在 .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 中获取了大部分内容,当我 运行 这段代码时,我不明白为什么要花这么长时间。
有没有更好的方法来完成这个任务?还是我上面的代码有一些我不知道的错误?提前致谢。
您可以通过重复使用相同的绘图对象而不是在每次迭代时都创建一个新的绘图对象来节省时间。您的代码中有以下行:
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 编写视频从来都不是很快,但是当您重用对象而不是重新创建它们时,会有很大的不同。
所以我正在处理来自单独代码的一些输出(在 .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 中获取了大部分内容,当我 运行 这段代码时,我不明白为什么要花这么长时间。
有没有更好的方法来完成这个任务?还是我上面的代码有一些我不知道的错误?提前致谢。
您可以通过重复使用相同的绘图对象而不是在每次迭代时都创建一个新的绘图对象来节省时间。您的代码中有以下行:
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 编写视频从来都不是很快,但是当您重用对象而不是重新创建它们时,会有很大的不同。