Sunday, 2 January 2022

(Python) tkinter figures (with colorbar) overlap when using slider (update)

The following codes 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

enter image description here

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")

def plot_noise():
    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 = plt.Figure()                       
    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=========================================
    ax = fig.add_subplot(111)                 
    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])
    # ================================================Slider==========================================
    global slider_de
    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.5, antialiased = True)
                cbar = fig.colorbar(con,ax = ax)
                ax.axis([1, 12, 1, 6])
                
    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()

When running it, I got

enter image description here

Now, if I use fig.clf, for example

fig.clf()
con = ax.contourf(x,y,dfs[ii], levels = levels, cmap=cm.jet, alpha = 0.5, antialiased = True)
cbar = fig.colorbar(con,ax = ax)

I got

enter image description here

The contour disappeared. I also tried from matplotlib.figure import Figure instead of pyplot; however, it does not work.

How to fix this odd problem?

Any advices please, thanks!


Now I solve the original problem; however, the new problem popped out. I rewrote the update() function as the following

def update(val):
    num_on_slider.append(slider_de.val)
    for ii in range(0,num):
        if num_on_slider[-1] == ii:
                global cbar
                if cbar:
                    cbar.remove()
                    con = ax.contourf(x,y,dfs[ii], levels = levels, cmap=cm.jet, alpha = 0.5, antialiased = True)
                    cbar = fig.colorbar(con,ax = ax)
                    ax.axis([1, 12, 1, 6])

No overlap; however, the graph will not change as I move the slider. How to fix that?



from (Python) tkinter figures (with colorbar) overlap when using slider (update)

No comments:

Post a Comment