I'm trying to run a gui where I'm providing two buttons. 1st one to print content of the file 'names.txt' and 2nd is to plot the data. However, if I'm plotting data first and then going to print the content, the subplot is remaining as it is and I'm unable to clear it. Here is my output: [:[wrong_output][1]]1 I read the post : Clear figure subplots matplotlib python and tried the same, however I'm not getting correct output And the subplot is not destroying. I even tried to destroy
the widget using self.scatter1.get_tk_widget().destroy()
but this isnt working either Can someone please tell me how to proceed? My code is:
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import random
x_loc=[5, 6, 34, 54, 23]
y_loc=[3, 4.34, 2, 44, 65]
avgLst=[24, 35.65, 54.6, 53, 2]
root= tk.Tk()
class graph_plot():
global graph_past
global graph_Avg
def __init__(self):
self.figure1 = plt.Figure()
self.scatter1 = FigureCanvasTkAgg(self.figure1, root)
self.scatter1.get_tk_widget().place(relx= 0.5, rely=0.1)
self.subplot1 = self.figure1.add_subplot(111)
self.subplot1.set_xlabel('x location')
self.subplot1.set_ylabel('y location')
def display_graph(self):
data1 = {'x-locations' : x_loc , 'y_locations' : y_loc}
df3 = DataFrame(data1,columns=['x-locations','y_locations'])
global graph_past
label2.config(text='')
print('graph in= ' , graph_past)
im0= self.subplot1.scatter(df3['x-locations'],df3['y_locations'], c=avgLst, cmap='rainbow', vmin=min(avgLst), vmax=max(avgLst))
self.figure1.colorbar(im0)
self.subplot1.set_title('Avg')
graph_past= True
def clear_graph(self):
print('Destroyed!')
self.subplot1.clear
## ??? which command
def do_graph():
obj1 = graph_plot()
obj1.display_graph()
def on_key(event):
if myLine and event.keysym != 'Return':
update_print()
def do_printing():
global myLine
global graph_past
#print('graph_past= ' , graph_past)
if graph_past:
obj2 = graph_plot()
obj2.clear_graph()
graph_past = False
input_File = open('names.txt','r')
myLine = input_File.readlines()
update_print()
def update_print():
label2.config(text=random.choice(myLine))
def flag_print():
global graph_Avg
graph_Avg=False
do_printing()
def flag_Avg():
global graph_Avg
graph_Avg=True
do_graph()
root.bind('<Key>', on_key)
myCanvas = tk.Canvas(root, width = 800, height = 500)
myCanvas.grid(row=2, column= 4)
label1 = tk.Label(root, text='MENU')
label1.config(font=('Arial', 20))
myCanvas.create_window(200, 20, window=label1)
myLine= None
graph_Avg=False
graph_past=False
label2 = tk.Label(root, font=('Courier', 15))
label2.place(relx= 0.3, rely=0.1)
B1 = tk.Button(root, text ="Option 1", font=('Courier', 12), command = flag_print)
myCanvas.create_window(200, 100, window=B1)
B2 = tk.Button(root, text ="Option 2", font=('Courier', 12), command = flag_Avg)
myCanvas.create_window(200, 140, window=B2)
root.mainloop()```
[1]: https://i.stack.imgur.com/RgL7S.png
Try self.subplot1.clear()
in the place of self.subplot1.destroy()
Problem
The problem is due to creating multiple FigureCanvasTkAgg
objects in the __init__()
method of the graph_plot
class. this constructor is called in the do_graph()
and do_printing()
methods which means many of the same canvas are being created on top of one another. This means when you .destroy()
the widget it will be destroying a new one and leaving the one underneath.
Solution
The solution would be to hoist more variables up into global variables if you're going to continue using classes and that way you'll be ensured you're handling the same objects, not separate ones. It might be best to rethink the use of classes for this problem entirely though.
Code I restructured some of your code to eschew classes and achieve the desired results:
import tkinter as tk
import matplotlib.pyplot as plt
from pandas import DataFrame
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import random
x_loc=[5, 6, 34, 54, 23]
y_loc=[3, 4.34, 2, 44, 65]
avgLst=[24, 35.65, 54.6, 53, 2]
GRAPH_AVG=False
GRAPH_PAST=False
MY_LINE = None
ROOT = tk.Tk()
ROOT.geometry("900x600")
FIGURE = plt.Figure()
SCATTER = FigureCanvasTkAgg(FIGURE, ROOT)
TK_WIDGET = SCATTER.get_tk_widget()
SUBPLOT = FIGURE.add_subplot(111)
SUBPLOT.set_xlabel('x location')
SUBPLOT.set_ylabel('y location')
NAME_LABEL = tk.Label(ROOT, font=('Courier', 15))
NAME_LABEL.place(relx=0.3, rely=0.1)
def display_graph():
global GRAPH_PAST, FIGURE, SUBPLOT
data1 = {'x-locations' : x_loc , 'y_locations' : y_loc}
df3 = DataFrame(data1, columns=['x-locations','y_locations'])
NAME_LABEL.config(text='')
print('graph past= ' , GRAPH_PAST)
im0= SUBPLOT.scatter(df3['x-locations'],df3['y_locations'], c=avgLst, cmap='rainbow', vmin=min(avgLst), vmax=max(avgLst))
FIGURE.colorbar(im0)
SUBPLOT.set_title('Avg')
TK_WIDGET.place(relx=0.3, rely=0.1)
GRAPH_PAST= True
def clear_graph():
global SUBPLOT, TK_WIDGET
print('Destroyed!')
SUBPLOT.clear()
TK_WIDGET.place_forget()
def on_key(event):
global MY_LINE
if MY_LINE and event.keysym != 'Return':
update_print()
def do_printing():
global MY_LINE, GRAPH_AVG, GRAPH_PAST
if GRAPH_PAST:
clear_graph()
GRAPH_PAST = False
MY_LINE = ["john kenny", "maria rose", "sheena"]
update_print()
def update_print():
NAME_LABEL.config(text=random.choice(MY_LINE))
def flag_print():
global GRAPH_AVG
GRAPH_AVG=False
do_printing()
def flag_Avg():
global GRAPH_AVG
GRAPH_AVG=True
display_graph()
ROOT.bind('<Key>', on_key)
B1 = tk.Button(ROOT, text ="Print", font=('Courier', 12), command=flag_print)
B1.place(relx=0.1, rely=0.1)
B2 = tk.Button(ROOT, text ="Graph", font=('Courier', 12), command=flag_Avg)
B2.place(relx=0.1, rely=0.2)
ROOT.mainloop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.