我制作了一个具有GUI并绘制数据集的Python脚本。但是,当我使用PyInstaller将其转换为可执行文件时,GUI运行良好,但是没有绘图。 在控制台上出现错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "tkinter\__init__.py", line 1883, in __call__
File "adc_project.py", line 451, in plot_data
File "matplotlib\pyplot.py", line 540, in figure
File "matplotlib\backend_bases.py", line 3358, in new_figure_manager
File "matplotlib\backends\_backend_tk.py", line 897, in new_figure_manager_given_figure
File "tkinter\__init__.py", line 4061, in __init__
File "tkinter\__init__.py", line 4006, in __init__
_tkinter.TclError: couldn't open "C:\Users\phbar\AppData\Local\Temp\_MEI31202\mpl-data\images\matplotlib_128.ppm": no such file or directory
Matplotlib version = 2.2.5
PyInstaller version = 4.0
Python version = 3.8.3
这是完整的Python代码;它会创建一个GUI,要求用户打开一个文本文件,计算然后绘制该文本文件中的数据。
import tkinter as tk
from tkinter.filedialog import askopenfilename
import tkinter.scrolledtext as st
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
import os
import sys
from tkinter import messagebox
ideal_list = []
adc_list = []
adc_list_int = []
global num_codes
window = tk.Tk()
window.title("ADC Linearity Analyzer")
window.geometry("562x172")
window.resizable(width=True, height = True)
##window.resizable(width=True, height = True)
frame1 = tk.LabelFrame(window, padx = 5, pady = 5)
frame1.grid(row = 0, column = 0, padx = 10, pady = 5, sticky = tk.W)
label_res = tk.Label(frame1, text = "ADC Resolution: ")
label_res.grid(row = 2, column = 0, sticky = tk.S+tk.W)
entry_res = tk.Entry(frame1, width = 7)
entry_res.config(justify = tk.CENTER)
entry_res.grid(row = 2, column = 0, padx = 100, sticky = tk.W)
label_hits = tk.Label(frame1, text = "Hits per Code: ")
label_hits.grid(row = 3, column = 0, sticky = tk.S+tk.W)
entry_hits = tk.Entry(frame1, width = 7)
entry_hits.config(justify = tk.CENTER)
entry_hits.grid(row = 3, column = 0, padx = 100, sticky = tk.W)
label_beyond = tk.Label(frame1, text = "LSB Beyond: ")
label_beyond.grid(row = 4, column = 0, sticky = tk.S+tk.W)
entry_beyond = tk.Entry(frame1, width = 7)
entry_beyond.config(justify = tk.CENTER)
entry_beyond.grid(row = 4, column = 0, padx = 100, sticky = tk.W)
label_transpoint = tk.Label(frame1, text = "Transition Point: ")
label_transpoint.grid(row = 5, column = 0, sticky = tk.W)
entry_transpoint = tk.Entry(frame1, width = 7)
entry_transpoint.config(justify = tk.CENTER)
entry_transpoint.grid(row = 5, column = 0, padx = 100, sticky = tk.W)
label_title = tk.Label(frame1, text = "Welcome to ADC Linearity Analyzer!")
label_title.grid(row = 0, column = 0, sticky = tk.W)
label_open = tk.Label(frame1, text = "Open datalog: ")
label_open.grid(row = 1, column = 0, sticky = tk.W)
entry_file = tk.Entry(frame1, width = 54)
entry_file.grid(row = 1, column = 0, padx = 100, columnspan = 2)
entry_file.config(justify = tk.LEFT)
var1 = tk.IntVar()
chck_window = tk.Checkbutton(frame1, text = "Window", variable = var1, onvalue = 1, offvalue = 0)
chck_window.grid(row = 5, column = 1, padx = 10, sticky = tk.S+tk.W)
frame2 = tk.LabelFrame(window, padx = 5, pady = 5)
def open_file():
entry_file.delete(0, 'end')
global filename
filename = askopenfilename()
entry_file.insert(0, filename)
def restart_prog():
python = sys.executable
os.execl(python, python, * sys.argv)
def plot_data():
if entry_file.get() == "":
messagebox.showinfo("Error", "Select a text file.")
elif entry_res.get() == "":
messagebox.showinfo("Error", "Enter ADC Resolution.")
elif entry_hits.get() == "":
messagebox.showinfo("Error", "Enter Hits per Code.")
elif entry_beyond.get() == "":
messagebox.showinfo("Error", "Enter LSB Beyond.")
elif entry_transpoint.get() == "":
messagebox.showinfo("Error", "Enter Transition Point.")
else:
btn_plot.configure(state = tk.DISABLED)
btn_browse.configure(state = tk.DISABLED)
window.geometry("562x645")
## creates a list from 0 to num_codes
## for best fit ramp
res = int(entry_res.get())
num_codes = 2**res
num_hits = int(entry_hits.get())
lsb_beyond = int(entry_beyond.get())
transpoint = entry_transpoint.get()
if transpoint == '1':
hits_transpoint = num_hits
elif transpoint == '0.5':
if num_hits % 2 == 1:
hits_transpoint = num_hits//2 + 1
else:
hits_transpoint = num_hits//2
for h in range(0, num_codes):
if h == 0:
for e in range((num_hits*lsb_beyond) + int(hits_transpoint)):
ideal_list.append(h)
if h == num_codes - 1:
for n in range((num_hits*(lsb_beyond))+int(hits_transpoint)):
ideal_list.append(h)
if h != 0 and h != num_codes:
for i in range(num_hits):
ideal_list.append(h)
with open(filename, 'r+') as read_obj:
with open('adc_data.txt', 'w') as write_obj:
for line in read_obj:
if (line[2:8] == 'ADC_DB' and line[10:13] != 'DNL'
and line[10:13] != 'Off' and line[10:13] != 'Gai'
and line[10:13] != 'wor' and line[10:13] != 'min'
and line[10:13] != 'INL' and line[10:13] != 'Mis'
and line[10:13] != 'Abs' and line[10:13] != 'Spa'
and line[10:13] != 'VB_' and line[8:11] != ' - '
and line[10:13] != 'Avg'):
f = write_obj.write(line[10:-1])
with open('adc_data.txt', 'r+') as new_file:
for line in new_file:
adc_list.append(line[0:-1].rstrip('\n').replace(':', ','))
adc_list_int = list(map(int, adc_list[0].split(',')))
##---------Missing Codes---------------------------------
miss_codes_list = []
##Counts the number of iteration each code have
sum_hits = 0
count_hits = []
ideal_count_hits = []
for code in range(num_codes):
u = Counter(adc_list_int)
hits_count.insert(tk.INSERT, 'Code {} = {}\n'.format(code, u[code]))
count_hits.append(u[code])
if u[code] == 0:
miss_codes_list.append(code)
entry_misscode.insert(0, len(miss_codes_list))
misscodes_list.insert(tk.INSERT, 'Code {}\n'.format(code))
uu = Counter(ideal_list)
ideal_count_hits.append(uu[code])
if not miss_codes_list:
entry_misscode.insert(0, "None")
misscodes_list.insert(tk.INSERT, "No Missing\nCodes")
sum_count_hits = 0
sum_ideal_hits = 0
sum_count_hits_list = []
sum_ideal_hits_list = []
for ele_count_hits in range(0, num_codes):
sum_count_hits = sum_count_hits + count_hits[ele_count_hits]
sum_count_hits_list.append(sum_count_hits)
for ele_ideal_hits in range(0, num_codes):
sum_ideal_hits = sum_ideal_hits + ideal_count_hits[ele_ideal_hits]
sum_ideal_hits_list.append(sum_ideal_hits)
##---------DNL & INL--------------------------------
##get average hits per code
for ele in range(1, (len(count_hits)-1)):
sum_hits = sum_hits + count_hits[ele]
ave_hits = sum_hits/(num_codes - 2)
entry_avehits.insert(0, round(ave_hits, 5))
dnl_code = []
inl_code = []
max_dnl_codes = []
min_dnl_codes = []
max_inl_codes = []
inl_val = 0
worst_INL = 0
worst_INLcode = 0
for p in count_hits:
dnl_per_code = (p / ave_hits) - 1
dnl_code.append(dnl_per_code)
dnl_code[0] = 0
dnl_code[-1] = 0
for d in range(len(dnl_code)):
dnl_max = max(dnl_code)
dnl_min = min(dnl_code)
dnl_val = dnl_code[d]
inl_val = inl_val + dnl_val
inl_code.append(inl_val)
dnl_list.insert(tk.INSERT, 'Code {} = {}\n'.format(d, round(dnl_val, 6)))
inl_list.insert(tk.INSERT, 'Code {} = {}\n'.format(d, round(inl_val, 6)))
if dnl_val == dnl_max:
max_dnl_codes.append(d)
dnlmax_list.insert(tk.INSERT, 'Code {}\n'.format(d))
if dnl_val == dnl_min:
min_dnl_codes.append(d)
dnlmin_list.insert(tk.INSERT, 'Code {}\n'.format(d))
for e in range(len(inl_code)):
if abs(inl_code[e]) > abs(worst_INL):
worst_INL = inl_code[e]
worst_INLcode = e
entry_dnl.insert(0, round(max(dnl_code), 6))
entry_dnlmin.insert(0, round(min(dnl_code), 6))
entry_inl.insert(0, 'Code {} = {}'.format(worst_INLcode, round(worst_INL, 6)))
##-----------------Absolute Error------------------------------
actualNumofHits = 0
idealNumofHits = 0
absErr_list = []
worstabsErr = 0
for abscode in range(0, num_codes):
if abscode == 0:
absErr = 0.0
elif (abscode > 0 and abscode < num_codes - 1):
idealNumofHits = idealNumofHits + ideal_count_hits[abscode - 1]
actualNumofHits = actualNumofHits + count_hits[abscode - 1]
elif abscode == num_codes - 1:
idealNumofHits = idealNumofHits + ideal_count_hits[abscode - 1] + num_hits
actualNumofHits = actualNumofHits + count_hits[abscode - 1]
absErr = (actualNumofHits - idealNumofHits) / num_hits
absErr_list.append(absErr)
abserr_list.insert(tk.INSERT, 'Code {} = {}\n'.format(abscode, absErr_list[abscode]))
if abs(absErr) > abs(worstabsErr):
worstabsErr = absErr
for maxabserrcode in range(len(absErr_list)):
if (absErr_list[maxabserrcode] == worstabsErr):
maxabserr_list.insert(tk.INSERT, 'Code {}\n'.format(maxabserrcode))
entry_abserr.insert(0, worstabsErr)
##--------------------------------------------------------------------------
## Offset error
idealhits_code0 = num_hits * (lsb_beyond + float(transpoint))
offsetErr = (u[0] - idealhits_code0) / num_hits
entry_offseterr.insert(0, round(offsetErr, 5))
## Gain error
idealhits_lastcode = num_hits * ((lsb_beyond+1) + float(transpoint))
last_code = (u[num_codes-1] - idealhits_lastcode) / num_hits
gainerror = last_code + offsetErr
entry_gainerr.insert(0, round(gainerror, 5))
frame2.grid(row = 6, column = 0, padx = 10, pady = 75, sticky = tk.N + tk.W)
lbl_hits.grid(row = 0, column = 0, sticky = tk.N + tk.W)
hits_count.grid(row = 1, column = 0, rowspan = 2, columnspan = 2, sticky = tk.W)
hits_count.configure(state = 'disable')
lbl_dnl_list.grid(row = 0, column = 3, sticky = tk.N + tk.W)
dnl_list.grid(row = 1, column = 3, rowspan = 2, columnspan = 2, sticky = tk.W)
dnl_list.configure(state = 'disable')
lbl_dnlmax_list.grid(row = 0, column = 5, sticky = tk.N + tk.W)
dnlmax_list.grid(row = 1, column = 5, columnspan = 1, sticky = tk.N+tk.W)
dnlmax_list.configure(state = 'disable')
lbl_dnlmin_list.grid(row = 2, column = 5, sticky = tk.N + tk.W)
dnlmin_list.grid(row = 2, column = 5, pady = 20, columnspan = 1, sticky = tk.N+tk.W)
dnlmin_list.configure(state = 'disable')
lbl_inl_list.grid(row = 3, column = 0, sticky = tk.N + tk.W)
inl_list.grid(row = 4, column = 0, rowspan = 2, columnspan = 2, sticky = tk.W)
inl_list.configure(state = 'disable')
lbl_abserr_list.grid(row = 3, column = 3, sticky = tk.N + tk.W)
abserr_list.grid(row = 4, column = 3, rowspan = 2, columnspan = 2, sticky = tk.W)
abserr_list.configure(state = 'disable')
lbl_maxabserr_list.grid(row = 3, column = 5, sticky = tk.N + tk.W)
maxabserr_list.grid(row = 4, column = 5, columnspan = 1, sticky = tk.N+tk.W)
maxabserr_list.configure(state = 'disable')
lbl_misscodes_list.grid(row = 5, column = 5, sticky = tk.N + tk.W)
misscodes_list.grid(row = 5, column = 5, pady = 20, columnspan = 1, sticky = tk.N+tk.W)
misscodes_list.configure(state = 'disable')
label_avehits.grid(row = 6, column = 0, padx = 10, sticky = tk.N + tk.W)
entry_avehits.grid(row = 6, column = 0, padx = 100, sticky = tk.N+tk.W)
entry_avehits.configure(state = 'readonly')
label_offseterr.grid(row = 6, column = 0, padx = 10, pady = 26, sticky = tk.N +tk.W)
entry_offseterr.grid(row = 6, column = 0, padx = 100, pady = 25, sticky = tk.N +tk.W)
entry_offseterr.configure(state = 'readonly')
label_gainerr.grid(row = 6, column = 0, padx = 10, pady = 51, sticky = tk.N +tk.W)
entry_gainerr.grid(row = 6, column = 0, padx = 100, pady = 50, sticky = tk.N +tk.W)
entry_gainerr.configure(state = 'readonly')
label_dnl.grid(row = 6, column = 0, padx = 190, sticky = tk.N+tk.W)
entry_dnl.grid(row = 6, column = 0, padx = 290, sticky = tk.N+tk.W)
entry_dnl.configure(state = 'readonly')
label_dnlmin.grid(row = 6, column = 0, padx = 190, pady = 26, sticky = tk.N+tk.W)
entry_dnlmin.grid(row = 6, column = 0, padx = 290, pady = 25, sticky = tk.N+tk.W)
entry_dnlmin.configure(state = 'readonly')
label_inl.grid(row = 6, column = 0, padx = 190, pady = 51, sticky = tk.N+tk.W)
entry_inl.grid(row = 6, column = 0, padx = 290, pady = 50, sticky = tk.N+tk.W)
entry_inl.configure(state = 'readonly')
label_abserr.grid(row = 6, column = 0, padx = 380, sticky = tk.N+tk.W)
entry_abserr.grid(row = 6, column = 0, padx = 470, sticky = tk.N+tk.W)
entry_abserr.configure(state = 'readonly')
label_misscode.grid(row = 6, column = 0, padx = 380, pady = 26, sticky = tk.N+tk.W)
entry_misscode.grid(row = 6, column = 0, padx = 470, pady = 25, sticky = tk.N+tk.W)
entry_misscode.configure(state = 'readonly')
##------------------------------------------------------------------------
plt.style.use('fivethirtyeight')
if (var1.get() == 0):
fig1 = plt.figure(figsize = (20, 10))
sub1 = plt.subplot(2, 2, 1)
sub1.plot(ideal_list, marker=".", lw = 0.3, label = "Ideal")
sub1.plot(adc_list_int, lw = 1, marker = '.', label = "Actual")
plt.title("ADC Plot")
plt.legend()
plt.grid(True)
sub2 = plt.subplot(2, 2, 2)
sub2.hist(ideal_list, bins = num_codes, rwidth = 0.6, histtype = 'bar', label = "Ideal")
sub2.hist(adc_list_int, bins = num_codes, rwidth = 0.3, histtype = 'bar', label = "Actual")
plt.title("ADC Histogram")
plt.legend()
plt.grid(True)
sub3 = plt.subplot(2, 2, 3)
sub3.plot(range(0, num_codes), dnl_code, lw = 0.6, linestyle = '-', label = "DNL")
plt.yticks(fontsize = 8)
plt.xticks(fontsize = 8)
plt.title("DNL", y = -0.01)
plt.grid(True)
sub4 = plt.subplot(2, 2, 4)
sub4.plot(range(0, num_codes), inl_code, lw = 0.6, linestyle = '-', label = "INL")
plt.xticks(fontsize = 8)
plt.yticks(fontsize = 8)
plt.title("INL",y = -0.01)
plt.grid(True)
else:
fig1 = plt.figure(figsize = (20, 10))
sub1 = plt.subplot(2, 2, 1)
sub1.plot(ideal_list, marker=".", lw = 0.3, label = "Ideal")
sub1.plot(adc_list_int, lw = 1, marker = '.', label = "Actual")
plt.title("ADC Plot")
plt.legend()
plt.grid(True)
sub2 = plt.subplot(2, 2, 2)
sub2.hist(ideal_list, bins = num_codes, rwidth = 0.6, histtype = 'bar', label = "Ideal")
sub2.hist(adc_list_int, bins = num_codes, rwidth = 0.3, histtype = 'bar', label = "Actual")
plt.title("ADC Histogram")
plt.legend()
plt.grid(True)
sub3 = plt.subplot(2, 2, 3)
sub3.plot(range(0, num_codes), dnl_code, lw = 0.6, linestyle = '-', label = "DNL")
plt.yticks(fontsize = 8)
plt.xticks(fontsize = 8)
plt.title("DNL", y = -0.01)
plt.grid(True)
sub4 = plt.subplot(2, 2, 4)
sub4.plot(range(0, num_codes), inl_code, lw = 0.6, linestyle = '-', label = "INL")
plt.xticks(fontsize = 8)
plt.yticks(fontsize = 8)
plt.title("INL",y = -0.01)
plt.grid(True)
fig2 = plt.figure()
plt.plot(ideal_list, marker=".", lw = 0.3, label = "Ideal")
plt.plot(adc_list_int, lw = 1, marker = '.', label = "Actual")
plt.ylabel("Codes")
plt.xlabel("Hits")
plt.title("ADC Plot")
plt.legend()
plt.grid(True)
fig3 = plt.figure()
plt.hist(ideal_list, bins = num_codes, rwidth = 0.5, histtype = 'bar', label = "Ideal")
plt.hist(adc_list_int, bins = num_codes, rwidth = 0.3, histtype = 'bar', label = "Actual")
plt.ylabel("Hits")
plt.xlabel("Codes")
plt.title("ADC Histogram")
plt.legend()
plt.grid(True)
fig4 = plt.figure()
plt.plot(range(0, num_codes), dnl_code, lw = 0.6, linestyle = '-', label = "DNL")
plt.ylabel("DNL")
plt.xlabel("Codes")
plt.yticks(fontsize = 8)
plt.xticks(fontsize = 8)
plt.title("Differential Nonlinearity")
plt.grid(True)
fig5 = plt.figure()
plt.plot(range(0, num_codes), inl_code, lw = 0.6, linestyle = '-', label = "INL")
plt.ylabel("INL")
plt.xlabel("Codes")
plt.xticks(fontsize = 8)
plt.yticks(fontsize = 8)
plt.title("Integral Nonlinearity")
plt.grid(True)
fig6 = plt.figure()
plt.plot(sum_ideal_hits_list, range(0, num_codes), label = "Ideal")
plt.plot(sum_count_hits_list, range(0, num_codes), label = "INL")
plt.grid(True)
plt.show()
##------------------------------------------------------------------------------
lbl_hits = tk.Label(frame2, text = "Hits per Code ")
hits_count = st.ScrolledText(frame2, width = 22, height = 10, font = ("Courier", 10))
lbl_dnl_list = tk.Label(frame2, text = "DNL per Code")
dnl_list = st.ScrolledText(frame2, width = 22, height = 10, font = ("Courier", 10))
lbl_dnlmax_list = tk.Label(frame2, text = "Codes with Max. DNL")
dnlmax_list = st.ScrolledText(frame2, width = 14, height = 3, font = ("Courier", 10))
lbl_dnlmin_list = tk.Label(frame2, text = "Codes with Min. DNL")
dnlmin_list = st.ScrolledText(frame2, width = 14, height = 3, font = ("Courier", 10))
lbl_inl_list = tk.Label(frame2, text = "INL per Code")
inl_list = st.ScrolledText(frame2, width = 22, height = 10, font = ("Courier", 10))
lbl_abserr_list = tk.Label(frame2, text = "Absolute Error per Code")
abserr_list = st.ScrolledText(frame2, width = 22, height = 10, font = ("Courier", 10))
lbl_maxabserr_list = tk.Label(frame2, text = "Worst Abs. Error Codes")
maxabserr_list = st.ScrolledText(frame2, width = 14, height = 3, font = ("Courier", 10))
lbl_misscodes_list = tk.Label(frame2, text = "Missing Codes")
misscodes_list = st.ScrolledText(frame2, width = 14, height = 3, font = ("Courier", 10))
label_avehits = tk.Label(window, text = "Average Hits: ")
entry_avehits = tk.Entry(window, width = 13, bg = "white")
entry_avehits.config(justify = tk.CENTER)
label_offseterr = tk.Label(window, text = "Offset Error: ")
entry_offseterr = tk.Entry(window, width = 13, bg = "white")
entry_offseterr.config(justify = tk.CENTER)
label_dnl = tk.Label(window, text = "Maximum DNL: ")
entry_dnl = tk.Entry(window, width = 13, bg = "white")
entry_dnl.config(justify = tk.CENTER)
label_dnlmin = tk.Label(window, text = "Minimum DNL: ")
entry_dnlmin = tk.Entry(window, width = 13, bg = "white")
entry_dnlmin.config(justify = tk.CENTER)
label_inl = tk.Label(window, text = "Worst INL: ")
entry_inl = tk.Entry(window, width = 28, bg = "white")
entry_inl.config(justify = tk.CENTER)
label_abserr = tk.Label(window, text = "Absolute Error: ")
entry_abserr = tk.Entry(window, width = 13, bg = "white")
entry_abserr.config(justify = tk.CENTER)
label_gainerr = tk.Label(window, text = "Gain Error: ")
entry_gainerr = tk.Entry(window, width = 13, bg = "white")
entry_gainerr.config(justify = tk.CENTER)
label_misscode = tk.Label(window, text = "Missing Codes: ")
entry_misscode = tk.Entry(window, width = 13, bg = "white")
entry_misscode.config(justify = tk.CENTER)
btn_browse = tk.Button(frame1, text = "Browse", width = 12, command = open_file)
btn_browse.grid(row = 1, column = 1, padx = 1, sticky = tk.E)
btn_clear = tk.Button(frame1, text = "Restart", width = 12, command = restart_prog)
btn_clear.grid(row = 4, column = 1, padx = 1, sticky = tk.E)
btn_plot = tk.Button(frame1, text = "Run", width = 12, command = plot_data)
btn_plot.grid(row = 5, column = 1, padx = 1, sticky = tk.E)
window.mainloop()