Python tkinter图形(带颜色条)每次缩小';展示

Python tkinter图形(带颜色条)每次缩小';展示,python,matplotlib,tkinter,colorbar,Python,Matplotlib,Tkinter,Colorbar,这是一个tkinter程序,由我正在使用的GUI简化而成: import tkinter as tk import matplotlib.pyplot as plt import numpy as np from matplotlib.backends.backend_tkagg import ( FigureCanvasTkAgg, NavigationToolbar2Tk) class App(tk.Tk): def __init__(self): supe

这是一个tkinter程序,由我正在使用的GUI简化而成:

import tkinter as tk
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)

class App(tk.Tk):
    def __init__(self):
        super(App, self).__init__()
        self.main_frame = tk.Frame(self,)
        self.main_frame.pack(fill=tk.BOTH, expand=1)
        
        self.plot1_button = tk.Button(self.main_frame, text='Plot 1',
                                      command=self.draw_plot1)
        self.plot1_button.pack(fill=tk.X,expand=1)
        
        self.plot2_button = tk.Button(self.main_frame, text='Plot 2',
                                      command=self.draw_plot2)
        self.plot2_button.pack(fill=tk.X,expand=1)

        self.FIG, self.AX = plt.subplots()
        self.canvas = FigureCanvasTkAgg(self.FIG, master=self.main_frame)   
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.main_frame)
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        
    def draw_plot1(self):
        self.clear_axes()
        fig = self.AX.plot(np.random.rand(10),np.random.rand(10), color='red')
        self.canvas.draw_idle()
        self.toolbar.update()      
        
    def draw_plot2(self):
        self.clear_axes()
        im = self.AX.matshow(np.random.rand(100,100))
        self.canvas.draw_idle()
        self.toolbar.update()
        cb = plt.colorbar(im, ax=self.AX)
    
    def clear_axes(self):
        for ax in self.FIG.axes:
            ax.clear()
            if ax != self.AX:
                ax.remove()
root = App()
root.resizable(False, False)
root.mainloop()
Plot 1按钮绘制随机线图,Plot 2按钮绘制带有色条的随机热图。可以重复单击“绘图1”按钮,按预期创建新的随机线图。单击10次后,显示屏看起来很好:

:

但“绘图2”按钮会使图形在每次单击时缩小。单击10次后,图形无法理解:

此外,再次单击“绘图1”时,图形大小仍然存在:

这些是从应用程序工具栏保存的
.png
文件,但在GUI窗口中可以看到相同的文件。我已尝试在不同位置向GUI/canvas添加更新(例如,
self.update()
self.canvas.draw\u idle()
),但未找到任何影响问题的内容。我添加了
clear_axes()
函数,因为在真实的GUI中,我有一些带有多个
轴的图形,这会删除它们,但显然在这里没有帮助


我发现,如果移除颜色栏,问题就会消失(即注释掉
cb=plt.colorbar(im,ax=self.ax)
),但我希望将此作为图的一部分。有人能解释一下发生了什么,或者有人能提出解决方案吗?我使用的是
matplotlib 3.2.1

问题是清除轴时没有清除
色条

class App(tk.Tk):
    def __init__(self):
        super(App, self).__init__()
        self.main_frame = tk.Frame(self,)
        ...
        self.cb = None

    ...

    def draw_plot2(self):
        self.clear_axes()
        im = self.AX.matshow(np.random.rand(100,100))
        self.canvas.draw_idle()
        self.toolbar.update()
        self.cb = plt.colorbar(im, ax=self.AX)

    def clear_axes(self):
        if self.cb:
            self.cb.remove()
            self.cb = None
        for ax in self.FIG.axes:
            ax.clear()
            if ax != self.AX:
                ax.remove()

还请注意,在使用
tkinter
时,应使用
matplotlib.figure.figure
而不是
pyplot
。有关官方样品,请参阅。

非常感谢,这非常有帮助!你说你不应该把
pyplot
tkinter
一起使用,我以前没听说过。缺点是什么?如果您的GUI和pyplot管理图形,它们可能会干扰并导致所有问题。对于初学者来说,退出GUI时,由于
pyplot
在不同的线程上运行,脚本可能无法正确退出。创建
Figure
类是为了使用
tkinter
接口安全地嵌入
matplotlib
图形。