1

I am trying to plot data in realtime using matplotlib. So far I have only succeeded in showing a static figure window and in frustrating myself. I tried many minor changes based on other answer here but none seem to work. My code looks something as follows. Any help is appreciated.

import matplotlib.pyplot as plt
import numpy as np

class Plotter():
    def __init__(self):
        self.error = []
        self.fig, self.ax = plt.subplots()
        self.line, = self.ax.plot(range(len(self.error)), self.error)

    def start_plot(self):
        plt.ion()


    def end_plot(self):
        self.error = []

    def update(self, worker):
        self.error.append(worker.GetMetricValue())
        self.line.set_ydata(self.error)
        return self.line

    def update_plot(self, worker):
        self.error.append(worker.Get_metric_value())
        self.ax.set_ylim(np.min(self.error)*1.1, (np.max(self.error)+0.1)*1.1)
        self.line.set_ydata(self.error)
        self.line.set_xdata(range(len(self.error)))
        self.fig.canvas.draw()
        plt.pause(0.1)
        #self.fig.canvas.flush_events()

    def get_error(self):
        return self.error



class WorkerClass():
    def __init__(self):
        pass

    def Get_metric_value(self):
        return np.random.rand()


def main():
    worker = WorkerClass()
    pltr = Plotter()
    pltr.start_plot()
    for i in range(10):
        print("iteration {}".format(i))
        pltr.update_plot(worker)


if __name__ == '__main__':
    main()
Haaput
  • 45
  • 5

1 Answers1

0

Here is a corrected version of the code. I would propose to use FuncAnimation for the animation, since it's more stable and runs within the event loop of the figure.

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

class Plotter():
    def __init__(self):
        self.worker = WorkerClass()
        self.error = []
        self.fig, self.ax = plt.subplots()
        self.line, = self.ax.plot(range(len(self.error)), self.error)

    def start_plot(self):
        self.ani = FuncAnimation(self.fig, self.update_plot, frames=10, 
                                 interval=100, repeat=False)
        plt.show()

    def end_plot(self):
        self.error = []

    def update_plot(self, i):
        self.error.append(self.worker.Get_metric_value())
        self.line.set_data(range(len(self.error)), self.error)
        self.ax.relim()
        self.ax.autoscale_view()

    def get_error(self):
        return self.error


class WorkerClass():
    def __init__(self):
        pass

    def Get_metric_value(self):
        return np.random.rand()


def main():

    pltr = Plotter()
    pltr.start_plot()

if __name__ == '__main__':
    main()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712