Как создать анимацию (например, mpeg movie) сюжетов из текстового файла, не сохраняя их по отдельности на компьютере? - PullRequest
2 голосов
/ 12 мая 2019

, поэтому я работаю с некоторым выводом (в файле .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

, и у меня есть x-значения, которые я создаю, используя numpy.linspace.

Моя цель - создать фильм (.mpeg,например) который в основном строит график plt.plot (x, y), где x одинаков в каждом кадре, а y - в каждой строке матрицы, начиная с первой строки и заканчивая последней строкой.

В действительности у меня 6000 строк и 401 узел, что дает мне матрицу 6000 на 401 в файле output.txt, но я ожидаю, что матрица будет намного больше, когда я увеличу временной шаг в коде решателя до, возможно, 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 , и когда я запускаю этот код, яНе понимаю, почему это так долго.

Есть ли лучший способ выполнить эту задачу?Или в моем коде выше есть какая-то ошибка, о которой я не знаю?Заранее спасибо.

1 Ответ

0 голосов
/ 13 мая 2019

Вы можете сэкономить время, повторно используя один и тот же объект графика вместо создания нового на каждой итерации.В вашем коде есть следующая строка:

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 никогда не бывает очень быстрым, но при повторном использовании объектов вместо их воссоздания есть существенные различия.

...