How to speed up tkinter embedded matplot lib and python

前端 未结 1 592
挽巷
挽巷 2021-01-27 09:36

I have a GUI that I am using to send a query data from an arduino. I then went to live graph this data without slow down. I currently am getting slow down with the more numbers

相关标签:
1条回答
  • 2021-01-27 10:08

    You need to use the matplotlib animation capabilities for the fastest response. Here's an example inside a tkinter window. I obviously can't test it since I don't have your arduino, so I commented out the arduino parts and added some random parts.

    import Tkinter as tk
    import serial
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    from matplotlib import pyplot as plt
    import matplotlib.animation as animation
    from collections import deque
    import random
    
    HISTORY_LEN = 200
    
    class App(tk.Frame):
        def __init__(self, master=None, **kwargs):
            tk.Frame.__init__(self, master, **kwargs)
    
            self.running = False
            self.ani = None
    
            btns = tk.Frame(self)
            btns.pack()
    
            lbl = tk.Label(btns, text="Number of points")
            lbl.pack(side=tk.LEFT)
    
            self.points_ent = tk.Entry(btns, width=5)
            self.points_ent.insert(0, '500')
            self.points_ent.pack(side=tk.LEFT)
    
            lbl = tk.Label(btns, text="update interval (ms)")
            lbl.pack(side=tk.LEFT)
    
            self.interval = tk.Entry(btns, width=5)
            self.interval.insert(0, '30')
            self.interval.pack(side=tk.LEFT)
    
            self.btn = tk.Button(btns, text='Start', command=self.on_click)
            self.btn.pack(side=tk.LEFT)
    
            self.fig = plt.Figure()
            self.ax1 = self.fig.add_subplot(111)
            self.line, = self.ax1.plot([], [], lw=2)
            self.canvas = FigureCanvasTkAgg(self.fig,master=master)
            self.canvas.show()
            self.canvas.get_tk_widget().pack()
    
        def on_click(self):
            if self.ani is None:
                return self.start()
            if self.running:
                self.ani.event_source.stop()
                self.btn.config(text='Un-Pause')
            else:
                self.ani.event_source.start()
                self.btn.config(text='Pause')
            self.running = not self.running
    
        def start(self):
            self.xdata = deque([], maxlen=HISTORY_LEN)
            self.ydata = deque([], maxlen=HISTORY_LEN)
            #~ self.arduinoData = serial.Serial('com5', 115200)
            #~ self.arduinoData.flushInput()
            self.points = int(self.points_ent.get()) + 1
            self.ani = animation.FuncAnimation(
                self.fig,
                self.update_graph,
                frames=self.points,
                interval=int(self.interval.get()),
                repeat=False)
            self.running = True
            self.btn.config(text='Pause')
            self.ani._start()
    
        def update_graph(self, i):
            self.xdata.append(i)
            #~ self.ydata.append(int(self.arduinoData.readline()))
            self.ydata.append(random.randrange(100)) # DEBUG
            self.line.set_data(self.xdata, self.ydata)
            self.ax1.set_ylim(min(self.ydata), max(self.ydata))
            self.ax1.set_xlim(min(self.xdata), max(self.xdata))
            if i >= self.points - 1:
                #~ self.arduinoData.close()
                self.btn.config(text='Start')
                self.running = False
                self.ani = None
            return self.line,
    
    def main():
        root = tk.Tk()
        app = App(root)
        app.pack()
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    For more speed, cut out the print functions. Printing to the terminal is very slow. Also, you may want to move the serial initialization to someplace where it's only called once.

    For my computer, the fastest I could go was 25 ms / frame.

    0 讨论(0)
提交回复
热议问题