How can I create an animation of a plot (like an mpeg movie) from a text file without saving it separately to the computer?


gram_schmidt

So I'm processing some output (in a .txt file) from a separate code that takes the final matrix and writes that matrix to a file. The output is that each line of the file is the solution to the one-dimensional heat equation for a specific time step. This matrix can be hundreds of thousands of rows long (based on many time steps I choose to run). For example, maybe the output looks like this:

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

and I have x values ​​created using numpy.linspace.

My goal is to create a movie (eg. .mpeg) that basically plots plt.plot(x,y) where x is the same in every frame and y is each row of the matrix, Start on the first line and end on the last line.

Actually, I have 6000 rows and 401 nodes, which gives me a 6000 x 401 matrix in the output.txt file, but when I increase the timesteps in the solver code to a possible 1,000,000 timesteps, I want The matrix will be much larger (can give me hundreds of thousands of rows). Due to the number of plots, I'm trying to avoid the approach of writing multiple images for each line and storing them on the computer and then compiling it into a movie - I want to write this data to a file all at once.

Here's what I've tried so far:

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()

I got most of it from the MatPlotLib MovieWriter documantation and when I run this code I don't understand why it is taking so long.

Is there a better way to accomplish this task? Or is there a bug in the code above that I don't know about? Thanks in advance.

Jdehesa

You can save time by reusing the same plot object instead of creating a new plot object on each iteration. You have the following lines in your code:

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

You seem to be creating a diagram here to reuse it later, but then lit's not used anymore. Try something like this:

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()

Writing videos with Matplotlib and ffmpeg is never very fast in my experience, but it makes a big difference when you reuse objects instead of recreating them.

Related


How can I plot this data from text?

lolo I want to make this graph using python , where the data in the text file looks like this (each row represents the data for the current day, showing the data for 5 days): -110 -108 -95 -92 -88 -87 -85 -75 -73 -69 -67 -59 -51 -49 -47 -42 -39 -35 -36 -36 -32

Create a text file and email it without saving it locally

user3558939: I want to create a text file in Python, write something to it, and email it out ( test.txtas an email attachment). However, I cannot save this file locally. Does anyone know how to do this? As soon as the text file is opened for writing, the file

How can I measure the size of a file without saving it to disk?

Marlon Jack I am making a postgres base dump file. By using pg_dump base > base.sql, postgres is created, base.sqlbut until the process is complete, the file appears as 0 bytes. Is there a way to access the size of the file to make some kind of progress bar? I

How can I stream a file without saving it first?

Bowdoin I've put together the code below to create a CSV called example.csvusing json2csvthe library . I would like to not have to save and store the CSV file before passing it to the front end for download. I can't seem to figure out how to stream or pipe the

How can I measure the size of a file without saving it to disk?

Marlon Jack I am making a postgres base dump file. By using pg_dump base > base.sql, postgres is created, base.sqlbut until the process is complete, the file appears as 0 bytes. Is there a way to access the size of the file to make some kind of progress bar? I

How can I create and start threads separately

lye What I want to do is to create some threads and push them into a vector to start them after some checks. So here I mainly want to create the following themes int main() { Pont pont; for (int k = 0; k <= 20; k++) { std::thread th(crossBrid