Question: I'm currently coding my first tkinter GUI. I'm trying to make an interactive plot, using some scales so that the user can set the values of parameters affecting the plot. when I do this it starts lagging and my solution; working with threading is not working as intended. In my real code there are multiple plots so the application started lagging as shown here: from tkinter import * from tkinter import ttk import threading import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import time import numpy as np def create_window(root): frame1 = Frame(root) frame2 = Frame(root) frame1.grid(row=0,column=0) frame2.grid(row=0,column=1) figure1 = plt.Figure(figsize=(5,5)) figure1.set_tight_layout(True) ax1 = figure1.add_subplot(111) canvas1 = FigureCanvasTkAgg(figure1, frame1) canvas1.get_tk_widget().grid(column=1,row=1, padx=10, pady=10) m.trace_add('write', lambda var=None, index=None, mode=None: update_plot_tracer(ax1, canvas1)) m_scale = ttk.Scale(frame2, orient=VERTICAL, length=200, from_=100.0, to=0.0, variable=m) m_scale.grid(column=0, row=0) update_plot(ax1,canvas1) def update_plot(ax, canvas): #to make it lag time.sleep(0.1) x = np.arange(0,10,1) y = m.get() * x ax.clear() ax.plot(x,y) ax.set_ylim([0, 100]) canvas.draw() def update_plot_tracer(ax, canvas, var=None, index=None, mode=None): update_plot(ax, canvas) if __name__ == '__main__': root = Tk() m = DoubleVar(value = 10.0) create_window(root) root.mainloop()  My solution to that was to use threading so that the rest of the user interface is still usable while the plot is plotting. The problem I am running into now is that when the user drags the scale a lot there would be multiple threads called which interfere so I tried to stop the program from updating multiple times at the same time as shown below: from tkinter import * from tkinter import ttk import threading import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import time import numpy as np def create_window(root): frame1 = Frame(root) frame2 = Frame(root) frame1.grid(row=0,column=0) frame2.grid(row=0,column=1) figure1 = plt.Figure(figsize=(5,5)) figure1.set_tight_layout(True) ax1 = figure1.add_subplot(111) canvas1 = FigureCanvasTkAgg(figure1, frame1) canvas1.get_tk_widget().grid(column=1,row=1, padx=10, pady=10) m.trace_add('write', lambda var=None, index=None, mode=None: update_plot_tracer(ax1, canvas1)) m_scale = ttk.Scale(frame2, orient=VERTICAL, length=200, from_=100.0, to=0.0, variable=m) m_scale.grid(column=0, row=0) update_plot(ax1,canvas1) m_entry = ttk.Entry(frame2, textvariable = m) m_entry.grid(column=0, row=1) def update_plot(ax, canvas): x = np.arange(0,10,1) y = m.get() * x print('last used value of m', m.get()) ax.clear() ax.plot(x,y) ax.set_ylim([0, 100]) canvas.draw() #to make it lag time.sleep(0.2) def update_plot_tracer(ax, canvas, var=None, index=None, mode=None): global thread1#just to make this example work, in my real code i have it as a class variable... if thread1 is None or not thread1.is_alive(): thread1 = threading.Thread(target= lambda: update_plot(ax, canvas)) thread1.start() if __name__ == '__main__': thread1 = None root = Tk() m = DoubleVar(value = 10.0) create_window(root) root.mainloop()  Now I have the next problem: when the thread is started but the user keeps moving the mouse, the value he/she sees is not the one used in the plot, so I would like to do something like adding the threads to a queue, but then I will run into the problem that this queue could get very long and it would take some time to update to the newest state, even though all the threads between the currently running and the newest added are useless, but as far as I have understood it, once I have added a thread to the queue (from the queue bib) it cant be removed. I have never worked with most of this so any help is appreciated. Also, I want to keep it as interactive as possible, so to only update once the user lets go of the scale is not my preferred way of doing this. EDIT: The question is how do I create a queue of threads from which I can remove entries?

Answer: Even though Tkinter supports manipulating GUI in a thread different than the thread that created the Tcl interpreter(the root Tk instance), it's best to avoid that scenario because the implementation is not perfect and most GUI frameworks do not support that scenario. I recommend to do a data processing work in a background thread and a plotting work in the main thread. Now, let's move to the main topic on the queue. You don't need to implement a queue of threads. You can just start a new thread when the existing thread is finished. Use the after_idle() to schedule a function like this. Also, don't forget to join the thread. ... def update_plot_tracer(ax, canvas, var=None, index=None, mode=None): global thread1 if thread1 is None: def entry(): update_plot(ax, canvas) root.after_idle(on_end_thread) def on_end_thread(): # This will be run in the main thread. global thread1 if thread1.invalidated: root.after_idle(lambda: update_plot_tracer(ax, canvas)) thread1.join() thread1 = None thread1 = threading.Thread(target=entry) thread1.invalidated = False thread1.start() else: thread1.invalidated = True ...