Question: I try to implement a matplotlib figure that updates during the simulation of my environment.  The following Classes works fine in my test but doesn't update the figure when I use it in my environment. During the simulation of the environment, the graph is shown, but no lines are plotted. My guess is that .draw() is not working how I think it does.  Can anyone figure out the issue here?  class Visualisation: def __init__(self, graphs): self.graphs_dict = {} for graph in graphs: fig = plt.figure() ax = fig.add_subplot(111) line, = ax.plot(graph.x, graph.y, 'r-') self.graphs_dict[graph.title] = {"fig": fig, "ax": ax, "line": line, "graph": graph} self.graphs_dict[graph.title]["fig"].canvas.draw() plt.ion() plt.show() def update(self, graph): graph = self.graphs_dict[graph.title]["graph"] self.graphs_dict[graph.title]["line"].set_xdata(graph.x) self.graphs_dict[graph.title]["line"].set_ydata(graph.y) self.graphs_dict[graph.title]["fig"].canvas.flush_events() x_lim, y_lim = self.get_lim(graph) self.graphs_dict[graph.title]["ax"].set_xlim(x_lim) self.graphs_dict[graph.title]["ax"].set_ylim(y_lim) self.graphs_dict[graph.title]["fig"].canvas.draw() @staticmethod def get_lim(graph): if graph.x_lim is None: x = np.array(graph.x) y = np.array(graph.y) x_lim = [x.min(), x.max()] y_lim = [y.min(), y.max()] else: x_lim = graph.x_lim y_lim = graph.y_lim return x_lim, y_lim class Graph: def __init__(self, title, x, y, x_label="", y_label=""): """ Sets up a graph for Matplotlib Parameters ---------- title : String Title of the plot x : float y : float x_label : String x Label y_label : String y Label """ self.title = title self.x = x self.y = y self.x_label = x_label self.y_label = y_label self.x_lim, self.y_lim = None, None def set_lim(self, x_lim, y_lim): self.x_lim = x_lim self.y_lim = y_lim class Environment: def __init__(self, [..], verbose=0): """verbose : int 0 - No Visualisation 1 - Visualisation 2 - Visualisation and Logging""" self.vis = None self.verbose = verbose [......] def simulate(self): for _ in range(self.n_steps): [...] self.visualize() def visualize(self): if self.verbose == 1 or self.verbose == 2: if self.vis is None: graphs = [Graph(title="VariableY", x=[], y=[])] graphs[0].set_lim(x_lim=[0, 100], y_lim=[0, 300]) self.vis = Visualisation(graphs=graphs) else: self.vis.graphs_dict["VariableY"]["graph"].x.append(self.internal_step) self.vis.graphs_dict["VariableY"]["graph"].y.append(150) self.vis.update(self.vis.graphs_dict["VariableY"]["graph"])  When I run the code I more or less just write: env.simulate().  The code runs fine here: class TestSingularVisualisation(unittest.TestCase): def setUp(self): self.graph = Graph(title="Test", x=[0], y=[0]) self.vis = Visualisation(graphs=[self.graph]) class TestSingleUpdate(TestSingularVisualisation): def test_repeated_update(self): for i in range(5): self.graph.x.append(i) self.graph.y.append(np.sin(i)) self.vis.update(self.graph) time.sleep(1) 

Answer: Turns out your code works the way it is set up. Here is the sole problem with the code you provided: self.vis.graphs_dict["VariableY"]["graph"].x.append(self.internal_step) self.vis.graphs_dict["VariableY"]["graph"].y.append(150)  You are plotting a line and correctly updating the canvas, however, you keep appending the exact same (x, y) coordinate. So the simulation does update the line, but the line simplifies to a point. Your test case does not do this. You can run a dummy example with your code by simply adding a line like this: self.internal_step += 5  before adding the new x point, and you will produce a horizontal line. Let me know if this solves your problem.