The following is to plot contours from five (slider: 0 ~ 4) .xlsx files on tkinter
. Each file just contains numerical data in the matrix 12X6 such as
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()
I use <------ to mark the place using imshow
.
My question is after using slider to choose plot, by update(var)
, the background blurs. I mean
I know in the update(var)
, I should remove the previous con = ax.contourf
. However, it does not work if I add 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'
How to fix this issue? Thanks!!
The background is not the problem, you are drawing multiple transparent plots on top of each other without removing the previous one; hence, they stack and blur the background.
To fix, you can add this in you update function
for c in ax.collections:
c.remove()
It shows some artifacts for me, but at least you get to see the correct picture without rethinking the whole code structure.