如何使用Python和Tkinter实时更新多个子图

时间:2017-04-12 19:37:45

标签: python user-interface tkinter arduino graphing

我正在制作一个Python GUI,以替换我使用Arduino进行接口的旧Matlab GUI。我需要GUI能够以每秒20点的速度绘制传入的arduino数据而不会减速,我只需要它来绘制最近的100点最小值。我在这方面遇到了很多麻烦,并且希望我能够得到一些如何做到这一点的帮助我还不是很熟悉Python,所以我提前道歉没有最多的pythonic代码并没有完全理解事物。这就是我到目前为止所拥有的。 (我需要能够在运行时操作GUI上的按钮,以防我需要停止它等等)

import Tkinter
import numpy as np
import serial
import time
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from math import sin

class App:
    def __init__(self, master):

        frame = Tkinter.Frame(master)

        self.Max_press = Tkinter.StringVar()
        self.Max_press.set("10")
        self.Min_press = Tkinter.StringVar()
        self.Min_press.set("0")
        self.Cycle_per_minute = Tkinter.StringVar()
        self.Cycle_per_minute.set("12")
        self.Duration_cycle = Tkinter.StringVar()
        self.Duration_cycle.set("1")

        self.respiration = Tkinter.LabelFrame(frame, text="Respiration Testing", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10)
        self.respiration.grid(row=0, column=0, padx=20, pady=20)

        self.max_pressure = Tkinter.Label(self.respiration, text="Maximum Pressure (mmHg)")
        self.max_pressure.grid(row=0, column=0, padx=5, pady=5)

        self.Max_pressure = Tkinter.Entry(self.respiration,textvariable=self.Max_press)
        self.Max_pressure.grid(row=1, column=0, padx=5, pady=5)

        self.min_pressure = Tkinter.Label(self.respiration, text="Minimum Pressure (mmHg)")
        self.min_pressure.grid(row=2, column=0, padx=5, pady=5)

        self.Min_pressure = Tkinter.Entry(self.respiration, textvariable=self.Min_press)
        self.Min_pressure.grid(row=3, column=0, padx=5, pady=5)

        self.cycles_per_minute = Tkinter.Label(self.respiration, text="Cycles Per Minute")
        self.cycles_per_minute.grid(row=4, column=0, padx=5, pady=5)

        self.Cycles_per_minute = Tkinter.Entry(self.respiration,textvariable=self.Cycle_per_minute)
        self.Cycles_per_minute.grid(row=5, column=0, padx=5, pady=5)

        self.duration_of_test = Tkinter.Label(self.respiration, text="Duration (minutes)")
        self.duration_of_test.grid(row=6, column=0, padx=5, pady=5)

        self.Duration_of_test = Tkinter.Entry(self.respiration, textvariable=self.Duration_cycle)
        self.Duration_of_test.grid(row=7, column=0, padx=5, pady=5)

        self.run_respiration = Tkinter.Button(self.respiration, text="RUN RESPIRATION", command=self.getData)
        self.run_respiration.grid(row=8, column=0, padx=5, pady=5)

        self.burst = Tkinter.LabelFrame(frame, text="Burst Test", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10 )
        self.burst.grid(row=0, column=1, padx=20, pady=20)

        self.burst_pressure = Tkinter.Button(self.burst, text="RUN BURST TEST")
        self.burst_pressure.grid(row=0, column=0, padx=5, pady=5)

        self.test_options = Tkinter.LabelFrame(frame, text="Test Options", borderwidth=10, relief=Tkinter.GROOVE, padx=10, pady=10 )
        self.test_options.grid(row=0, column=2, padx=20, pady=35)

        self.stop = Tkinter.Button(self.test_options, text="STOP", bd=10, height=5, width=10)
        self.stop.grid(row=0, column=0, padx=10, pady=25)

        self.pause = Tkinter.Button(self.test_options, text="PAUSE", bd=10, height=5, width=10)
        self.pause.grid(row=1, column=0, padx=10, pady=25)

        self.reset = Tkinter.Button(self.test_options, text="RESET", bd=10, height=5, width=10)
        self.reset.grid(row=2, column=0, padx=10, pady=25)

        self.save = Tkinter.Button(self.test_options, text="SAVE", bd=10, height=5, width=10)
        self.save.grid(row=3, column=0, padx=10, pady=25)

        fig = Figure()
        ax = fig.add_subplot(211)
        fig1 = Figure()
        ax1 =  fig1.add_subplot(212)
        self.line, = ax.plot([x/0.5 for x in range(20)])
        self.line, = ax1.plot([x/1 for x in range(20)])
        self.canvas = FigureCanvasTkAgg(fig,master=master)
        self.canvas.show()
        self.canvas = FigureCanvasTkAgg(fig1,master=master)
        self.canvas.show()
        self.canvas.get_tk_widget().grid(row=0, column=3, padx=20, pady=20)
        frame.grid(row=0, column=0, padx=20, pady=20)

    def getData(self):
        press_max = float(self.Max_press.get())
        press_min = float(self.Min_press.get())
        duration = float(self.Duration_cycle.get())*60*20
        cycle_time = float(self.Cycles_per_minute.get())
        self.makeSine(press_max, press_min, duration, cycle_time)

    def makeSine(self, Press_max, Press_min, Duration, Cycle_time):
        i = 0
        x = []
        y = []
        amp = (Press_max - Press_min)/2
        offset = amp + Press_min
        spb = 60/Cycle_time
        while (i < Duration + 1):
            x.append(i)
            sine = amp*np.sin((x[i]*(np.pi*4))/(2*spb)) + offset + 1
            y.append(sine)
            i = i + 1

        self.readWrite(x,y, Duration)

    def readWrite(self, x, y, Duration):
        i = 0
        arduinoData = serial.Serial('com5', 115200)
        arduinoData.flushInput()
        start = time.time()
        while (i < Duration + 1): # While loop that loops forever
            while (arduinoData.inWaiting()==0):
                 pass
             arduinoString = arduinoData.readline()
            dataArray = arduinoString #.split(',')
            #temp = int( dataArray[0])
            temp = int(dataArray)
            #P =    int( dataArray[1])
            print temp #, P
            i = i + 1
        end = time.time()
        print (end - start)




root = Tkinter.Tk()
app = App(root)
root.mainloop()

1 个答案:

答案 0 :(得分:1)

以下是如何在动画中使用最后x个数据点的示例。

<script>