清除当前图形后,为什么窗口中会占用空间?

时间:2019-04-02 07:21:09

标签: python user-interface matplotlib tkinter

我正在构建一个GUI应用程序以绘制数据行。该代码的当前问题是,尽管使用plt.clf()清除了当前图形,但窗口中仍然有一个占用的空间。

使用FigureCanvasTkAgg或matplotlib.pyplot时,还有其他注意事项吗?

我尝试了plt.cla(),plt.clf()和plt.close()。 plt.cla()和plt.clf()似乎都清除了数据,而plt.close()关闭了不需要的应用程序。

class PlotPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.canvas = None
        self.xlist, self.ylist = [1,2,3,4], [1,4,9,16]
        label = tk.Label(self, text="PlotPage")
        label.pack(pady=5)
        self.f = None

        buttonPlot = tk.Button(self, text="Show Plot", command=self.plot)
        buttonPlot.pack(pady=5)

        buttonClear = tk.Button(self, text="Clear Plot Field", command = self.clearPlotPage)
        buttonClear.pack(pady=5)

    def plot(self):
        if self.canvas == None:
            if self.f == None:
                self.f = plt.figure(1,figsize=(8,4), dpi=100)   
            plt.plot(self.xlist,self.ylist, 'ro')

            self.canvas = FigureCanvasTkAgg(self.f, self)
            self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
            self.canvas.draw()

            toolbar = NavigationToolbar2Tk(self.canvas, self)
            toolbar.update()
            self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

            print("Stuff has been plotted")
        else:
            print("Plot already plotted please clear first")\

    def clearPlotPage(self):
#         self.f == None
#         plt.clf()
        plt.cla()
        self.canvas.draw()
        self.canvas = None
        print("Plot Page has been cleared")

我希望能够在tkinter窗口上绘制数据,然后清除要在同一图上绘制新数据的轴;但是,实际情况是清除图形/轴之后,将数据绘制在新图形/轴上,而不是在清除的图形/轴上。

2 个答案:

答案 0 :(得分:0)

您可以致电canvas.get_tk_widget().destroy()

class PlotPage(tk.Frame):
    def __init__(self, parent):
        ...

    def plot(self):
        if self.canvas == None:
            if self.f == None:
                self.f = plt.figure(1,figsize=(8,4), dpi=100)
            plt.plot(self.xlist,self.ylist, 'ro')
            self.canvas = FigureCanvasTkAgg(self.f, self)
            self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
            toolbar = NavigationToolbar2Tk(self.canvas, self)
            toolbar.update()
            print("Stuff has been plotted")
        else:
            print("Plot already plotted please clear first")

    def clearPlotPage(self):
        plt.cla()
        self.canvas.get_tk_widget().destroy()
        self.canvas = None
        print("Plot Page has been cleared")

答案 1 :(得分:0)

作为Henry's answer的替代方法,我建议您不要每次都创建一个新图形。相反,您应该保留图形和画布(可能还有坐标轴),并且仅更新图的 content 。像这样(此代码目前未经测试):

class PlotPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.f = plt.figure(1, figsize=(8, 4), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.f, self)
        self.ax = self.f.add_subplot(111)
        self.isPlotted = False

        self.xlist, self.ylist = [1, 2, 3, 4], [1, 4, 9, 16]
        label = tk.Label(self, text="PlotPage")
        label.pack(pady=5)

        buttonPlot = tk.Button(self, text="Show Plot", command=self.plot)
        buttonPlot.pack(pady=5)

        buttonClear = tk.Button(self, text="Clear Plot Field", command=self.clearPlotPage)
        buttonClear.pack(pady=5)

    def plot(self):
        if not self.isPlotted:
            self.ax.plot(self.xlist, self.ylist, 'ro')

            self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
            self.canvas.draw()

            toolbar = NavigationToolbar2Tk(self.canvas, self)
            toolbar.update()
            self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

            print("Stuff has been plotted")
        else:
            print("Plot already plotted please clear first")

    def clearPlotPage(self):
        self.ax.clear()
        self.canvas.draw()
        print("Plot Page has been cleared")