本人编程外行,代码可以在解释器里正常运行,但无法利用pyinstaller对代码封装,封装过程中报错“UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 375: invalid continuation byte”,不大清楚错误在哪,急需各位大神的帮助。完整代码如下
*******************************************************************************
import tkinter as tk
from tkinter import filedialog, dialog
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.pylab import mpl
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import os
import matplotlib.colors
import heapq
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
mpl.rcParams['axes.unicode_minus'] = False # 负号显示
##########窗口设置
window = tk.Tk()
window.title('局部放电聚类分析软件') # 标题
window.geometry('1000x550') # 窗口尺寸
l = tk.Label(window, text='局部放电聚类分析软件', bg='#5F9EA0', font=('宋体', 12), width=50, height=2).place(x=500,y=0,anchor='n')
text_operation = '''操作步骤:
1.选择想要分析的TF谱图文件
2.选择与TF谱图同时间的PRPD文件
3.根据显示的TF谱图确定聚类个数
4.点击“进行聚类”得到聚类结果
(注:可设置的最大聚类数为7)
'''
l2 = tk.Label(window, text=text_operation,justify='left',font=('宋体', 11), width=30, height=6).place(x=0,y=0,anchor='nw')
#########################################################################################聚类分析相关函数
# 计算各点间距离、各点点密度(局部密度)大小
def get_point_density(datas,labers,min_distance,points_number):
# 将numpy.ndarray格式转为list格式,并定义元组大小
data = datas.tolist()
laber = labers.tolist()
distance_all = np.random.rand(points_number,points_number)
point_density = np.random.rand(points_number)
# 计算得到各点间距离
for i in range(points_number):
for n in range(points_number):
distance_all[i][n] = np.sqrt(np.square(data[i][0]-data[n][0])+np.square(data[i][1]-data[n][1]))
# 计算得到各点的点密度
for i in range(points_number):
x = 0
for n in range(points_number):
if distance_all[i][n] > 0 and distance_all[i][n]< min_distance:
x = x+1
point_density[i] = x
return distance_all, point_density
def get_max_distance(distance_all,point_density,laber):
point_density = point_density.tolist()
a = int(max(point_density))
b = laber[point_density.index(a)]
c = max(distance_all[b])
return c
# 计算得到各点的聚类中心距离
def get_each_distance(distance_all,point_density,data,laber):
nn = []
for i in range(len(point_density)):
aa = []
for n in range(len(point_density)):
if point_density[i] < point_density[n]:
aa.append(n)
# print("大于自身点密度的索引",aa,type(aa))
ll = get_min_distance(aa,i,distance_all, point_density,data,laber)
nn.append(ll)
return nn
# 获得:到点密度大于自身的最近点的距离
def get_min_distance(aa,i,distance_all, point_density,data,laber):
min_distance = []
"""
如果传入的aa为空,说明该点是点密度最大的点,该点的聚类中心距离计算方法与其他不同
"""
if aa != []:
for k in aa:
min_distance.append(distance_all[i][k])
return min(min_distance)
else:
max_distance = get_max_distance(distance_all, point_density, laber)
return max_distance
#####################
######################原始分布图显示
def open_file():
'''
打开文件
:return:
'''
global file_path
global file_text
global new_array
global labels_list
global distance_all
global point_density
global nn
global min_distance
global points_number
file_path = filedialog.askopenfilename(title=u'Select file')
if file_path is not None:
with open(file=file_path, mode='r+', encoding='ansi') as file:
file_text = file.read()
a = file_text
b = a.split("\n")
del b[0]
new_list = []
for i in range(len(b)-1):
temp_list = []
b1 = b[i].split("\t")
temp_list.append(float(b1[0]))
temp_list.append(float(b1[1]))
new_list.append(temp_list)
#print(new_list)
new_array = np.array(new_list)
labels = []
for i in range(len(new_array)):
labels.append(i)
min_distance =np.ceil(0.012*len(new_array)) # 邻域半径
points_number = len(new_array) # 随机点个数
labels_list= np.array(labels,dtype="int")
distance_all, point_density = get_point_density(new_array, labels_list, min_distance, points_number)
nn = get_each_distance(distance_all, point_density, new_array, labels_list)
nn_array = np.array(nn)
rr = nn_array*point_density
rr_list =rr.tolist()
colors1 = '#00CED1' #点的颜色
area = np.pi * 4**2 # 点面积
# 画散点图
f = Figure(figsize=(3.5,3.5), dpi=100)
a = f.add_subplot(111)
a.scatter(new_array[:,0], new_array[:,1], s=area, c=colors1, alpha=0.4)
a.set_xlabel('等效时宽/ns')
a.set_ylabel('等效频宽/MHz')
a.set_title('原始数据分布')
#figure =plt.scatter(new_array[:,0], new_array[:,1], s=area, c=colors1, alpha=0.4, label='label A')
canvas = FigureCanvasTkAgg(f,master=window)
canvas.draw()
canvas.get_tk_widget().place(x=0,y=120,anchor='nw')
#text1.insert('insert', file_text)
#############################PRPD文件打开
def open_file2():
'''
打开文件
:return:
'''
global new_array_PRPD
file_path = filedialog.askopenfilename(title=u'Select file')
print('打开文件:', file_path)
if file_path is not None:
with open(file=file_path, mode='r+', encoding='ansi') as file:
file_text = file.read()
a = file_text
b = a.split("\n")
del b[0]
new_list = []
for i in range(len(b)-1):
temp_list = []
b1 = b[i].split("\t")
temp_list.append(float(b1[0]))
temp_list.append(float(b1[1]))
new_list.append(temp_list)
#print(new_list)
new_array_PRPD = np.array(new_list)
###########################聚类数输入
entry = tk.Entry(window,width=15) #文本输入框
entry.place(x=500,y=50,anchor='n')
def change_state():
global Cluster_num
Cluster_num = entry.get() # 调用get()方法,将Entry中的内容获取出来
print(Cluster_num)
######################################################聚类算法编成函数
def getListMaxNumIndex(num_list,topk=3):
max_num=heapq.nlargest(topk,num_list)
max_num_index = []
for j in max_num:
for i in range(len(num_list)):
if num_list[i] ==j:
if i not in max_num_index:
max_num_index.append(i)
return max_num_index
def getListMinNumIndex(num_list,topk=3):
min_num=heapq.nsmallest(topk,num_list)
min_num_index = []
for i in min_num:
tempvar = num_list.index(i)
min_num_index.append(tempvar)
return min_num_index
def clustrt():
global rr_list
nn_array = np.array(nn)
rr = nn_array*point_density
rr_list =rr.tolist()
max_index = getListMaxNumIndex(rr_list,int(Cluster_num))
#print(max_index)
distance_all_list = distance_all.tolist()
class_list = [] #生成一个三个空的子列表,用于存放每个点对于的索引
for i in range(len(max_index)):
tempcalss_list = []
class_list.append(tempcalss_list)
distance_list = [] #用于存放每个点到三个聚类中心点的距离
for i in range(len(distance_all_list)):
temp_list =[]
for j in range(len(max_index)):
temp_list.append(distance_all_list[i][max_index[j]])
distance_list.append(temp_list)
for i in range(len(distance_list)): #选出每个点到三个聚类中心点的距离的最小值索引,得到分类索引
temp_class = getListMinNumIndex(distance_list[i],1)
class_list[temp_class[0]].append(i)
class_data = [] #根据分类索引,将数据集进行分类
for i in range(len(class_list)):
list_temp = []
for j in class_list[i]:
list_temp.append(new_array[j].tolist())
class_data.append(list_temp)
class_num =[]
for i in range(len(class_data)):
class_num.append(len(class_data[i]))
class_data_PRPD = [] #根据分类索引,将PRPD数据集进行分类
for i in range(len(class_list)):
list_temp = []
for j in class_list[i]:
list_temp.append(new_array_PRPD[j].tolist())
class_data_PRPD.append(list_temp)
f2 = Figure(figsize=(3.5, 3.5), dpi=100)
b = f2.add_subplot(111)
#list_c = class_data[0]
#array_c = np.array(list_c)
area = np.pi * 4**2 # 点面积
colors1 = '#00CED1' #点的颜色
colors2 = '#DC143C'
colors3 = '#006400'
colors4 = '#7FFF00'
colors5 = '#A52A2A'
colors6 = '#000000'
colors7 = '#DEB887'
colors_list = [colors1,colors2,colors3,colors4,colors5,colors6,colors7]
for i in range(len(class_data)):
temp_array = np.array(class_data[i])
b.scatter(temp_array[:,0], temp_array[:,1], s=area, c=colors_list[i], alpha=0.4, label='类别 %d'%(i))
b.legend()
b.set_xlabel('等效时宽/ns')
b.set_ylabel('等效频宽/MHz')
b.set_title('聚类结果')
canvas = FigureCanvasTkAgg(f2,master=window)
canvas.draw()
canvas.get_tk_widget().place(x=500,y=120,anchor='n')
f3 = Figure(figsize=(3.9, 3.5), dpi=100)
c = f3.add_subplot(111)
for i in range(len(class_data_PRPD)):
temp_array = np.array(class_data_PRPD[i])
c.scatter(temp_array[:,1], temp_array[:,0], s=area, c=colors_list[i], alpha=0.4, label='类别 %d'%(i))
c.legend()
c.set_xlabel('相位/°')
c.set_ylabel('放电幅值/mV')
c.set_title('PRPD谱图')
c.set_xlim(0, 360)
canvas = FigureCanvasTkAgg(f3,master=window)
canvas.draw()
canvas.get_tk_widget().place(x=840,y=120,anchor='n')
for i in range(len(class_num)):
text1.insert('insert','类别%d 样本数%d '%(i,class_num[i]))
#################################################################
text1 = tk.Text(window, width=50, height=4, bg='#5F9EA0', font=('宋体', 12))
text1.place(x=500,y=550,anchor='s')
#####################################
bt_openfile = tk.Button(window, text='选择TF文件', width=15, height=1,command=open_file).place(x=330,y=50,anchor='n')
bt_openfile_2 = tk.Button(window, text='选择PRPD文件', width=15, height=1,command=open_file2).place(x=330,y=80,anchor='n')
bt_CN= tk.Button(window,text='确定聚类数', width=15, height=1,command=change_state).place(x=500,y=80,anchor='n')
bt_c = tk.Button(window,text='进行聚类', width=15, height=2,command=clustrt).place(x=670,y=55,anchor='n')
if __name__ =='__main__':
#设定初始目录为桌面
window.mainloop() # 显示