Home > Software engineering >  Matplotlib not plotting anything
Matplotlib not plotting anything

Time:05-04

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)

CodePudding user response:

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)
  • Related