接上一篇文章,由于txt文件的内容太大,前端展示图片比较缓慢,优化后,前端不展示图片,仅仅保存指定分辨率大小的图片,不显示Y轴刻度等;
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from tkinter import *
from tkinter import filedialog
import os
import time
import re
from datetime import datetime
from pylab import mpl
import matplotlib
# matplotlib.use('TkAgg') # 解决serWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figur异常
matplotlib.use('agg') # 前端不展示所绘制的图片
import matplotlib.pyplot as plt
mpl.rcParams["font.sans-serif"] = ["SimHei"] # 设置显示中文字体
mpl.rcParams["axes.unicode_minus"] = False # 设置正常显示符号
"""
out_los_GDHZ.txt文件内容
2024/03/05 05:50:01 sys: 1,prn: 8, f : 0, rr : 22776258.520521, cdts : 9499.326017, dtrpr : 0.000000, ionxr : 16.994414, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 8, f : 0, rr : 22776258.520521, cdts : 9499.326017, dtrpr : 0.000000, ionxr : 16.994414, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 8, f : 1, rr : 22776258.520521, cdts : 9499.326017, dtrpr : 0.000000, ionxr : 30.475578, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 8, f : 1, rr : 22776258.520521, cdts : 9499.326017, dtrpr : 0.000000, ionxr : 30.475578, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 14, f : 0, rr : 23343648.060891, cdts : 102648.741372, dtrpr : 0.000000, ionxr : 19.831918, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 14, f : 0, rr : 23343648.060891, cdts : 102648.741372, dtrpr : 0.000000, ionxr : 19.831918, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 14, f : 1, rr : 23343648.060891, cdts : 102648.741372, dtrpr : 0.000000, ionxr : 35.563990, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 14, f : 1, rr : 23343648.060891, cdts : 102648.741372, dtrpr : 0.000000, ionxr : 35.563990, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 30, f : 0, rr : 21635324.825727, cdts : -127128.592610, dtrpr : 0.000000, ionxr : 14.159144, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
2024/03/05 05:50:01 sys: 1,prn: 30, f : 0, rr : 21635324.825727, cdts : -127128.592610, dtrpr : 0.000000, ionxr : 14.159144, dantr : 0.000000, dantrr[findex] : 0.000000, scb : 0.000000,
"""
# 日志行数
LOG_LINE_NUM = 0
class MY_GUI():
def __init__(self, init_window_name):
self.init_window_name = init_window_name
# 设置窗口
def set_init_window(self):
self.init_window_name.title("电离层绘制工具_v1.0 @wqh") # 窗口名
self.init_window_name.geometry('480x300+10+10') # 290 160为窗口大小,+10 +10 定义窗口弹出时的默认展示位置
# self.init_window_name["bg"] = "pink" # 窗口背景色,其他背景色见:blog.csdn.net/chl0000/article/details/7657887
# self.init_window_name.attributes("-alpha",0.9) #虚化,值越小虚化程度越高
# 标签
self.init_data_label = Label(self.init_window_name, text="请输入展示的卫星片段数")
self.init_data_label.grid(row=0, column=0)
# self.result_data_label = Label(self.init_window_name, text="输出结果")
# self.result_data_label.grid(row=0, column=12)
self.log_label = Label(self.init_window_name, text="日志信息")
self.log_label.grid(row=12, column=0)
# 文本框
self.init_data_Text = Entry(self.init_window_name, width=10) # 卫星颗数录入框
self.init_data_Text.insert(0, "10") # 默认值
self.init_data_Text.grid(row=0, column=0, rowspan=10, columnspan=10)
# self.result_data_Text = Text(self.init_window_name, width=70, height=49) # 处理结果展示
# self.result_data_Text.grid(row=1, column=12, rowspan=15, columnspan=10)
self.log_data_Text = Text(self.init_window_name, width=66, height=14) # 日志框
self.log_data_Text.grid(row=20, column=0, columnspan=10)
# 按钮
self.select_file_button = Button(self.init_window_name, text="选择文件", bg="lightblue", width=10,
command=self.select_file)
self.select_file_button.grid(row=100, column=1)
self.start_drawing_button = Button(self.init_window_name, text="开始绘制", bg="lightblue", width=10,
command=self.start_drawing) # 调用内部方法 加()为直接调用
self.start_drawing_button.grid(row=100, column=5)
# 第一步,去重提取出指定列的数据
def get_sys(self):
# 用于存储去重后的数据
unique_data = set()
with open(self.file_path, 'r') as file:
lines = file.readlines()
# 因数据重复,隔行读取数据
for line in lines[::2]:
# 多个分隔符来分割
temp = re.split("[,| ]+", line)
# 提取指定的多列
selected_columns = [temp[3], temp[5], temp[8]]
# 将选定的列转换为元组,以便用于集合中的去重
selected_columns_tuple = tuple(selected_columns)
# 将元组添加到集合中
unique_data.add(selected_columns_tuple)
# 将集合转换回列表
self.unique_data_list = list(unique_data)
ll = len(self.unique_data_list)
self.write_log_to_Text(f"完成文件的卫星数据筛选,总计{ll}条卫星片段")
# print(self.unique_data_list)
return self.unique_data_list
# 第二步,根据指定的数据再统计、绘图
def start_drawing(self):
try:
# 获取文件的卫星列表
sys = self.get_sys()
lss = len(sys)
# 获取文本框输入的卫星颗数
ef = int(self.init_data_Text.get())
# 取输入的卫星颗数和文件的卫星颗数的小值
ls = ef if ef < lss else lss
with open(self.file_path, 'r') as file:
lines = file.readlines()
# 使用字典推导式生成对应数量的空列表和0,并为它们重新命名
time_lists = {f'time_list_{i}': [] for i in range(ls)}
#rr_lists = {f'rr_list_{i}': [] for i in range(ls)}
#cdts_lists = {f'cdts_list_{i}': [] for i in range(ls)}
#dtrpr_lists = {f'dtrpr_list_{i}': [] for i in range(ls)}
ionxr_lists = {f'ionxr_list_{i}': [] for i in range(ls)}
# count_lists = {f'count_list_{i}': 0 for i in range(ls)}
# 因数据重复,隔行读取数据
for line in lines[::2]:
# 多个分隔符来分割
temp = re.split("[,| ]+", line)
for j in range(0, ls):
if (temp[3] == str(sys[j][0])) & (temp[5] == str(sys[j][1])) & (temp[8] == str(sys[j][2])):
datee = temp[0]
timee = temp[1]
rr = temp[11]
cdts = temp[14]
dtrpr = temp[17]
ionxr = temp[20]
dt = datee + " " + timee
time_list = datetime.strptime(dt, "%Y/%m/%d %H:%M:%S")
time_lists['time_list_' + str(j)].append(time_list)
#rr_lists['rr_list_' + str(j)].append(rr)
#cdts_lists['cdts_list_' + str(j)].append(cdts)
#dtrpr_lists['dtrpr_list_' + str(j)].append(dtrpr)
ionxr_lists['ionxr_list_' + str(j)].append(ionxr)
# count_lists['count_list_' + str(j)] += 1
# print(time_lists['time_list_' + str(j)], ionxr_lists['ionxr_list_' + str(j)])
# 画布设置,figsize属性来改变画布尺寸,dpi属性来改变画布分辨率
plt.figure(figsize=(30, 8), dpi=600)
# 设置x轴标签、y轴标签、标题
plt.xlabel(u"UTC时间")
plt.ylabel(u"电离层系数")
plt.title(u'电离层活跃状况')
# yindex = [-200, -150, -100, -50, 0, 50, 100, 150, 200]
# plt.yticks(xindex, [ionxr_lists['ionxr_list_' + str(m)] for m in xindex]) # 自由显示刻度,xindex存一下要显示的刻度从0开始的下标即可
# plt.yticks(yindex)
# y轴不显示刻度
plt.yticks([])
if ls > 0:
# 开始绘图
self.write_log_to_Text(f"开始绘图,将会展示{ls}条卫星片段,请稍侯...")
# 绘制线形图
for j in range(ls):
# linewidth设置线条宽度
plt.plot(time_lists['time_list_' + str(j)], ionxr_lists['ionxr_list_' + str(j)], linewidth=1)
# print(count_lists['count_list_' + str(j)])
else:
self.write_log_to_Text(f"输入的卫星数不正确,或者文件中没有匹配的卫星,请重试!")
pass
# 保存图片
timestamp = int(time.time())
timestamp_str = str(timestamp)
file_path = os.path.dirname(__file__)
file_path_s = os.path.join(file_path, timestamp_str + '.jpg')
plt.savefig(file_path_s)
self.write_log_to_Text(f"图片存放的位置:{file_path_s}")
# 清理释放内存
plt.clf()
plt.close()
# # 显示图表
# plt.show()
except Exception as e:
self.write_log_to_Text(f"请选择文件,再开始绘图,报错信息:{e}")
# self.select_file()
# 选择文件
def select_file(self):
self.file_path = filedialog.askopenfilename()
# 判断文件名是否包含out_los
if "out_los" in os.path.basename(self.file_path):
# print(f"Selected file: {self.file_path}")
self.write_log_to_Text(f"文件路径: {self.file_path}")
else:
self.write_log_to_Text(f"非out_los文件,请重新选择,原文件路径为: {self.file_path}")
self.select_file()
# return self.file_path
# 获取当前时间
def get_current_time(self):
current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
return current_time
# 日志动态打印
def write_log_to_Text(self, logmsg):
global LOG_LINE_NUM
current_time = self.get_current_time()
logmsg_in = str(current_time) + " " + str(logmsg) + "\n" # 换行
if LOG_LINE_NUM <= 7:
self.log_data_Text.insert(END, logmsg_in)
LOG_LINE_NUM = LOG_LINE_NUM + 1
else:
self.log_data_Text.delete(1.0, 2.0)
self.log_data_Text.insert(END, logmsg_in)
def gui_start():
init_window = Tk() # 实例化出一个父窗口
ZMJ_PORTAL = MY_GUI(init_window)
# 设置根窗口默认属性
ZMJ_PORTAL.set_init_window()
init_window.mainloop() # 父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示
gui_start()
工具界面:
保存的图片: