我有一个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()
nyquist_plot
和refresh plot
的参数是不完整和不明确的。你应该显式传递df
。在refresh_plots
中,有一个对fig_nyquist
的引用,在你发布的代码片段中没有明确定义。你能否使用更好的代码段重新编写你的问题,以便其他人可以更精准地帮助你? - kikocorreoso