在 tkinter 上迭代后使用 imshow 的背景模糊

Background using imshow blurs after iteration on tkinter

以下是 tkinter 上五个(滑块:0 ~ 4).xlsx 文件的轮廓图。每个文件仅包含矩阵 12X6 中的数值数据,例如

from tkinter import *
import tkinter.ttk as ttk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
import ipywidgets as wg
import os
import pandas as pd
from matplotlib.ticker import MaxNLocator
from matplotlib.colors import BoundaryNorm
import math
from matplotlib.ticker import LinearLocator
%matplotlib widget
from matplotlib.widgets import Slider
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')

root = Tk()
root.title('TEST')
root.geometry("800x800")

cbar = None
def plot_noise():
    # ============================================Read .xlsx file=====================================
    folder = r'C:\Users\Dian-Jing Chen\Desktop\Work\test_read'
    files = os.listdir(folder)
    dfs = {}
    for i, file in enumerate(files):
        if file.endswith('.xlsx'):
            dfs[i] = pd.read_excel(os.path.join(folder,file), sheet_name='Z=143', header = None, skiprows=[0], usecols = "B:M")

    num = i + 1
    rec = np.shape(dfs[0])
    rmm = np.concatenate([dfs[0], dfs[1]])
    for jj in range(2,num):
        rmm = np.concatenate([rmm, dfs[jj]])
    # =================================================PLOT===========================================
    fig, ax = plt.subplots()                       
    canvas = FigureCanvasTkAgg(fig, root)     
    canvas.get_tk_widget().grid(row=3, column=0, columnspan=3, rowspan=3, sticky=W+E+N+S, padx=0, pady=0) 
    # ===============================================contourf=========================================          
    fig.subplots_adjust(bottom=0.25)          
    X = np.arange(1,rec[1]+1,1)
    Y = np.arange(1,rec[0]+1,1)
    x , y = np.meshgrid(X,Y)  
    # ==============================================color bar=========================================
    cbar_max = math.floor(np.min(rmm))
    cbar_min = math.ceil(np.max(rmm))
    cbar_num_colors = 200
    cbar_num_format = "%d"
    levels = MaxNLocator(nbins=cbar_num_colors).tick_values(cbar_min, cbar_max)
    # ============================================Initial plot======================================== 
    con = ax.contourf(x,y,dfs[1], levels = levels, cmap=cm.jet, alpha = 0.5, antialiased = True)  
    cbar = fig.colorbar(con,ax = ax)
    ax.axis([1, 12, 1, 6])
    implot = plt.imshow(plt.imread('pcb.png'), interpolation='nearest', alpha=0.8, extent=[1,12,1,6]) # <-----
    ax.set_aspect('equal', 'box')
    # ================================================Slider==========================================
    slider_bar = fig.add_axes([0.12, 0.1, 0.78, 0.03])     
    slider_de = Slider(slider_bar, 's_bar', 0, num-1, valinit=1,valfmt='%0.0f',  valstep=1)
    num_on_slider = []

    def update(val):
        num_on_slider.append(slider_de.val)
        for ii in range(0,num):
            if num_on_slider[-1] == ii:
                con = ax.contourf(x,y,dfs[ii], levels = levels, cmap=cm.jet, alpha = 0.3, antialiased = True)
                ax.axis([1, 12, 1, 6])
                ax.set_aspect('equal', 'box')
                
    slider_de.on_changed(update)            
                
    
# =================================================GUI - Tkinter======================================= 
resultButton = ttk.Button(root, text = 'show', command = plot_noise)
resultButton.grid(column=0, row=1, pady=15, sticky=W)

root.mainloop()

我使用 <------ 标记使用 imshow 的地方。

我的问题是在使用滑块选择绘图后,update(var),背景变模糊了。我是说

我知道在 update(var) 中,我应该 删除 之前的 con = ax.contourf。但是,如果我添加 con.remove()

它不起作用
def update(val):
    num_on_slider.append(slider_de.val)
    for ii in range(0,num):
        if num_on_slider[-1] == ii:
            con = ax.contourf(x,y,dfs[ii], levels = levels, cmap=cm.jet, alpha = 0.3, antialiased = True)
            ax.axis([1, 12, 1, 6])
            ax.set_aspect('equal', 'box')
            ax.set_title('Frequency: f=%f' %float(avector[ii]))
            con.remove()

AttributeError: 'QuadContourSet' object has no attribute 'remove'

如何解决这个问题?谢谢!!

背景不是问题,您在没有移除前一个的情况下在彼此之上绘制多个透明图;因此,它们堆叠并模糊了背景。

要修复,您可以在更新函数中添加这个

for c in ax.collections:
    c.remove()

它为我展示了一些瑕疵,但至少你可以看到正确的图片而无需重新考虑整个代码结构。