2016-08-30 6 views
1

У меня есть приложение tkinter, где у меня разные кадры, каждый из которых имеет отдельный сюжет. У меня есть функция импорта, которая позволяет мне выбрать файл данных, который я хочу построить.Как обновить сюжет на холсте Tkinter?

В настоящее время все работает хорошо, если я импортирую файл в начале программы, т. Е., Как только созданный подпрограмма создается на холсте, данные отображаются.

Однако, если подзаборка создается заранее без каких-либо данных, когда я импортирую данные и вызываю функцию для ее построения, холст не обновляет график. НО, если я изменяю размер окна (или увеличиваю его), сюжет обновляется.

Ниже приведен код. Любое предложение относительно структуры кода оценивается.

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

Код, который вы опубликовали, не очень хорошо отформатирован, не содержит правильного импорта и не выполнен, чтобы попытаться воспроизвести вашу ошибку (я отредактировал код). Трудно дать ответ без хорошего вопроса. Кроме того, аргументы для обеих конечных функций, 'nyquist_plot' и' refresh plot' являются неполными и не явными. Вы должны явно передать 'df'. В 'refresh_plots' есть ссылка на' fig_nyquist', которая явно не определена в остальной части фрагмента кода, который вы опубликовали. Не могли бы вы переписать свой вопрос с лучшим фрагментом кода, чтобы другие могли помочь вам более точно? – kikocorreoso

+0

Спасибо @kikocorreoso. Я не хотел давать полный код, потому что я думал, что это демотивирует людей, чтобы читать его ... мое плохое. Я просто добавил остальную часть кода. EIS_df - глобальная переменная (dataframe) – cinico

ответ

1

Позвоните нам по телефону draw().

+0

Я сделал это. Я ничего не делаю. – cinico

+0

Успех. Мне нужно было сделать fig_xxxxx.canvas.draw() – cinico