如何在Tkinter画布上更新情节? [英] How to update a plot on Tkinter canvas?

查看:54
本文介绍了如何在Tkinter画布上更新情节?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 tkinter 应用程序,其中我有不同的框架,每个框架都有不同的情节.我具有导入功能,可以选择要绘制的数据文件.

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

推荐答案

调用画布的draw()方法.

这篇关于如何在Tkinter画布上更新情节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆