Pyplot and Tkinter - Unwanted Extra Window - python

My code below creates an unwanted duplicate window when I try to add a window title using plt.figure().canvas.manager.set_window_title("Custom Title").
I've done some research and discovered that I am probably not supposed to be mixing pyplot and tkinter this way as they get confused. However I couldn't really make sense of the proposed solutions, some of which used something called FigureCanvasTkAgg which I don't know about. I want my plot to be freestanding, just as it is when I remove plt.figure().canvas.manager.set_window_title("Custom Title").
How can I refactor my code please to not violate any principles which my current code does and to remove the unwanted window?
import matplotlib.pyplot as plt
import tkinter as tk
import networkx as nx
NUM_ROWS = 5
BOLD_FONT = ("calbri", 12, "bold")
NORMAL_FONT = ("calbri", 12, "normal")
def create_widgets():
for i in range(NUM_ROWS):
key = chr(i + 65)
this_row = widgets[key] = {}
this_row["label"] = tk.Label(root, text=key, font=BOLD_FONT)
this_row["label"].grid(row=i, column=0, padx=5, pady=10)
this_row["factor_field"] = tk.Entry(root, width=60, font=NORMAL_FONT)
this_row["factor_field"].grid(row=i, column=1, padx=5, pady=10)
this_row["target_node_field"] = tk.Entry(
root, width=5, font=NORMAL_FONT)
this_row["target_node_field"].grid(row=i, column=2, padx=5, pady=10)
submit_button = tk.Button(root, text="Submit", command=submit,
font=BOLD_FONT).grid(row=NUM_ROWS + 1, column=0, padx=5, pady=10)
def submit():
plt.close()
G = nx.DiGraph()
edges = []
for key, row in widgets.items():
factor_field_contents = row["factor_field"].get()
target_node_field_contents = row["target_node_field"].get().upper()
if factor_field_contents != "" and target_node_field_contents != "":
edges.append((key, target_node_field_contents))
data[key] = {"factor": factor_field_contents,
"target_node": target_node_field_contents}
G.add_edges_from(edges)
# pos = nx.spring_layout(G, k=1.0, iterations=50)
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size=500, node_color="green")
nx.draw_networkx_labels(G, pos, font_color="white")
nx.draw_networkx_edges(
G, pos, connectionstyle='arc3, rad = 0.1', width=2, arrows=True)
plt.figure().canvas.manager.set_window_title("Custom Title")
plt.show()
if __name__ == "__main__":
data = {}
widgets = {}
root = tk.Tk()
root.title("My App")
create_widgets()
root.mainloop()

You said you found a solution in FigureCanvasTkAgg, but you don't understand it. You have to gain that understanding because it is literally the only way (according to my research). My example should get you started in that understanding. To be honest, I don't know anything, at all, about matplotlib. I just read the docs and fulfilled the requirements. It seems to work perfectly at creating a single window.
#import matplotlib.pyplot as plt #remove this, you can't use it anymore
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import tkinter as tk
import networkx as nx
NUM_ROWS = 5
BOLD_FONT = ("calbri", 12, "bold")
NORMAL_FONT = ("calbri", 12, "normal")
def create_widgets():
for i in range(NUM_ROWS):
key = chr(i + 65)
this_row = widgets[key] = {}
this_row["label"] = tk.Label(root, text=key, font=BOLD_FONT)
this_row["label"].grid(row=i, column=0, padx=5, pady=10)
this_row["factor_field"] = tk.Entry(root, width=60, font=NORMAL_FONT)
this_row["factor_field"].grid(row=i, column=1, padx=5, pady=10)
this_row["target_node_field"] = tk.Entry(
root, width=5, font=NORMAL_FONT)
this_row["target_node_field"].grid(row=i, column=2, padx=5, pady=10)
submit_button = tk.Button(root, text="Submit", command=submit,
font=BOLD_FONT).grid(row=NUM_ROWS + 1, column=0, padx=5, pady=10)
#this is your single window
#I'm sure some of this could be made just once and reused
#I'm also sure this could be made more dynamic
#At least you have the multi-window part solved
def plotter():
global plotwin
plotwin = tk.Toplevel(root)
fig = Figure(figsize=(5,5), dpi=100)
fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig, plotwin)
canvas._tkcanvas.pack(fill='both', expand=True)
NavigationToolbar2Tk(canvas, plotwin, pack_toolbar=True).update()
def submit():
try:
#if plotter() hasn't been called yet this will throw a NameError
#we simply catch and ignore it
plotwin.destroy()
except NameError as e:
pass
G = nx.DiGraph()
edges = []
for key, row in widgets.items():
factor_field_contents = row["factor_field"].get()
target_node_field_contents = row["target_node_field"].get().upper()
if factor_field_contents != "" and target_node_field_contents != "":
edges.append((key, target_node_field_contents))
data[key] = {"factor": factor_field_contents,
"target_node": target_node_field_contents}
G.add_edges_from(edges)
# pos = nx.spring_layout(G, k=1.0, iterations=50)
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size=500, node_color="green")
nx.draw_networkx_labels(G, pos, font_color="white")
nx.draw_networkx_edges(G, pos, connectionstyle='arc3, rad = 0.1', width=2, arrows=True)
#instantiate window
plotter()
if __name__ == "__main__":
data = {}
widgets = {}
root = tk.Tk()
root.title("My App")
create_widgets()
root.mainloop()

Related

Upload txt file to draw xy graph python

my name is Vo Minh Hoang. I wrote a Python program to upload file to draw graph but i have one problem which is the button to draw graph. Please help me and thank you very much. I send an image which is an example I want to complete the program.
from tkinter import *
from tkinter import filedialog
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
# functions
def openFile():
tf = filedialog.askopenfilename(
initialdir="C:/Users/MainFrame/Desktop/",
title="Open Text file",
filetypes=(("Text Files", "*.txt"),)
)
pathh.insert(END, tf)
tf = open(tf)
file_cont = tf.read()
txtarea.insert(END, file_cont)
tf.close()
def Draw():
tf = plt.figure(
mode='w',
title ="Draw",
ax = plt.subplots()
plt.subplots_adjust(left=0.3, bottom=0.25)
X, Y = np.loadtxt('data.txt', delimiter=',', unpack=True)
p, = ax.plot(X, Y, color="blue", marker="o")
print(X, Y)
)
tf.config(mode='w')
pathh.insert(END, tf)
data = str(txtarea.get(1.0, END))
tf.write(data)
tf.close()
ws = Tk()
ws.title("PythonGuides")
ws.geometry("400x500")
ws['bg']='#2a636e'
# adding frame
frame = Frame(ws)
frame.pack(pady=20)
# adding scrollbars
ver_sb = Scrollbar(frame, orient=VERTICAL )
ver_sb.pack(side=RIGHT, fill=BOTH)
hor_sb = Scrollbar(frame, orient=HORIZONTAL)
hor_sb.pack(side=BOTTOM, fill=BOTH)
# adding writing space
txtarea = Text(frame, width=40, height=20)
txtarea.pack(side=LEFT)
# binding scrollbar with text area
txtarea.config(yscrollcommand=ver_sb.set)
ver_sb.config(command=txtarea.yview)
txtarea.config(xscrollcommand=hor_sb.set)
hor_sb.config(command=txtarea.xview)
# adding path showing box
pathh = Entry(ws)
pathh.pack(expand=True, fill=X, padx=10)
# adding buttons
Button(
ws,
text="Open File",
command=openFile
).pack(side=LEFT, expand=True, fill=X, padx=20)
Button(
ws,
text="Draw",
command=Draw
).pack(side=LEFT, expand=True, fill=X, padx=20)
Button(
ws,
text="Exit",
command=lambda:ws.destroy()
).pack(side=LEFT, expand=True, fill=X, padx=20, pady=20)
ws.mainloop()
This is the code I try to complete
I tried to find in the Internet but it didn't work.
enter image description here

update pi_graph values in FigureCanvasTkAgg without destroying the frame

I am creating a pi graph where the data will be passed dynamically so created a method to pass variables so that it displays image on canvas but, I am not able to update data of canvas data , so should every time need to destroy the frame and create the total process again so
from tkinter import *
import numpy as np
import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
root = Tk()
root.geometry("500x500")
root.title("Pi Graph")
cash = IntVar()
credit = IntVar()
pi_frame_main = Frame(root)
pi_frame_main.pack(side="bottom", expand=True, fill="both")
def plot(cash_amount, credit_amount):
pi_frame = Frame(pi_frame_main, height=300, borderwidth=4)
def func(pct, values):
"""calculating the percentage of the values"""
absolute = int(pct / 100.0 * np.sum(values))
return "{:.1f}%\n({:d})".format(pct, absolute)
if cash_amount != 0 or credit_amount != 0:
# create frame for plotting
pi_frame.pack(side='right', padx=10, pady=10, fill='y')
my_dict = {'NAME': ['Cash', 'Credit'], 'Nos': [cash_amount, credit_amount]}
print(my_dict)
df = pd.DataFrame(data=my_dict)
lbl = ['Cash', 'Credit']
explode = [0.0, 0.1]
fig1 = df.plot.pie(title="Cash & Credit", y='Nos', autopct=lambda pct: func(pct, my_dict['Nos']),
explode=explode, figsize=(3,3), labels=lbl, shadow=True,
legend=False).get_figure()
fig1.legend(lbl, bbox_to_anchor=(0.75, 1), loc="upper left")
plot1 = FigureCanvasTkAgg(fig1, pi_frame)
plot1.get_tk_widget().pack(side='right', fill='y')
Entry(root, textvariable=cash).pack(side="left", padx=5)
Entry(root, textvariable=credit).pack(side="left", padx=5)
Button(root, text="Plot", command=lambda: plot(cash.get(), credit.get())).pack(side="right", padx=5)
root.mainloop()
needed some guidance how to update the the pi graph without destroying the frame

How to implement a scrollbar to grid in tkinter

I have a hard time implementing a scrollbar into my Tkinter project. I've been through numerous articles and answered questions on how to implement a scrollbar, but I'm just unable to implement a working solution after an entire day of researching this one 'simple' matter.
My current code looks like this:
import tkinter as tk
from tkinter import Button, ttk
from PIL import ImageTk, Image
from functools import partial
import queue as qu
import math
import re
import os
window = tk.Tk()
queue = qu.Queue()
#Basic values
#the window size
windowSize = "700x1000"
#picture and container size
x, y = 200, 300
#tmp
sidepanelsize = 200
window.geometry(windowSize)
#button identifier
def change(i):
print(I)
#temporary content generator
for g in range(12):
for item in os.listdir("."):
if re.search(r"\.(jpg|png)$", item):
queue.put(item)
n = queue.qsize()
#other panels that are going to be used later
frameLeft = tk.Frame(master=window, width=sidepanelsize, relief=tk.RIDGE)
frameLeft.pack(fill=tk.Y, side=tk.LEFT)
label1 = tk.Label(master=frameLeft, text="Left Panel")
label1.pack()
buttonLeft1 = tk.Button(master=frameLeft, text="Button 1", command=lambda: print("I'm a side button!"))
buttonLeft1.pack()
frameMain = tk.Frame(master=window, relief=tk.GROOVE, borderwidth=1)
frameMain.pack(side=tk.TOP, fill=tk.X, expand=1)
# SCROLLBAR IF YOU DISABLE THIS SECTION AND PUTS SOME PICTURES IN THE FOLDER WHITH THE FILE THE CODE WORKS #
myCanvas = tk.Canvas(master=frameMain)
myCanvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
myScrollbar = ttk.Scrollbar(master=frameMain, orient=tk.VERTICAL, command=myCanvas.yview)
myScrollbar.pack(side=tk.RIGHT, fill=tk.Y)
myCanvas.configure(yscrollcommand=myScrollbar.set)
myCanvas.bind('<Configure>', lambda e: myCanvas.configure(scrollregion=myCanvas.bbox("all")))
secondFrame = tk.Frame(master=myCanvas)
myCanvas.create_window((0, 0), window=secondFrame, anchor=tk.NW)
############################ END OF SCROLLBAR ############################
noOfImgPerRow = math.floor((int(windowSize.split("x")[0])-sidepanelsize+100)/x)
imgs = []
#generates the grid
for i in range(n):
o = i
i = (o % noOfImgPerRow) + 1
j = math.floor(o/noOfImgPerRow) + 1
frameMain.columnconfigure(i, weight = 1, minsize=x+15)
frameMain.rowconfigure(i, weight = 1, minsize=y+50)
frameBox = tk.Frame(
master=frameMain,
relief=tk.RAISED,
borderwidth=1,
width = x,
height = y
)
# here the error references to
frameBox.grid(row=j, column=i, padx=5, pady=5)
img = Image.open(queue.get()).convert("RGBA")
width, height = img.size
if width/x >= height/y:
left = width/2-(round((height*x)/y))/2
right = width/2+(round((height*x)/y))/2
upper = 0
lower = height
else:
left = 0
right = width
upper = height/2-(round((width*y)/x))/2
lower = height/2+(round((width*y)/x))/2
img2 = img.crop([left, upper, right, lower])
img2 = img2.resize((x, y), Image.Resampling.LANCZOS)
imgs.append(ImageTk.PhotoImage(img2))
label = tk.Label(master = frameBox, image = imgs[-1])
label.pack()
mainButton = Button(master=frameBox, text="Start", command=partial(change, o))
mainButton.pack()
window.mainloop()
I've tried to highlight the only thing of concern, that being the scrollbar, everything else is working at the moment, I just wanted to post the whole code for better understanding if it would help in any way.
My problem is whenever I implement the scrollbar, it throws back an error stating:
Traceback (most recent call last):
File "e:\Python\starter\main.py", line 85, in <module>
frameBox.grid(row=j, column=i, padx=5, pady=5)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1264.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2522, in grid_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager grid inside .!frame2 which already has slaves managed by pack
This error seems pretty self-explanatory, just grid the canvas instead of packing it, but when after a lot of small tweaking and doing things a roundabouts things
My second thought was if it has a problem with the grid to wrap the gridded frame in another bigger packed frame, like so:
yetAnotherFrame = tk.Frame(frameMain)
yetAnotherFrame.pack()
noOfImgPerRow = math.floor((int(windowSize.split("x")[0])-sidepanelsize+100)/x)
imgs = []
for i in range(n):
o = i
i = (o % noOfImgPerRow) + 1
j = math.floor(o/noOfImgPerRow) + 1
yetAnotherFrame.columnconfigure(i, weight = 1, minsize=x+15)
yetAnotherFrame.rowconfigure(i, weight = 1, minsize=y+50)
frameBox = tk.Frame(
master=yetAnotherFrame,
relief=tk.RAISED,
borderwidth=1,
width = x,
height = y
)
frameBox.grid(row=j, column=i, padx=5, pady=5)
This actually runs to my surprise, but the scrollbar still isn't working and the layout is broken again.
Solution
In your code frameBox's parent is frameMain. Instead you need to have the canvas as parent or the secondFrame which have the canvas as its parent.
Example
This is basically your code with fixes, but some of the unnecessary parts are removed.
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.geometry("400x400")
frameLeft = tk.Frame(master=window, width=400, height=400, relief=tk.RIDGE)
frameLeft.pack(fill=tk.Y, side=tk.LEFT)
myCanvas = tk.Canvas(master=frameLeft)
myCanvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
myScrollbar = ttk.Scrollbar(master=frameLeft, orient=tk.VERTICAL, command=myCanvas.yview)
myScrollbar.pack(side=tk.RIGHT, fill=tk.Y)
myCanvas.configure(yscrollcommand=myScrollbar.set)
myCanvas.bind('<Configure>', lambda e: myCanvas.configure(scrollregion=myCanvas.bbox("all")))
secondFrame = tk.Frame(master=myCanvas)
myCanvas.create_window((0, 0), window=secondFrame, anchor=tk.NW)
for i in range(100):
lbl = tk.Label(secondFrame, text=f"Label {i}")
lbl.grid(column=0, row=i, sticky=tk.W)
window.mainloop()

Add/change/remove elements in tkinter when specific dropdown menu item is selected

So I am trying to create a "programme" where you can click a calculate button, and then it will calculate and show a plot of some data that are dependent on some options a user chooses, i.e. dropdown menus, input fields, etc.
I have the following code:
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
from tkinter import *
import tkinter.ttk
import numpy as np
import matplotlib.pyplot as plt
class MainPlot:
def __init__(self, frame1):
self.frame1 = frame1
self.frame1a = Frame(frame1)
self.frame1a.pack(side=LEFT, fill=Y, padx=20, pady=20)
self.frame1b = Frame(frame1)
self.frame1b.pack(side=RIGHT, fill=BOTH, expand=True)
options2 = ["var1", "var2", "var3"]
self.variable2 = StringVar()
self.variable2.set("var1") # default value
self.w2 = OptionMenu(self.frame1a, self.variable2, *options2)
self.w2.grid(row=0, column=0, sticky=NW, ipadx=5)
# Variables
if self.variable2.get() == "var1":
self.equipment = {"var11": False,
"var12": True,
"var13": True,
"var14": True
}
elif self.variable2.get() == "var2":
self.equipment = {"var21": False,
"var22": True,
"var23": False
}
# Available nodes
self.available_nodes = Label(self.frame1a, text="Available nodes:")
self.available_nodes.grid(row=1, column=0, sticky=NW, pady=(10, 0))
self.CheckVar, self.C = dict(), dict()
for i, (key, value) in enumerate(self.equipment.items()):
self.CheckVar[key] = IntVar(self.frame1a)
self.CheckVar[key].set(value)
self.C[key] = Checkbutton(self.frame1a, text = key, variable=self.CheckVar[key], onvalue = True, offvalue = False, command=lambda: self.equipment[key].__setitem__(1, self.CheckVar[key].get()))
self.C[key].grid(row=2+i, column=0, sticky=NW)
# Separator
tkinter.ttk.Separator(self.frame1a, orient=HORIZONTAL).grid(column=0, row=3+len(self.equipment), rowspan=1, sticky='we', pady=15, padx=5)
# Calculate button
self.button1 = Button(self.frame1a, text="Calculate")
self.button1.grid(row=4+len(self.equipment), column=0, sticky=N, ipady=5, ipadx=10, padx=2)
if __name__ == '__main__':
root = Tk(className='Testing')
root.geometry("1920x1080")
aframe = Frame(root)
mainplot = MainPlot(aframe)
aframe.pack(side=LEFT, expand=True, fill=BOTH)
root.mainloop()
What I would like to do is that when I select a different option in the dropdown menu, the resulting checkboxes (created from the if, elif statements and dictionaries at # Variables) changes accordingly.
How can this be achieved ?

Tkinter Label not being updated with textvariable

In my code I see that the Label is not being updated with the 'textvariable', despite I believe I'm doing it right (probably not!).
varmuTemperature = StringVar(value="default value")
self.Label = Label(Frame2, textvariable = varmuTemperature)
self.Label.pack()
This should show a label with "default value" written on it. The problem is that I don't see anything written.
I have my code posted here.
import matplotlib
import matplotlib.artist as artists
import matplotlib.pyplot as plt
#import matplotlib.mlab as mlab
import scipy.stats
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,
NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
import numpy as np
import statistics
from tkinter import *
from tkinter import ttk
import serial
import time
import itertools
integer=0
xList = []
humidityList = []
humidityListHistogram = []
temperatureList = []
temperatureListHistogram = []
cnt=0
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
ser = serial.Serial()
style.use("seaborn-whitegrid")
#varmuTemperature = StringVar()
#varmuHumidity = StringVar()
f=plt.figure(0, figsize=(20,10))
humidityGraph = plt.subplot(224)
humidityGraph.set_title("Humidity vs Time")
humidityGraph.set_ylabel("Humidity RAW (Dec)")
humidityGraph.set_xlabel("Sample ()")
temperatureGraph = plt.subplot(223)
temperatureGraph.set_title("Temperature vs Time")
temperatureGraph.set_ylabel("Temperature RAW (Dec)")
temperatureGraph.set_xlabel("Sample ()")
humidityGraphHistogram = plt.subplot(222)
temperatureGraphHistogram = plt.subplot(221)
temperatureGraphHistogramNormal = temperatureGraphHistogram.twinx()
humidityGraphHistogramNormal = humidityGraphHistogram.twinx()
side_text = plt.figtext(0.93, 0.5, 'Text 1'+'\n'+'Text 2', bbox=dict(facecolor='white'))
plt.subplots_adjust(left = 0.05, right = 0.95, bottom = 0.05, top = 0.95, wspace = 0.16, hspace = 0.21)
class make_window():
def __init__(self, *args, **kwargs):
win = Tk()
win.title("Test")
win.state("zoomed")
Frame1 = Frame(win)
Frame1.pack()
self.comboBoxAvailableCOMPort = ttk.Combobox(Frame1, width = 30)
self.comboBoxAvailableCOMPort['values'] = []
self.comboBoxAvailableCOMPort.pack(padx=5, pady=5, side = LEFT)
self.buttonCheckComAvailable = Button(Frame1, text="Check COM Available", command = self.CheckComAvailable)
self.buttonCheckComAvailable.pack(padx=5, pady=10, side = LEFT)
self.buttonOpenCOMPort = Button(Frame1, text="Open COM Port", command = self.OnOpenCom)
self.buttonOpenCOMPort.pack(padx=5, pady=10, side = LEFT)
self.buttonCloseCOMPort = Button(Frame1, text="Close COM Port" , command = self.OnCloseCOM)
self.buttonCloseCOMPort.pack(padx=5, pady=10,side = LEFT)
self.CheckComAvailable()
Frame2 = Frame(win, highlightbackground = "red", highlightcolor = "red", highlightthickness = 1)
Frame2.pack()
varmuTemperature = StringVar(value="default value")
varmuTemperature.set("trerta")
print(varmuTemperature.get())
self.Label = Label(Frame2, textvariable = varmuTemperature)
self.Label.pack()
self.buttonCloseProgram = Button(Frame2, text="Close Program", command = self.OnCloseProgram)
self.buttonCloseProgram.pack(expand=True, fill='x', anchor='s')
Frame3 = Frame(win)
Frame3.pack()
canvas = FigureCanvasTkAgg(f, Frame3)
canvas.get_tk_widget().pack(padx=5, pady=10, side=BOTTOM, expand = True)
toolbar = NavigationToolbar2Tk(canvas, Frame3)
toolbar.update()
canvas._tkcanvas.pack(padx=5, pady=10,side = TOP)
def CheckComAvailable(self):
self.comboBoxAvailableCOMPort['values'] =[]
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
self.comboBoxAvailableCOMPort['values'] += tuple(result)
self.comboBoxAvailableCOMPort.set(result[0])
def OnOpenCom(self):
ser.baudrate = 115200
ser.port = self.comboBoxAvailableCOMPort.get()
try:
ser.open()
ser.readline()
ser.write("#dut,0$\n".encode('utf-8'))
ser.readline()
ser.write("#v,1800,1800$\n".encode('utf-8'))
ser.write("#W,77,08,07$\n".encode('utf-8'))
ser.readline()
except(OSError):
print("COM Port in use")
def OnCloseCOM(self):
global xList
global humidityList
global temperatureList
global humidityListHistogram
global temperatureListHistogram
global integer
integer=0
xList = []
humidityList = []
temperatureList = []
ser.close()
def OnCloseProgram(self):
self.OnCloseCOM()
exit()
## def toggle_geom(self,event):
## geom=self.master.winfo_geometry()
## print(geom,self._geom)
## self.master.geometry(self._geom)
## self._geom=geom
def animate(i):
global integer
global cnt
try:
ser.write(("#R,77,00,03$" + chr(10)).encode('utf-8'))
humidityLine=ser.readline()
inthumidityLine= int(humidityLine,16)
if (inthumidityLine > 8388608):
inthumidityLine = inthumidityLine - 16777216
humidityList.append(inthumidityLine)
humidityListHistogram.append(inthumidityLine)
ser.write(("#R,77,03,03$" + chr(10)).encode('utf-8'))
temperatureLine=ser.readline()
LineHistogram = temperatureLine
inttemperatureLine= int(temperatureLine,16)
if (inttemperatureLine > 8388608):
inttemperatureLine = inttemperatureLine - 16777216
temperatureList.append(inttemperatureLine)
temperatureListHistogram.append(inttemperatureLine)
xList.append(integer)
integer+=1
##################################################################################################################
## Creates the HUMIDITY Graphics
##################################################################################################################
humidityGraph.clear()
humidityGraph.plot(xList,humidityList,'-b*', label = "Humidity RAW")
humidityGraph.legend(loc='upper right', fancybox = True, frameon = True, shadow = True)
humidityGraph.set_title("Humidity vs Time")
humidityGraph.set_ylabel("Humidity RAW (Dec)")
humidityGraph.set_xlabel("Sample ()")
muHumidity = statistics.mean(humidityListHistogram)
#print("Mean = " + str(muHumidity) + " ; N = " + str(len(humidityListHistogram)))
#global varmuHumidity
#varmuHumidity.set("Humidity: ")
if (len(humidityListHistogram) > 1):
sigmaHumidity = statistics.pstdev(humidityListHistogram)
else:
sigmaHumidity = 100
humidityGraphHistogram.clear()
nHumidity, binsHumidity, patchesHumidity = humidityGraphHistogram.hist(humidityListHistogram, 100, density=False, facecolor='blue', alpha=0.75, histtype = 'stepfilled')
normalDistHumidity = scipy.stats.norm.pdf(binsHumidity, muHumidity, sigmaHumidity)
humidityGraphHistogramNormal.clear()
humidityGraphHistogramNormal.plot(binsHumidity, normalDistHumidity, 'r--')
humidityGraphHistogram.set_title("Histogram for Humidity Data")
humidityGraphHistogram.set_ylabel("Humidity RAW Counts (Dec)")
humidityGraphHistogram.set_xlabel("BINS ()")
humidityGraphHistogramNormal.set_ylabel("Normal Distribution")
##################################################################################################################
## Creates the TEMPERATURE Graphics
##################################################################################################################
temperatureGraph.clear()
temperatureGraph.plot(xList,temperatureList,'-r*', label = "Temperature RAW")
temperatureGraph.legend(loc='upper right', fancybox = True, frameon = True, shadow = True)
temperatureGraph.set_title("Temperature vs Time")
temperatureGraph.set_ylabel("Temperature RAW (Dec)")
temperatureGraph.set_xlabel("Sample ()")
muTemperature = statistics.mean(temperatureListHistogram)
#global varmuTemperature
#varmuTemperature.set("Temperature: " )
if (len(temperatureList) > 1):
sigmaTemperature = statistics.pstdev(temperatureListHistogram)
else:
sigmaTemperature = 100
temperatureGraphHistogram.clear()
nTemperature, binsTemperature, patchesTemperature = temperatureGraphHistogram.hist(temperatureListHistogram, 100, density=False, facecolor='red', alpha=0.75, histtype = 'stepfilled')
normalDistTemperature = scipy.stats.norm.pdf(binsTemperature, muTemperature, sigmaTemperature)
temperatureGraphHistogramNormal.clear()
temperatureGraphHistogramNormal.plot(binsTemperature, normalDistTemperature, 'b--')
temperatureGraphHistogram.set_title("Histogram for Temperature Data")
temperatureGraphHistogram.set_ylabel("Temperature RAW Counts (Dec)")
temperatureGraphHistogram.set_xlabel("BINS ()")
temperatureGraphHistogramNormal.set_ylabel("Normal Distribution")
if (cnt > 100):
xList.pop(0)
humidityList.pop(0)
temperatureList.pop(0)
cnt+=1
except(OSError):
bla=0
win = make_window()
ani = animation.FuncAnimation(f, animate, interval = 300)
make_window.mainloop()
Debugging a bit and start commenting lines of code, I see that the problem may come from the
f=plt.figure(0, figsize=(20,10))
Commenting this line (and all dependencies of this) makes the Label to be written.
Can someone help here, please? I don't get why the graphics can interfere in the Label.
Thanks a lot.
The general problem seems to be your management of instance variables and objects. You keep around as self.* variables, things you'll never need to reference again, like buttonCheckComAvailable, but fail to make self.* variables for things, like varmuTemperature, that you will need to reference later.
Object-wise, you do things that don't make sense:
make_window.mainloop()
as make_window is an object class, not an instance, and an instance of the class make_window won't respond to mainloop anyway as it contains a window but isn't one itself.
Here's my MCVE for your example code that makes varmuTemperature an instance variable and, just for demonstration purposes, sets it when the various buttons on the interface are clicked so you can see it's working:
from tkinter import *
from tkinter import ttk
class make_window():
def __init__(self):
self.win = Tk()
self.win.title("Test")
self.win.state("zoomed")
Frame1 = Frame(self.win)
self.comboBoxAvailableCOMPort = ttk.Combobox(Frame1, width=30)
self.comboBoxAvailableCOMPort['values'] = []
self.comboBoxAvailableCOMPort.pack(padx=5, pady=5, side=LEFT)
Button(Frame1, text="Check COM Available", command=self.CheckComAvailable).pack(padx=5, pady=10, side=LEFT)
Button(Frame1, text="Open COM Port", command=self.OnOpenCom).pack(padx=5, pady=10, side=LEFT)
Button(Frame1, text="Close COM Port", command=self.OnCloseCom).pack(padx=5, pady=10, side=LEFT)
Frame1.pack()
Frame2 = Frame(self.win, highlightbackground="red", highlightcolor="red", highlightthickness=1)
self.varmuTemperature = StringVar(value="default value")
Label(Frame2, textvariable=self.varmuTemperature).pack()
Button(Frame2, text="Close Program", command=self.OnCloseProgram).pack(expand=True, fill='x', anchor='s')
Frame2.pack()
def CheckComAvailable(self):
self.varmuTemperature.set("CheckCom")
def OnOpenCom(self):
self.varmuTemperature.set("OpenCom")
def OnCloseCom(self):
self.varmuTemperature.set("CloseCom")
def OnCloseProgram(self):
self.OnCloseCom()
exit()
window = make_window()
window.win.mainloop()

Categories