【问题标题】:How to make Tkinter GUI only plot Matplotlib figure once如何使 Tkinter GUI 只绘制一次 Matplotlib 图
【发布时间】:2020-12-25 23:35:22
【问题描述】:

我有一些制作 4tabbed gui 的 Tkinter 代码。在 GUI tab2 中有一个按钮来绘制一个简化的图形,它可以工作,但是当我再次单击该按钮时,它会重新打印画布并直接在第一个图下方绘制图形。我已经查看了如何使用关闭或清除按钮删除绘图,但确实需要它只绘制一次(即使再次单击该按钮)。

代码

import tkinter as tk                     
from tkinter import ttk 
import matplotlib
matplotlib.use("TkAgg")  # this is the backend of matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style


root = tk.Tk() 
root.title("Tab Widget")
root.geometry("1300x950") 
tabControl = ttk.Notebook(root) 
  
tab1 = ttk.Frame(tabControl) 
tab2 = ttk.Frame(tabControl)
tab3 = ttk.Frame(tabControl) 
tab4 = ttk.Frame(tabControl) 
  
tabControl.add(tab1, text ='Tab 1') 
tabControl.add(tab2, text ='Tab 2')
tabControl.add(tab3, text ='Tab 3')
tabControl.add(tab4, text ='Tab 4')


tabControl.pack(expand = 1, fill ="both") 
  
ttk.Label(tab1, text ="This is a  tab\n (1)").grid(column = 0, row = 0, padx = 30, pady = 30)   
ttk.Label(tab2, text ="This is another tab\n (2)").grid(column = 0, row = 0,  padx = 30, pady = 30) 
ttk.Label(tab3, text ="This is another tab\n (3)").grid(column = 0, row = 0,  padx = 30, pady = 30) 
ttk.Label(tab4, text ="This is another tab\n (4)").grid(column = 0, row = 0,  padx = 30, pady = 30)  


label_b1 = ttk.Label(tab1, text = "Button label 0,1").grid(column = 0, row = 1, padx = 30, pady = 30)
label_b1 = ttk.Label(tab1, text = "Button label 1,1").grid(column = 1, row = 1, padx = 30, pady = 30)
label_b1 = ttk.Label(tab1, text = "Button label 1,2").grid(column = 2, row = 1, padx = 30, pady = 30)


def plot(): 
    # the figure that will contain the plot 
    fig = Figure(figsize = (5, 5), dpi = 100) 
     
    y = [i**2 for i in range(101)] # list of squares
    
    # adding the subplot 
    plot1 = fig.add_subplot(111) 
    # plotting the graph 
    plot1.plot(y) 
    canvas = FigureCanvasTkAgg(fig, master = tab2)  # creating the Tkinter canvas containing the Matplotlib figure  
    canvas.draw() 
    canvas.get_tk_widget().grid()  # placing the canvas on the Tkinter window 


plot_button = tk.Button(master = tab2,  command = plot, height = 2,  width = 10, text = "Plot") 
plot_button.grid()   # place the button in main window 
root.mainloop() 

期望的输出

再次按下 Plot 按钮不会导致图表出现在第一个绘图下方。

来自 xszym 的想法

was_plotted = False

def plot():
    global was_plotted
    if(was_plotted) == False:
            # the figure that will contain the plot 
        fig = Figure(figsize = (5, 5), dpi = 100) 
        
        y = [i**2 for i in range(101)] # list of squares
        
        # adding the subplot 
        plot1 = fig.add_subplot(111) 
        # plotting the graph 
        plot1.plot(y) 
        canvas = FigureCanvasTkAgg(fig, master = tab2)  # creating the Tkinter canvas containing the Matplotlib figure  
        canvas.draw() 
        canvas.get_tk_widget().grid()  # placing the canvas on the Tkinter window 

        
        was_plotted = True

【问题讨论】:

  • 关键是复用同一个canvas对象,但不要每次执行plot函数时都创建一个新对象。
  • 我不知道该怎么做,我现在可以看到如何使用 xszym 提到的标志设置。
  • 该标志与重用同一个对象没有任何关系。只需将您的 canvas 创建和 grid 方法移到您的函数之外,当您 plot 它时,清除画布并在其上绘图。如果您仍然无法弄清楚,请查看this
  • 您好,Henry Yik,我采用了您的想法并且成功了,如果您将您的评论作为答案转发,我将很乐意接受。

标签: python matplotlib tkinter canvas figure


【解决方案1】:

可以通过设置全局标志was_plotted来解决

was_plotted = False

def plot():
    global was_plotted
    if(was_plotted):
        return 
    was_plotted = True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多