Threading multiple animated plots in GUI with python3

Viewed 652

The code below should run as it stands. I have three classes (pages in the GUI) that I want to animate a plot in. In each class (or page) I will be accessing a remote file with live data being generated by different audio codecs and network interference. So each class (page) needs to access this live data and plot it.

The problem is that only my last plot is animated with the live data. The first two plots are static, they don't get or update with the current data. I am trying to run the plotting in a separate thread for each class. It seems whichever matplotlib canvas I create last is the only one that properly animates, canvas3 = FigureCanvasTkAgg(f, self)

In this shortened version of the code I am randomly generating the live data, but it is using some logic from accessing a local text file, sampleData.txt, which is also included below the pyhton3 script.

I am having issues mainly in the bottom of the python file when I am defining Class MyApp(tk.Tk):. The class where the plot works is Class PageThree(), and the classes where the plot is currently not working are Class PageOne() and Class PageTwo(). If you click the button for "PageThree" you will see the working animated plot. Please help me get the other plots to also animate. I'm not sure if the issue is with the threading, matplotlib canvas, or the ani1 = animation.FuncAnimation(f, animate, interval=1000) function. I'm building from the command line ($ python3 gui2.py) and I don't get any errors or warnings either.

Thanks!

gui2.py

#!/usr/bin/env python3

import paramiko, threading
import time, os, subprocess
from subprocess import Popen
import sys
#if not sys.warnoptions:
#   import warnings
#   warnings.simplefilter("ignore")

import matplotlib
matplotlib.use("TkAgg")

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

import tkinter as tk
from tkinter import ttk

# Just being used to debug plots
import random


LARGE_FONT=("Verdana", 12)
style.use("ggplot")

f = Figure(figsize=(9,6), dpi=100)
aPlot = f.add_subplot(211)
aPlot2 = f.add_subplot(212)

f2 = Figure(figsize=(9,6), dpi=100)
bPlot = f2.add_subplot(211)
bPlot2 = f2.add_subplot(212)

###==========================================================================================
### BEGIN FUNCS 4 FUN ###++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


# Function to execute the C++ code over ssh (Adaptive mode is default):
def start_ssh():
    print("SSH started")


# Function to update live labels
def label_reader(label):
    def reader():
        label.config(text="Mode: "+ str(mode[-1]))
        label.after(100, reader)
    reader()

# Function to kill the processes running the C++ networking code:
def clear():
    print("processes closed")


# Function to execute the C++ code over ssh using only Mode 1:
def start_ssh_singleMode():
        print("SSH single mode started")


# Function to setup interference and/or set it back to 0%:
def interference_setup():
        print("Interference setup")


# Function to add a hard-coded amount of interference:
def add_interference():
        print("Interference added")


global mode
mode = ["0"]
global plossRate
global counter, counter2
# Plot to animate
def animate(i):

    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    aPlot.clear()
    aPlot2.clear()
    aPlot.plot(counter, plossRate)
    aPlot.set_title('Packet Loss Rate')
    aPlot.set_ylabel('Percentage')
    aPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    aPlot2.set_title('Current Audio Mode')
    aPlot2.set_ylabel('mode')


    #finally:
    #remote_file.close()


# def make_plot(i):
#   pullData = open("sampleData.txt", "r").read()
#   dataList = pullData.split('\n')
#   remote_file = dataList
#   curFrame = []
#   recFrame = []
#   #global mode
#   #mode = []
#   #bytesRead = []
#   #missingFrames = []
#   plossRate = []
#   counter = []
#   counter2 = []
#   counter2.append(0)
#   value = 0
#   for eachLine in remote_file:
#       if len(eachLine)>1:
#           value=value+1
#           #a, b, c, d, e = eachLine.split(',')
#           #curFrame.append(int(a))
#           #recFrame.append(int(b))
#           mode.append(random.randint(1,3))
#           #bytesRead.append(int(d))
#           #missingFrames.append(int(e))
#           plossRate.append(random.randint(0,90))
#           counter.append(int(value))
#           counter2.append(int(value))
#           #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))
#
#   bPlot.clear()
#   bPlot2.clear()
#   bPlot.plot(counter, plossRate)
#   bPlot.set_title('Packet Loss Rate')
#   bPlot.set_ylabel('Percentage')
#   bPlot2.plot(counter, mode[-counter[-1]:], 'bo')
#   #aPlot2.axis(0,counter[-1],0,3)
#   bPlot2.set_title('Current Audio Mode')
#   bPlot2.set_ylabel('mode')


# Start plot
# def start_plot(self):
#   canvas = FigureCanvasTkAgg(f, self)
#   canvas.draw()
#   canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

### END FUNCS 4 FUN ###++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
###==========================================================================================


###==========================================================================================
### BEGIN MAIN CLASS FOR NETWORKUP APP ###+++++++++++++++++++++++++++++++++++++++++++++++++++
class MyApp(tk.Tk):


    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        #tk.Tk.iconbitmap(self, default="logo-no-halo-sm.png")
        tk.Tk.wm_title(self, "Network Up")

        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo, PageThree):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)


    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()



class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Home Page", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="PageOne", command=lambda: controller.show_frame(PageOne))
        button1.pack()

        button2 = ttk.Button(self, text="PageTwo", command=lambda: controller.show_frame(PageTwo))
        button2.pack()

        button3 = ttk.Button(self, text="PageThree", command=lambda: controller.show_frame(PageThree))
        button3.pack()

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (No Interference)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda:[controller.show_frame(StartPage), clear()])
        button1.pack()

        button_start = ttk.Button(self, text="Play", command=lambda: start_ssh)
        button_start.pack()

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)

        #time.sleep(.5)
        # plot_thread1 = threading.Thread(target=make_plot(self))
        # plot_thread1.daemon = True
        # plot_thread1.start()

        # canvas1 = FigureCanvasTkAgg(f, self)
        # canvas1.draw()
        # canvas1.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        # Just trying something different here
        self.start_plot()

    def start_plot(self):
        plot_thread1 = threading.Thread(target=animate(self))
        plot_thread1.daemon = False
        plot_thread1.start()
        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)



class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (Interference)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda: [controller.show_frame(StartPage), clear(), interference_setup()])
        button1.pack()

        button_start_mode1 = ttk.Button(self, text="Play", command=lambda: [start_ssh_singleMode(), add_interference()])
        button_start_mode1.pack()

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)

        plot_thread2 = threading.Thread(target=animate(self))
        plot_thread2.daemon = True
        plot_thread2.start()

        canvas2 = FigureCanvasTkAgg(f, self)
        canvas2.draw()
        canvas2.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)



class PageThree(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (Interference and Adaptive Codec)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda: [interference_setup(), clear(), controller.show_frame(StartPage)])
        button1.pack()

        button_start2 = ttk.Button(self, text="Play", command=lambda: [start_ssh(), add_interference()])
        button_start2.pack()


        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)


        plot_thread3 = threading.Thread(target=animate(self))
        plot_thread3.daemon = True
        plot_thread3.start()

        canvas3 = FigureCanvasTkAgg(f, self)
        canvas3.draw()
        canvas3.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        #toolbar = NavigationToolbar2Tk(canvas, self)
        #toolbar.update()
        #canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)


app = MyApp()
ani1 = animation.FuncAnimation(f, animate, interval=1000)
#ani2 = animation.FuncAnimation(f2, make_plot, interval=1000)

app.mainloop()

And here is the text file that I am using in some of the logic. It needs to be placed in the same directory that you run the python program from.

sampleData.txt

1,1
2,3
3,4
4,3
5,5
6,7
7,7
8,14
9,30
10,23
11,5
12,4
13,27
14,9
15,14
16,16
17,2
18,1
19,5
20,2
1 Answers

I finally figured out how to make all the plots work and update live. Turns out I needed a figure for each plot that was on a different page of the GUI. And I removed the threading for the figures because it caused performance problems in the real application. Turns out it was faster and more responsive without the threading. A fully working version of the code is at the bottom:

f = Figure(figsize=(9,6), dpi=100)
aPlot = f.add_subplot(211)
aPlot2 = f.add_subplot(212)


f2 = Figure(figsize=(9,6), dpi=100)
bPlot = f2.add_subplot(211)
bPlot2 = f2.add_subplot(212)

f0 = Figure(figsize=(9,6), dpi=100)
cPlot = f0.add_subplot(211)
cPlot2 = f0.add_subplot(212)

f4 = Figure(figsize=(9,6), dpi=100)
dPlot = f4.add_subplot(211)
dPlot2 = f4.add_subplot(212)

Then I needed a different function to animate each figure. So it was a lot of redundant code. There must be a better way to accomplish this.

def animate(i):

    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    #print("i is: " + str(i))
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    aPlot.clear()
    aPlot2.clear()
    aPlot.plot(counter, plossRate)
    aPlot.set_title('Packet Loss Rate')
    aPlot.set_ylabel('Percentage')
    aPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    aPlot2.set_title('Current Audio Mode')
    aPlot2.set_ylabel('mode')



    #finally:
    #pullData.close()


def make_plot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    bPlot.clear()
    bPlot2.clear()
    bPlot.plot(counter, plossRate[-counter[-1]:])
    bPlot.set_title('Packet Loss Rate')
    bPlot.set_ylabel('Percentage')
    bPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    bPlot2.set_title('Current Audio Mode')
    bPlot2.set_ylabel('mode')


def base_plot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    cPlot.clear()
    cPlot2.clear()
    cPlot.plot(counter, plossRate[-counter[-1]:])
    cPlot.set_title('Packet Loss Rate')
    cPlot.set_ylabel('Percentage')
    cPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    cPlot2.set_title('Current Audio Mode')
    cPlot2.set_ylabel('mode')

def livePlot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    dPlot.clear()
    dPlot2.clear()
    dPlot.plot(counter, plossRate[-counter[-1]:])
    dPlot.set_title('Packet Loss Rate')
    dPlot.set_ylabel('Percentage')
    dPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    dPlot2.set_title('Current Audio Mode')
    dPlot2.set_ylabel('mode')

Then in the app main loop I had to call all of these:

ani1 = animation.FuncAnimation(f, animate, interval=1000)
ani2 = animation.FuncAnimation(f2, make_plot, interval=1000)
ani3 = animation.FuncAnimation(f0, base_plot, interval=1000)
ani4 = animation.FuncAnimation(f4, livePlot, interval=1000)

Here is a working version of the python code:

gui3.py

#!/usr/bin/env python3

import paramiko, threading
import time, os, subprocess
from subprocess import Popen
import sys
# if not sys.warnoptions:
#   import warnings
#   warnings.simplefilter("ignore")

import matplotlib
matplotlib.use("TkAgg")

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style

import tkinter as tk
from tkinter import ttk

# Just being used to debug plots
import random
from matplotlib import pyplot as plt


LARGE_FONT=("Verdana", 12)
style.use("ggplot")

f = Figure()
aPlot = f.add_subplot(211)
aPlot2 = f.add_subplot(212)


f2 = Figure(figsize=(9,6), dpi=100)
bPlot = f2.add_subplot(211)
bPlot2 = f2.add_subplot(212)

f0 = Figure(figsize=(9,6), dpi=100)
cPlot = f0.add_subplot(211)
cPlot2 = f0.add_subplot(212)

f4 = Figure(figsize=(9,6), dpi=100)
dPlot = f4.add_subplot(211)
dPlot2 = f4.add_subplot(212)


###==========================================================================================
### BEGIN FUNCS 4 FUN ###++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


# Function to execute the C++ code over ssh (Adaptive mode is default):
def start_ssh():
    print("SSH started")


# Function to update live labels
def label_reader(label):
    def reader():
        label.config(text="Mode: "+ str(mode[-1]))
        label.after(100, reader)
    reader()

def loss_label_reader(label):
    def reader():
        label.config(text="Loss: "+ str(plossRate[-1]))
        label.after(100, reader)
    reader()

# Function to kill the processes running the C++ networking code:
def clear():
    print("processes closed")


# Function to execute the C++ code over ssh using only Mode 1:
def start_ssh_singleMode():
        print("SSH single mode started")


# Function to setup interference and/or set it back to 0%:
def interference_setup():
        print("Interference setup")


# Function to add a hard-coded amount of interference:
def add_interference():
        print("Interference added")


global mode
mode = ["0"]
global plossRate
plossRate = ["0"]
global counter, counter2
# Plot to animate
def animate(i):

    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    #print("i is: " + str(i))
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    aPlot.clear()
    aPlot2.clear()
    aPlot.plot(counter, plossRate)
    aPlot.set_title('Packet Loss Rate')
    aPlot.set_ylabel('Percentage')
    aPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    aPlot2.set_title('Current Audio Mode')
    aPlot2.set_ylabel('mode')



def make_plot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    bPlot.clear()
    bPlot2.clear()
    bPlot.plot(counter, plossRate[-counter[-1]:])
    bPlot.set_title('Packet Loss Rate')
    bPlot.set_ylabel('Percentage')
    bPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    bPlot2.set_title('Current Audio Mode')
    bPlot2.set_ylabel('mode')


def base_plot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    cPlot.clear()
    cPlot2.clear()
    cPlot.plot(counter, plossRate[-counter[-1]:])
    cPlot.set_title('Packet Loss Rate')
    cPlot.set_ylabel('Percentage')
    cPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    cPlot2.set_title('Current Audio Mode')
    cPlot2.set_ylabel('mode')

def livePlot(i):
    pullData = open("sampleData.txt", "r").read()
    dataList = pullData.split('\n')
    remote_file = dataList
    curFrame = []
    recFrame = []
    #global mode
    #mode = []
    #bytesRead = []
    #missingFrames = []
    #plossRate = []
    counter = []
    counter2 = []
    counter2.append(0)
    value = 0
    for eachLine in remote_file:
        if len(eachLine)>1:
            value=value+1
            #a, b, c, d, e = eachLine.split(',')
            #curFrame.append(int(a))
            #recFrame.append(int(b))
            mode.append(random.randint(1,3))
            #bytesRead.append(int(d))
            #missingFrames.append(int(e))
            plossRate.append(random.randint(0,90))
            counter.append(int(value))
            counter2.append(int(value))
            #print("mode = " + str(c) + " lastFrame =  " + str(b) + "  conter = " + str(value))

    dPlot.clear()
    dPlot2.clear()
    dPlot.plot(counter, plossRate[-counter[-1]:])
    dPlot.set_title('Packet Loss Rate')
    dPlot.set_ylabel('Percentage')
    dPlot2.plot(counter, mode[-counter[-1]:], 'bo')
    #aPlot2.axis(0,counter[-1],0,3)
    dPlot2.set_title('Current Audio Mode')
    dPlot2.set_ylabel('mode')


### END FUNCS 4 FUN ###++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
###==========================================================================================


###==========================================================================================
### BEGIN MAIN CLASS FOR NETWORKUP APP ###+++++++++++++++++++++++++++++++++++++++++++++++++++
class MyApp(tk.Tk):


    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        #tk.Tk.iconbitmap(self, default="logo-no-halo-sm.png")
        tk.Tk.wm_title(self, "Network Up")

        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo, PageThree, PageFour):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)


    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Home Page", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="PageOne", command=lambda: controller.show_frame(PageOne))
        button1.pack()

        button2 = ttk.Button(self, text="PageTwo", command=lambda: controller.show_frame(PageTwo))
        button2.pack()

        button3 = ttk.Button(self, text="PageThree", command=lambda: controller.show_frame(PageThree))
        button3.pack()

        button4 = ttk.Button(self, text="PageFour", command=lambda: controller.show_frame(PageFour))
        button4.pack(pady=5, padx=5)

        canvas0 = FigureCanvasTkAgg(f, self)
        self.canvas = canvas0

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (No Interference)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda:[controller.show_frame(StartPage), clear()])
        button1.pack()

        button_start = ttk.Button(self, text="Play", command=lambda: start_ssh)
        button_start.pack()

        loss_label = ttk.Label(self, text="Loss 0")
        loss_label.pack()
        loss_label_reader(loss_label)

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)

        canvas1 = FigureCanvasTkAgg(f0, self)
        canvas1.draw()
        canvas1.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.canvas = canvas1



class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (Interference)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda: [controller.show_frame(StartPage), clear(), interference_setup()])
        button1.pack()

        button_start_mode1 = ttk.Button(self, text="Play", command=lambda: [start_ssh_singleMode(), add_interference()])
        button_start_mode1.pack()

        loss_label = ttk.Label(self, text="Loss 0")
        loss_label.pack()
        loss_label_reader(loss_label)

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)

        canvas2 = FigureCanvasTkAgg(f2, self)
        canvas2.draw()
        canvas2.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.canvas = canvas2



class PageThree(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (Interference and Adaptive Codec)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda: [interference_setup(), clear(), controller.show_frame(StartPage)])
        button1.pack()

        button_start2 = ttk.Button(self, text="Play", command=lambda: [start_ssh(), add_interference()])
        button_start2.pack()

        loss_label = ttk.Label(self, text="Loss 0")
        loss_label.pack()
        loss_label_reader(loss_label)

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)

        canvas3 = FigureCanvasTkAgg(f, self)
        canvas3.draw()
        canvas3.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.canvas = canvas3


class PageFour(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="Audio (Interference and Adaptive Codec)", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Back to Home", command=lambda: [interference_setup(), clear(), controller.show_frame(StartPage)])
        button1.pack()

        button_start2 = ttk.Button(self, text="Play", command=lambda: [start_ssh(), add_interference()])
        button_start2.pack()

        w2 = tk.Scale(self, from_=0, to=90, orient='horizontal')
        w2.pack()

        loss_label = ttk.Label(self, text="Loss 0")
        loss_label.pack()
        loss_label_reader(loss_label)

        mode_label = ttk.Label(self, text="Mode 1")
        mode_label.pack()
        label_reader(mode_label)


        canvas4 = FigureCanvasTkAgg(f4, self)
        canvas4.draw()
        canvas4.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.canvas = canvas4



app = MyApp()
app.geometry("1280x720")
ani1 = animation.FuncAnimation(f, animate, interval=1000)
ani2 = animation.FuncAnimation(f2, make_plot, interval=1000)
ani3 = animation.FuncAnimation(f0, base_plot, interval=1000)
ani4 = animation.FuncAnimation(f4, livePlot, interval=1000)

app.mainloop()

And based on the logic you still need to add sampleData.txt which can be found in the posts question above.

Related