Question: I am working on a Tkinter project where I am plotting live data from different sensors. I am using Tkinter to create the GUI and matplotlib animation.FuncAnimation to create live plots that update every given time (i.e. 1 second). The code is written in python 3. This work fine as long as the total number of point is small. As the number of points exceed 300-400 the system starts accumulating delay, slows down and eventually freezes. I.e. if I aim to have a reading every 1 second, in the beginning the system returns a reading every 1 second and few ms. However as the time goes by, it starts increasing the interval with a linear trend (please see image below) I can reproduce the problem by creating a single plot having on the x-axis the number of iteration (i.e. readings) and on the y-axis the delta time between each iteration and updating the plot every second (even if I use a longer time interval the result is the same). I have tried to put the animation function in an independent thread, as it was suggested in other posts, but it did not help at all. If I do not create the plot but I use the generated data (i.e. delta time) to update labels in tkinter I do not have the issue, so it must be related with the creation/update of the plot. Switching on/off blit does not help, and I would prefer to keep it off anyway. Please see below a short version of the code to reproduce the error and the output image after 600 iterations. import tkinter as tk import matplotlib.pyplot as plt from matplotlib.backends import backend_tkagg as bk import matplotlib.animation as animation import numpy as np import time import threading class Application(tk.Frame): def __init__(self, master=None, **kwargs): tk.Frame.__init__(self, master, **kwargs) # ============================================================================= # # Test 1 flags initialization # ============================================================================= self.ani = None # ============================================================================= # Canvas frame # ============================================================================= self.fig = plt.figure(figsize=(15,5)) frm = tk.Frame(self) frm.pack() self.canvas = bk.FigureCanvasTkAgg(self.fig, master=frm) self.canvas.get_tk_widget().pack() # ============================================================================= # # Figure initialization # ============================================================================= self.ax = self.fig.add_subplot(1,1,1) self.ax.plot([],[],'-k', label='delta time') self.ax.legend(loc='upper right') self.ax.set_xlabel('n of readings [-]') self.ax.set_ylabel('time difference between readings [s]') # ============================================================================= # # Start/Quick button # ============================================================================= frm4 = tk.Frame(self) frm4.pack(side='top', fill='x') frm_acquisition = tk.Frame(frm4) frm_acquisition.pack() self.button= tk.Button(frm_acquisition, text="Start acquisition", command=lambda: self.on_click(), bg='green') self.button.grid(column = 0, row=0) # ============================================================================= # # Methods # ============================================================================= def on_click(self): '''the button is a start/stop button ''' if self.ani is None: self.button.config(text='Quit acquisition', bg='red') print('acquisition started') return self.start() else: self.ani.event_source.stop() self.button.config(text='Start acquisition', bg='green') print('acquisition stopped') self.ani = None return def start(self): self.starting_time = time.time() self.time = np.array([]) self.ani = animation.FuncAnimation(self.fig, self.animate_thread, interval =1000, blit=False, cache_frame_data=False) #interval in ms self.ani._start() return # Some post suggested to put animate() in an indipendent thread, but did not solve the problem def animate_thread(self, *args): self.w = threading.Thread(target=self.animate) self.w.daemon = True # Daemonize the thread so it exits when the main program finishes self.w.start() return self.w def animate(self, *args): self.time = np.append(self.time, time.time()-self.starting_time) if len(self.time) > 1: self.ax.scatter(len(self.time),self.time[-1]-self.time[-2], c='k') # root.update() # another post suggested root.update() but did not help either return self.ax, if __name__ == "__main__": root = tk.Tk() app=Application(root) app.pack() root.mainloop()  Time delay plot: 

Answer: Most of the examples matplotlib animation suggests creating the plot axes during intialization of animation instead of creating inside animate function, as your above part of code shows. So a possible way can be create scatter object and hold it in a variable which is intialized once. it actually returns matplotlib collections. Something like this for example,  self.ax = self.fig.add_subplot(1,1,1) self.ax.plot([],[],'-k', label='delta time') self.ax.legend(loc='upper right') self.ax.set_xlabel('n of readings [-]') self.ax.set_ylabel('time difference between readings [s]') self.scatplot = self.ax.scatter(x, y, c='k') #here x and y are array data initalized empty.  And in animate function, you can utilize 'self.scatplot' like this below with proper data format and customization, Refer here How to animate a scatter plot and FuncAnimation  def animate(self, *args): self.time = np.append(self.time, time.time()-self.starting_time) data = np.stack([len(self.time), self.time[-1]-self.time[-2]]) if len(self.time) > 1: self.scatplot.set_offsets(data) return self.scatplot,