【问题标题】:How to remove/clear the subplot and canvas (white window- FigureCanvasTkAgg) from matplotlib in Tkinter?如何从 Tkinter 的 matplotlib 中删除/清除子图和画布(白色窗口-FigureCanvasTkAgg)?
【发布时间】:2020-06-22 18:47:58
【问题描述】:

我正在尝试运行一个提供两个按钮的 gui。第一个打印文件“names.txt”的内容,第二个是绘制数据。但是,如果我先绘制数据然后再打印内容,则子图将保持原样,我无法清除它。这是我的输出: [![wrong_output][1]]1 我读了帖子:Clear figure subplots matplotlib python 并尝试了同样的方法,但是我没有得到正确的输出 次要情节并没有破坏。 我什至尝试使用self.scatter1.get_tk_widget().destroy()destroy 小部件,但这也不起作用 有人可以告诉我如何进行吗? 我的代码是:

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

【问题讨论】:

    标签: python python-3.x matplotlib tkinter subplot


    【解决方案1】:

    尝试用self.subplot1.clear() 代替self.subplot1.destroy()

    【讨论】:

      【解决方案2】:

      问题

      问题是由于在graph_plot 类的__init__() 方法中创建了多个FigureCanvasTkAgg 对象。这个构造函数在do_graph()do_printing() 方法中被调用,这意味着许多相同的画布正在彼此之上创建。这意味着当您.destroy() 小部件时,它将销毁一个新的小部件并将其留在下面。

      解决方案

      如果您要继续使用类,解决方案是将更多变量提升到全局变量中,这样可以确保您处理的是相同的对象,而不是单独的对象。不过,最好重新考虑完全使用类来解决这个问题。

      代码 我重组了您的一些代码以避开类并达到预期的结果:

      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()
      

      【讨论】:

      • 哦,谢谢。我错误地发布了错误的代码。我现在已经进行了必要的更新。
      • 通过该编辑,除了我的计算机上没有names.txt 文件之外,我可以正常运行代码
      • 我试过了,但仍然存在白色矩形(实际上是由于 canvas-FigureCanvasTkAgg)。如果您将行 input_File = open('names.txt','r') myLine = input_File.readlines() 替换为任何预定义列表,例如 ['john kenny', 'maria rose sheena', 'navier kate ramen'],那么您会看到此列表中的项目与白色窗口(画布)重叠
      • 好的,所以您希望在绘制绘图时保留名称(选项 2 按钮)而不是空白?
      • 没有。当我按下按钮时,我只想要名称。不能同时使用
      猜你喜欢
      • 2021-12-27
      • 1970-01-01
      • 2020-11-30
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2018-06-16
      • 1970-01-01
      相关资源
      最近更新 更多