0

I am trying to animate a figure with 3 subplots for some data from a tensor log. I've made generator and animation functions which appear to yield the correct data, however when I do plt.show(), nothing shows on the plot, and when I try to save as mp4, nothing is plotted on the generated video, and it only iterates up to the 100th value (out of 609) and then stops.

Here is the minimal code:

import os
import matplotlib.pyplot as plt
import numpy as np
import matplotlib

def gendat():

    res = list(np.random.random_sample(size=609))
    lens = list(np.random.random_sample(size=609))
    loss = list(np.random.random_sample(size=609))
    for i, (r, le, lo) in enumerate(zip(res,lens,loss)):
        yield i, r, le , lo


figure, axis = plt.subplots(1,3, figsize=(15,5))

line1, = axis[0].plot([],[])
axis[0].set_xlabel("Episodes")
axis[0].set_ylabel("Average Reward")
axis[0].set_title("Reward")

line2, = axis[1].plot([],[])
axis[1].set_xlabel("Episodes")
axis[1].set_ylabel("Average Episode Length")
axis[1].set_title("Episode Length")

line3, = axis[2].plot([],[])
axis[2].set_xlabel("Episodes")
axis[2].set_ylabel("Average Loss")
axis[2].set_title("Loss")

line = [line1,line2,line3]

def init():
    line[0].set_data([],[])
    line[1].set_data([],[])
    line[2].set_data([],[])

    return line

figure.tight_layout()

def animate(dat):

    i,r, le , lo = dat

    print("got",i,r,le,lo)
    line[0].set_data(i,r)
    line[1].set_data(i,le)
    line[2].set_data(i,lo)

    return line

FFwriter = matplotlib.animation.FFMpegWriter(fps=30, extra_args=['-vcodec', 'libx264'])
ani = matplotlib.animation.FuncAnimation(figure, animate, init_func=init, frames=gendat, interval=20, repeat=False, blit=True)

plt.show()

ani.save("results.mp4",writer=FFwriter, dpi=500)
#plt.savefig("results.png",transparent=True, dpi=500)

1 Answer 1

0

Two things to fix:

  1. The axis limits for all subplots.
  2. set_data requires lists of coordinates, not numbers!
import os
import matplotlib.pyplot as plt
import numpy as np
import matplotlib

N = 609
def gendat():

    res = list(np.random.random_sample(size=609))
    lens = list(np.random.random_sample(size=609))
    loss = list(np.random.random_sample(size=609))
    for i, (r, le, lo) in enumerate(zip(res,lens,loss)):
        yield i, r, le , lo


figure, axis = plt.subplots(1,3, figsize=(15,5))

line1, = axis[0].plot([],[])
axis[0].set_xlabel("Episodes")
axis[0].set_ylabel("Average Reward")
axis[0].set_title("Reward")
axis[0].set_xlim(0, N)
axis[0].set_ylim(-10, 10)

line2, = axis[1].plot([],[])
axis[1].set_xlabel("Episodes")
axis[1].set_ylabel("Average Episode Length")
axis[1].set_title("Episode Length")
axis[1].set_xlim(0, N)
axis[1].set_ylim(-10, 10)

line3, = axis[2].plot([],[])
axis[2].set_xlabel("Episodes")
axis[2].set_ylabel("Average Loss")
axis[2].set_title("Loss")
axis[2].set_xlim(0, N)
axis[2].set_ylim(-10, 10)

line = [line1,line2,line3]

def init():
    line[0].set_data([],[])
    line[1].set_data([],[])
    line[2].set_data([],[])

    return line

figure.tight_layout()

def append_to_line(line, x, y):
    xd, yd = [list(t) for t in line.get_data()]
    xd.append(x)
    yd.append(y)
    line.set_data(xd, yd)
    print(xd)
    
def animate(dat):
    i, r, le, lo = dat

    append_to_line(line[0], i, r)
    append_to_line(line[1], i, le)
    append_to_line(line[2], i, lo)

# FFwriter = matplotlib.animation.FFMpegWriter(fps=30, extra_args=['-vcodec', 'libx264'])
ani = matplotlib.animation.FuncAnimation(figure, animate, frames=gendat, interval=20, repeat=False)

plt.show()

ani.save("results.mp4",writer=FFwriter, dpi=500)
Sign up to request clarification or add additional context in comments.

2 Comments

This is amazing cheers. Do you have any idea why the mp4 writer only does the first 100 frames though? it just stops at 99 for me.
No idea, I never had to save an animation... Don't forget to mark this answer as the solution to the question!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.