I am making a GUI which shows a graph of 4 different readings. Right now the readings are randomly generated. I am using matplotlib and animation to show live readings, where 2 of the readings are sharing one subplot, and the other two are shown on the other subplot. On the x-axis, I am showing the current time readings.
I am relatively new to python, so I am not sure how some of the stuff works. My issue is most likely that I have the answers but don't know how to apply them.
Here is my code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import matplotlib.pyplot as plt #to plot the graph
import matplotlib.animation as animation #to create the real-time graph
from matplotlib import style #to change the way the graph will look
import matplotlib.ticker as mticker
import numpy as np
import datetime as dt
#-----------------------------END OF IMPORT -----------------------------------------------#
matplotlib.use("TkAgg") #backend of matplotlib??
style.use("dark_background")
LARGE_FONT = ("Times New Roman", 12)
NORM_FONT = ("Times New Roman", 9)
colors = ('tab:red','tab:blue')
#----------------------------------FUNCTION------------------------------------------------#
fig1 = plt.figure(0)
ax11 = fig1.add_subplot(211)
ax12 = ax11.twinx()
ax21 = fig1.add_subplot(212,sharex=ax11)
ax22 = ax21.twinx()
xList1= []
yList11=[]
yList12=[]
xList2= []
yList21=[]
yList22=[]
def animate_graph(i,x1,y11,y12,ax11
,ax12
,x2
,y21,y22,ax21,ax22
):
a = (2-1)*np.random.random()+1
b = (4-3)*np.random.random()+3
c = (6-5)*np.random.random()+5
d = (8-7)*np.random.random()+7
x1.append(dt.datetime.now().strftime('%H:%M:%S'))
y11.append(a)
y12.append(b)
x2.append(dt.datetime.now().strftime('%H:%M:%S'))
y21.append(c)
y22.append(d)
x1 = x1[-10:]
y11 = y11[-10:]
y12 = y12[-10:]
x2 = x2[-10:]
y21 = y21[-10:]
y22 = y22[-10:]
ax11.clear()
ln1 = ax11.plot(x1,y11,colors[0],label = 'Temp(C)')
ax11.tick_params(axis = 'y',labelcolor = colors[0])
ax12.clear()
ln2 = ax12.plot(x1,y12,colors[1],label = 'RH(%?)')
ax12.tick_params(axis = 'y',labelcolor = colors[1])
lns1 = ln1 + ln2
labs1 = [l.get_label() for l in lns1]
ax11.legend(lns1,labs1,bbox_to_anchor = (0,1.02,1,0.102),loc = 3,ncol = 3,borderaxespad = 0)
ax21.clear()
ln3 = ax21.plot(x2,y21,colors[0],label = 'CO(%)')
ax21.tick_params(axis = 'y',labelcolor = colors[0])
ax22.clear()
ln4 = ax22.plot(x2,y22,colors[1],label = 'CO2(%)')
ax22.tick_params(axis = 'y',labelcolor = colors[1])
lns2 = ln3 + ln4
labs2 = [l.get_label() for l in lns2]
ax21.legend(lns2,labs2,bbox_to_anchor = (0,1.02,1,0.102),loc = 3,ncol = 3,borderaxespad = 0)
ax11.tick_params(axis = 'x',labelrotation = 45)
ax21.tick_params(axis = 'x',labelrotation = 45)
#----------------------------------MAIN-------------------------------#
class main(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self,*args,**kwargs)
tk.Tk.title(self, "Hubba Dub")
container = tk.Frame(self)
container.pack(side = "top" , fill = "both" , expand = True)
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0,weight = 1)
menubar = tk.Menu(self,tearoff=0)
filemenu = menubar.add_command(label= "Exit", command=quit)
menubar.add_cascade(label="File",menu= filemenu)
playpausemenu = menubar.add_command(label= "Pause", command=0)
menubar.add_cascade(label = "Pause/Play",menu=playpausemenu)
self.frames = {}
for f in (StartPage,GraphAll):
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,control):
tk.Frame.__init__(self,parent)
label = ttk.Label(self,text = "StartPage", font = LARGE_FONT)
label.pack(pady = 10, padx = 10)
b1 = ttk.Button(self,text = "Open page to display sensor data", command = lambda: control.show_frame(GraphAll))
b1.pack()
b3 = ttk.Button(self,text = "Exit", command = quit)
b3.pack()
class GraphAll(tk.Frame):
def __init__(self,parent,control):
tk.Frame.__init__(self,parent)
label = ttk.Label(self,text = "Show All Readings",font = LARGE_FONT)
label.pack()
b1 = ttk.Button(self,text = "Pause", command = lambda: anim.event_source.stop())
b1.pack()
b2 = ttk.Button(self,text = "Play", command = lambda: anim.event_source.start())
b2.pack()
b3 = ttk.Button(self,text = "Exit",command= quit)
b3.pack()
canvas = FigureCanvasTkAgg(fig1,self)
canvas.draw()
canvas.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)
# call main class
gui = main()
# gui.geometry("1280x720")
gui.state('zoomed') #maximise window
anim = animation.FuncAnimation(fig1,animate_graph,
fargs=(xList1,yList11,yList12,ax11
,ax12
,xList2,yList21,yList22,ax21,ax22
)
,interval= 1000
)
#run in loop
gui.mainloop()
This is the graphing page. You can see the readings here are showing up correctly. The only issue is the x-axis readings are showing up on both instead of just one.
I thought by using sharex, it would show only show the x-axis on the bottom plot, rather than the top, but that didn't change anything, which is surprising to me because that should have worked.
I tried to use set_xticks set_xticks([]) but I don't see any change. Maybe I am not doing it right but I am not sure where the issue actually is.
I found out about get_xticklines() from this question but that doesn't seem to work either.
Any help is appreciated. Thanks.
I figured out the problem. So it turns out it was just lack of programming experience in python that was the issue.
I was following sentdex's youtube playlist on making a GUI. I found the answer to my problem there.
I added this line
plt.setp(ax21.get_xticklabels(),visible = False)in theanimate_graphfunction. The block of code shown below.Then I got this image . The legend for the second subplot needed to be moved, so I realised that the
bbox_to_anchorparameter in theax21.legend()should be changed to(0,-0.1,1,0). Now I get this image