【发布时间】:2021-01-08 16:38:30
【问题描述】:
我有一个复杂的 gui,太长了,无法在此处发布。我无法理解如何从我的 Tkinter gui 中的图形中清除图形。我有一个选项卡式 gui,想在每个选项卡中绘制一个图形并清除每个选项卡中的图形。当我尝试这样做时,我会遇到与画布有关的各种不同错误。我可以理解图形、轴、选项卡和框架,但画布似乎被称为图形的同义词,看起来很奇怪(而且可能不正确)。
我看不出图形和画布之间有什么区别(有吗?),我在这里阅读的大多数文章和答案似乎根本没有覆盖画布
Matplotlib 文档: “数字 整个图。该人物跟踪所有子 Axes、少数“特殊”艺术家(标题、人物传说等)和画布。 (不要太担心画布,它是至关重要的,因为它是实际绘制绘图的对象,但作为用户,它是你或多或少看不见)。一个图形可以有任意数量的轴,但要有用,至少应该有一个。”
代码
import tkinter.filedialog
import os
import re
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
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import easygui
from matplotlib.legend_handler import HandlerLine2D
from scipy.stats import linregress
pd.set_option("display.max_rows", None, "display.max_columns", None)
#=====================================================================
# ROOT FIGURE FOR GUI
#=====================================================================
root = tk.Tk()
root.title("Tab Widget")
root.geometry("600x450")
tabControl = ttk.Notebook(root)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tabControl.add(tab1, text ='Circle cal drops')
tabControl.add(tab2, text ='OPW')
tk.Grid.rowconfigure(root, 0, weight=1)
tk.Grid.columnconfigure(root, 0, weight=1)
tabControl.grid(column=0, row=0, sticky=tk.E+tk.W+tk.N+tk.S)
# TAB 1
# creating a frame (my_frame_1)
my_frame_1 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_1.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
fig = Figure(figsize=(4,4), dpi=100)
def clearPlot():
fig.clear()
canvas.draw_idle()
def plotData():
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [5, 6, 1, 3, 8], marker='.', c='r')
canvas = FigureCanvasTkAgg(fig, master = my_frame_1)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_2)
my_frame_2 = tk.Frame(tab1, bd=2, relief=tk.GROOVE)
my_frame_2.pack(side=tk.RIGHT)
#---------------------------------------------------------------------
button1_cal = tk.Button(my_frame_2, text = "Clear Plot", command = clearPlot, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_2, text = "Plot \nData", command = plotData, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
# TAB 2
# creating a frame (my_frame_3)
my_frame_3 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_3.pack(side=tk.LEFT, anchor=tk.N, fill=tk.BOTH, expand=True)
#---------------------------------------------------------------------
def clearPlotOpw():
pass
def plotDataOpw():
fig = Figure(figsize=(4,4), dpi=100)
a = fig.add_subplot(111)
a.plot([1, 2, 3, 4, 5], [8, 5, 1, 3, 11], marker='o', c='b')
canvas = FigureCanvasTkAgg(fig, master = my_frame_3)
canvas.get_tk_widget().pack()
canvas._tkcanvas.pack()
#create another frame(my_frame_4)
my_frame_4 = tk.Frame(tab2, bd=2, relief=tk.GROOVE)
my_frame_4.pack(side=tk.RIGHT)
button1_cal = tk.Button(my_frame_4, text = "Clear Plot", command = clearPlotOpw, relief = tk.GROOVE, padx =20, pady =20 )
button1_cal.pack(side="top", fill="x")
button2_cal = tk.Button(my_frame_4, text = "Plot \nData", command = plotDataOpw, relief = tk.GROOVE, padx =20, pady =20 )
button2_cal.pack(side="top", fill="x" )
root.mainloop()
print('\n'*4)
*** 期望的结果 ***
能够根据需要清除每个绘图并重新绘图。
尝试使用清晰绘图功能时的回溯
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/.../opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/.../Desktop/tk_gui_grid/basic_08.py", line 48, in clearPlot
canvas.draw_idle()
NameError: name 'canvas' is not defined
我知道画布是未定义的,但是当我定义它时,情节根本没有被绘制出来。
【问题讨论】:
-
试着在
plotDataOpw()和plotData()上说global canvas? -
我试过了。它将清除第一个图,但不会清除第二个(plotDataOpw())。
-
这类问题总是一样的:不要每次执行函数都创建一个新的
Figure和FigureCanvasTkAgg对象。在函数外部创建一次,清除画布并在函数内部绘图。
标签: python matplotlib user-interface tkinter tkinter-canvas