如何清除 tkinter 中的 matplotlib 图?
How do I clear a mathplotlib graph in tkinter?
我正在尝试清除 tkinker 中的(整个)mathplotlib 图。意思是,我正在尝试绘制图 A。单击清除按钮。单击清除按钮后,我的目标是从 canvas 中清除图 A。如果我点击按钮 plot graph B,就会出现 graph B 的内容。目前,当我尝试清除图形(单击清除图形按钮)时,我看到 AttributeError: 'GetInterfaceValues' object has no attribute 'canvas'
。有人可以引导我朝着正确的方向前进吗?
基本上这是我的代码:
plotting.py 文件
import matplotlib
import pandas as pd
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
fig, ax = plt.subplots()
def plotGraph(self):
df = pd.DataFrame({'Years': ['2016-12-31', '2017-12-31', '2018-12-31', '2019-12-31'],
'Value': [-495982.0, -405549.0, -351541.0, -283790.0]})
yLabelText = "Value"
ax.set_xlabel('Years')
ax.set_ylabel(yLabelText)
fig = plt.figure(figsize=(12, 10), dpi=80)
ax1 = fig.add_subplot(111)
ax1.set_title('Keg values')
ax1.set_xlabel('Years')
ax1.set_ylabel(yLabelText)
datas = df.plot(ax=ax1, color ='orange')
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
fig.tight_layout()
canvas = FigureCanvasTkAgg(fig, self)
canvas.draw()
canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
def plotCashGraph(self):
df = pd.DataFrame({'Quarter': ['2018-03-31', '2018-06-30', '2018-10-31', '2020-01-01'],
'Value': [-9000.0, 105549.0, -51541.0, 2790.0]})
yLabelText = "Value"
ax.set_xlabel('Quarter')
ax.set_ylabel(yLabelText)
fig = plt.figure(figsize=(12, 10), dpi=80)
ax1 = fig.add_subplot(111)
ax1.set_title('Cash')
ax1.set_xlabel('Quarter')
ax1.set_ylabel(yLabelText)
datas = df.plot(ax=ax1, color ='green')
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
fig.tight_layout()
canvas = FigureCanvasTkAgg(fig, self)
canvas.draw()
canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
def clearPlotPage(self):
self.canvas.destroy()
self.canvas = None
和接口文件:
try:
import Tkinter as tk
except:
import tkinter as tk
import plotting as pyt
class GetInterfaceValues():
def __init__(self):
self.root = tk.Tk()
self.totalValue = tk.StringVar()
self.root.geometry('900x500')
self.plotGraphButton = tk.Button(self.root, text='plot the kegs values', command=self.plotKeg)
self.plotCashValue = tk.Button(self.root, text='plot cash value', command=self.plotCash)
self.clearButton = tk.Button(self.root,text='Clear Chart',command=self.clear)
self.plotGraphButton.pack()
self.plotCashValue.pack()
self.clearButton.pack()
self.root.mainloop()
def plotKeg(self):
pyt.plotGraph(self.root)
def plotCash(self):
pyt.plotCashGraph(self.root)
def clear(self):
pyt.clearPlotPage(self)
app = GetInterfaceValues()
几件事:
- 奇怪的是,当您不使用
class
时,您的函数接受 self
作为参数。我想您最初是从 OOP 方法复制代码的。
- 您不必删除
canvas
并重新创建它。您可以简单地重复使用它。
fig
也是如此——你只需要清除它并重新绘制。
从您的 plotting.py 开始,我建议您创建 class
并改为创建 class 方法:
import matplotlib
import pandas as pd
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure #as said before, use Figure instead of pyplot
class PlotGraph:
def __init__(self):
self.canvas = None
self.fig = Figure(figsize=(12, 10), dpi=80)
def plotGraph(self, container):
df = pd.DataFrame({'Years': ['2016-12-31', '2017-12-31', '2018-12-31', '2019-12-31'],
'Value': [-495982.0, -405549.0, -351541.0, -283790.0]})
ax = self.fig.add_subplot(111)
ax.set_title('Keg values')
ax.set_xlabel('Years')
ax.set_ylabel("Value")
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
df.plot(ax=ax, color='orange')
if not self.canvas:
self.canvas = FigureCanvasTkAgg(self.fig, container)
self.canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
self.canvas.draw_idle()
def plotCashGraph(self, container):
df = pd.DataFrame({'Quarter': ['2018-03-31', '2018-06-30', '2018-10-31', '2020-01-01'],
'Value': [-9000.0, 105549.0, -51541.0, 2790.0]})
ax = self.fig.add_subplot(111)
ax.set_xlabel('Quarter')
ax.set_ylabel("Value")
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
df.plot(ax=ax, color='green')
if not self.canvas:
self.canvas = FigureCanvasTkAgg(self.fig, container)
self.canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
self.canvas.draw_idle()
def clearPlotPage(self):
self.fig.clear() #clear your figure
self.canvas.draw_idle() #redraw your canvas so it becomes empty
设置好后端后,只需稍微修改一下接口文件即可:
try:
import Tkinter as tk
except:
import tkinter as tk
import plotting as pyt
class GetInterfaceValues():
def __init__(self):
self.root = tk.Tk()
self.totalValue = tk.StringVar()
self.root.geometry('900x500')
self.plotGraphButton = tk.Button(self.root, text='plot the kegs values', command=self.plotKeg)
self.plotCashValue = tk.Button(self.root, text='plot cash value', command=self.plotCash)
self.clearButton = tk.Button(self.root, text='Clear Chart', command=self.clear)
self.plotGraphButton.pack()
self.plotCashValue.pack()
self.clearButton.pack()
self.root.mainloop()
def plotKeg(self):
plot.plotGraph(self.root)
def plotCash(self):
plot.plotCashGraph(self.root)
def clear(self):
plot.clearPlotPage()
plot = pyt.PlotGraph() #initiate a class instance
app = GetInterfaceValues()
我正在尝试清除 tkinker 中的(整个)mathplotlib 图。意思是,我正在尝试绘制图 A。单击清除按钮。单击清除按钮后,我的目标是从 canvas 中清除图 A。如果我点击按钮 plot graph B,就会出现 graph B 的内容。目前,当我尝试清除图形(单击清除图形按钮)时,我看到 AttributeError: 'GetInterfaceValues' object has no attribute 'canvas'
。有人可以引导我朝着正确的方向前进吗?
基本上这是我的代码: plotting.py 文件
import matplotlib
import pandas as pd
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
fig, ax = plt.subplots()
def plotGraph(self):
df = pd.DataFrame({'Years': ['2016-12-31', '2017-12-31', '2018-12-31', '2019-12-31'],
'Value': [-495982.0, -405549.0, -351541.0, -283790.0]})
yLabelText = "Value"
ax.set_xlabel('Years')
ax.set_ylabel(yLabelText)
fig = plt.figure(figsize=(12, 10), dpi=80)
ax1 = fig.add_subplot(111)
ax1.set_title('Keg values')
ax1.set_xlabel('Years')
ax1.set_ylabel(yLabelText)
datas = df.plot(ax=ax1, color ='orange')
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
fig.tight_layout()
canvas = FigureCanvasTkAgg(fig, self)
canvas.draw()
canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
def plotCashGraph(self):
df = pd.DataFrame({'Quarter': ['2018-03-31', '2018-06-30', '2018-10-31', '2020-01-01'],
'Value': [-9000.0, 105549.0, -51541.0, 2790.0]})
yLabelText = "Value"
ax.set_xlabel('Quarter')
ax.set_ylabel(yLabelText)
fig = plt.figure(figsize=(12, 10), dpi=80)
ax1 = fig.add_subplot(111)
ax1.set_title('Cash')
ax1.set_xlabel('Quarter')
ax1.set_ylabel(yLabelText)
datas = df.plot(ax=ax1, color ='green')
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
fig.tight_layout()
canvas = FigureCanvasTkAgg(fig, self)
canvas.draw()
canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
def clearPlotPage(self):
self.canvas.destroy()
self.canvas = None
和接口文件:
try:
import Tkinter as tk
except:
import tkinter as tk
import plotting as pyt
class GetInterfaceValues():
def __init__(self):
self.root = tk.Tk()
self.totalValue = tk.StringVar()
self.root.geometry('900x500')
self.plotGraphButton = tk.Button(self.root, text='plot the kegs values', command=self.plotKeg)
self.plotCashValue = tk.Button(self.root, text='plot cash value', command=self.plotCash)
self.clearButton = tk.Button(self.root,text='Clear Chart',command=self.clear)
self.plotGraphButton.pack()
self.plotCashValue.pack()
self.clearButton.pack()
self.root.mainloop()
def plotKeg(self):
pyt.plotGraph(self.root)
def plotCash(self):
pyt.plotCashGraph(self.root)
def clear(self):
pyt.clearPlotPage(self)
app = GetInterfaceValues()
几件事:
- 奇怪的是,当您不使用
class
时,您的函数接受self
作为参数。我想您最初是从 OOP 方法复制代码的。 - 您不必删除
canvas
并重新创建它。您可以简单地重复使用它。 fig
也是如此——你只需要清除它并重新绘制。
从您的 plotting.py 开始,我建议您创建 class
并改为创建 class 方法:
import matplotlib
import pandas as pd
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure #as said before, use Figure instead of pyplot
class PlotGraph:
def __init__(self):
self.canvas = None
self.fig = Figure(figsize=(12, 10), dpi=80)
def plotGraph(self, container):
df = pd.DataFrame({'Years': ['2016-12-31', '2017-12-31', '2018-12-31', '2019-12-31'],
'Value': [-495982.0, -405549.0, -351541.0, -283790.0]})
ax = self.fig.add_subplot(111)
ax.set_title('Keg values')
ax.set_xlabel('Years')
ax.set_ylabel("Value")
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
df.plot(ax=ax, color='orange')
if not self.canvas:
self.canvas = FigureCanvasTkAgg(self.fig, container)
self.canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
self.canvas.draw_idle()
def plotCashGraph(self, container):
df = pd.DataFrame({'Quarter': ['2018-03-31', '2018-06-30', '2018-10-31', '2020-01-01'],
'Value': [-9000.0, 105549.0, -51541.0, 2790.0]})
ax = self.fig.add_subplot(111)
ax.set_xlabel('Quarter')
ax.set_ylabel("Value")
ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
df.plot(ax=ax, color='green')
if not self.canvas:
self.canvas = FigureCanvasTkAgg(self.fig, container)
self.canvas.get_tk_widget().pack(side="bottom", fill="both", expand=True)
self.canvas.draw_idle()
def clearPlotPage(self):
self.fig.clear() #clear your figure
self.canvas.draw_idle() #redraw your canvas so it becomes empty
设置好后端后,只需稍微修改一下接口文件即可:
try:
import Tkinter as tk
except:
import tkinter as tk
import plotting as pyt
class GetInterfaceValues():
def __init__(self):
self.root = tk.Tk()
self.totalValue = tk.StringVar()
self.root.geometry('900x500')
self.plotGraphButton = tk.Button(self.root, text='plot the kegs values', command=self.plotKeg)
self.plotCashValue = tk.Button(self.root, text='plot cash value', command=self.plotCash)
self.clearButton = tk.Button(self.root, text='Clear Chart', command=self.clear)
self.plotGraphButton.pack()
self.plotCashValue.pack()
self.clearButton.pack()
self.root.mainloop()
def plotKeg(self):
plot.plotGraph(self.root)
def plotCash(self):
plot.plotCashGraph(self.root)
def clear(self):
plot.clearPlotPage()
plot = pyt.PlotGraph() #initiate a class instance
app = GetInterfaceValues()