How to update a plot on Tkinter canvas?

拥有回忆 提交于 2020-01-14 02:37:08

问题


I have a tkinter app where I have different frames, each one with a different plot. I have an import function that allows me to select the data file that I want to plot.

Right now, everything is working well if I import the file right at the start of the program, i.e. as soon as the subplot is created on the canvas the data is shown.

However, if the subplot is created beforehand without any data, when I import the data and call the function to plot it, the canvas does not update the plot. BUT, if I resize the window (or maximize it) the plot is updated.

Below is the code. Any suggestion regarding the code structure are appreciated.

import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use("TkAgg")

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation


import Tkinter as tk
import ttk
from tkFileDialog import askopenfilename

LARGE_FONT= ("Verdana", 12)
plot_colors = plt.rcParams['axes.color_cycle']
width, height = plt.figaspect(1)

fig_nyquist = Figure(figsize=(width, height), dpi=100)
plot_axes_nyquist = fig_nyquist.add_subplot(111)

fig_bode = Figure(figsize=(width, height), dpi=100)
plot_axes_bode = fig_bode.add_subplot(111)

fig_randles = Figure(figsize=(width, height), dpi=100)
plot_axes_randles = fig_randles.add_subplot(111)


class EISapp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "EIS + CV Analyser")


        container = tk.Frame(self)
        container.pack(pady=10,padx=10, side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}


        for F in (menu_page, nyquist_page, bode_page, randles_page):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(menu_page)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()




class menu_page(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        label = tk.Label(self, text="Menu", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        import_button = ttk.Button(self, text="Import EIS data file", command=lambda: import_EIS_data())
        import_button.pack()

        nyquist_button = ttk.Button(self, text="Nyquist Plot", command=lambda: controller.show_frame(nyquist_page))
        nyquist_button.pack()

        bode_button = ttk.Button(self, text="Bode Plot", command=lambda: controller.show_frame(bode_page))
        bode_button.pack()

        randles_button = ttk.Button(self, text="Randles Plot", command=lambda: controller.show_frame(randles_page))
        randles_button.pack()



class nyquist_page(tk.Frame):

    def __init__(self, parent, controller):        
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Nyquist Plot", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        menu_button = ttk.Button(self, text="Menu", command=lambda: controller.show_frame(menu_page))
        menu_button.pack()

        refresh_button = ttk.Button(self, text="Refresh", command=lambda: refresh_plots())
        refresh_button.pack()

        canvas = FigureCanvasTkAgg(fig_nyquist, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

        toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()

class bode_page(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Bode Plot", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        menu_button = ttk.Button(self, text="Menu", command=lambda: controller.show_frame(menu_page))
        menu_button.pack()

        canvas = FigureCanvasTkAgg(fig_bode, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

        toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()

class randles_page(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Randles Plot", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        menu_button = ttk.Button(self, text="Menu", command=lambda: controller.show_frame(menu_page))
        menu_button.pack()

        canvas = FigureCanvasTkAgg(fig_randles, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

        toolbar = NavigationToolbar2TkAgg(canvas, self)
        toolbar.update()

def import_EIS_data():
    global EIS_df    
    try:
        filename = askopenfilename(defaultextension='.txt', filetypes=[('txt file','*.txt'), ('All files','*.*')]) # show an "Open" dialog box and return the path to the selected file 

        data_table = pd.read_table(filename, index_col=False, skiprows=headers_footers(filename)[0], skip_footer=headers_footers(filename)[1], names=['Temperature', 'Frequency', 'Raw Amplitude', 'Z1', 'Z2', 'Time', 'Gain level'] )

        # Convert Frequency values from kHz to Hz
        data_table['Frequency'] = data_table['Frequency'] * 1000;

        # Delete Unnecessary Columns
        data_table = data_table.drop(['Temperature', 'Gain level', 'Raw Amplitude', 'Time'], axis=1); # axis=1 selects "vertical axis" (i.e. columns instead of rows)

        # Adds calculated values of impedance modulus and angle
        data_table['Z'] = np.sqrt(data_table['Z1']**2 + data_table['Z2']**2);
        data_table['Angle'] = np.degrees( np.arctan( -data_table['Z2'] / data_table['Z1'] ) );

        EIS_df = EIS_df.append(data_table)
        refresh_plots()

    except:
        quit()




def nyquist_plot(Z1, Z2, plot_axes=None):
    if plot_axes == None:
        plot_axes = plt.subplot(111)
    if not EIS_df.empty:
        plot_axes.plot(Z1, Z2)
        plot_axes.set_xlabel('$\Re(Z)$')
        plot_axes.set_ylabel('$\Im(Z)$')  
        plot_axes.set_xlim([0, 800]);
        plot_axes.set_ylim([-800, 0]);

def bode_plot(freq, Z, angle, imped_axis=None):

    if imped_axis == None:
        imped_axis = plt.subplot(111)
    if not EIS_df.empty:    
        handle_imped, = imped_axis.plot(freq, Z, label="Impedance")
        imped_axis.set_xlabel('$Frequency$ $(Hz)$')
        imped_axis.set_ylabel('$|Z|$')
        imped_axis.semilogx()
        imped_axis.semilogy()
        imped_axis.legend(loc=2)

    #    imped_axis.set_xlim([0, 1E7]);
    #    imped_axis.set_ylim([1E-1, 1E5]);

        angle_axis = imped_axis.twinx();
        handle_angle, = angle_axis.plot(freq, angle, plot_colors[1], label="Angle", linestyle='--');

        #Configure plot design    
        angle_axis.set_ylabel(r"$\theta$ $(^{\circ}) $")
    #    angle_axis.semilogx()
        angle_axis.grid('off')
        angle_axis.set_ylim([0, 90]);
        angle_axis.legend(loc=1, handlelength=3.6)


def randles_plot(freq, Z1, Z2, plot_axes=None):
    if plot_axes == None:
        plot_axes = plt.subplot(111)
    if not EIS_df.empty:
        plot_axes.plot(1/(np.pi*np.sqrt(freq)),Z1, label='$\Re(Z)$')
        plot_axes.plot(1/(np.pi*np.sqrt(freq)),-Z2, label='$\Im(Z)$')
        plot_axes.legend(loc=2)
        plot_axes.set_xlabel('$(\sqrt{\omega})^{-1}$')
        plot_axes.set_ylabel('$Impedance$') 


def refresh_plots():
    nyquist_plot(EIS_df.Z1, EIS_df.Z2, plot_axes_nyquist)
    fig_nyquist.tight_layout()

    bode_plot(EIS_df.Frequency, EIS_df.Z, EIS_df.Angle, plot_axes_bode)
    fig_bode.tight_layout()    

    randles_plot(EIS_df.Frequency, EIS_df.Z1, EIS_df.Z2, plot_axes_randles)
    fig_randles.tight_layout()


EIS_df = pd.DataFrame(columns=['Frequency', 'Z1', 'Z2', 'Z', 'Angle'] )
app = EISapp()
app.mainloop()

回答1:


Call the draw() method of the canvas.



来源:https://stackoverflow.com/questions/39222641/how-to-update-a-plot-on-tkinter-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!