当前位置: 首页 > news >正文

多线程显示 CSV 2 PNG 倒计时循环播放

import argparse
import logging
import sys
from pathlib import Path
import time
import os
import pandas as pd
import matplotlib.pyplot as plt
from concurrent.futures import ProcessPoolExecutor, as_completed

# 初始化日志记录
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    handlers=[logging.FileHandler('script.log'), logging.StreamHandler(sys.stdout)])

def process_file(file_path, input_directory, output_directory):
    try:
        # 使用 Pandas 读取 CSV 文件
        data1 = pd.read_csv(file_path)
    except Exception as e:
        logging.error(f"读取文件 {file_path} 时发生错误: {e}")
        return

    # 获取数据的行数和列数
    nRow, nCol = data1.shape

    # 绘制图表
    plt.figure(figsize=(10, 8))
    index = 0
    for i in range(nCol):
        if data1.columns[i] == "datetime":
            continue

        plt.subplot(nCol - 1, 1, index + 1)
        index += 1
        plt.plot(data1.iloc[:, i])
        plt.title(data1.columns[i])

    # 获取当前时间并格式化
    formatted_time = time.strftime('%Y_%m_%d_%H_%M', time.localtime())

    # 修改文件名以包含当前时间,并替换特殊字符
    file_stem = file_path.stem.replace('@', '_').replace(':', '_')
    file_name = formatted_time + '_' + file_stem + '.png'

    # 生成输出路径
    output_path = Path(output_directory) / file_name

    # 保存图像到 Fig 目录
    try:
        plt.savefig(str(output_path))
        logging.info(f"存储图片中... {output_path}")
        plt.close()
    except Exception as e:
        logging.error(f"保存图像 {output_path} 时发生错误: {e}")
        return
    return output_path

def animate_charts(output_directory):
    # 获取最新生成的两个图表文件
    paths = sorted(Path(output_directory).glob('*.png'), key=lambda p: p.stat().st_mtime, reverse=True)
    latest_paths = paths[:2]

    # 设置初始状态
    paused = False

    def on_key_press(event):
        nonlocal paused
        if event.key == ' ':  # 空格键
            paused = not paused
            if paused:
                print("Paused. Press space to continue.")
            else:
                print("Continuing...")

    # 主循环
    while True:
        for path in latest_paths:
            # 显示文件名
            print(f"正在显示文件: {path}")

            if paused:
                plt.connect('key_press_event', on_key_press)
                img = plt.imread(str(path))
                fig, ax = plt.subplots()
                ax.imshow(img)
                ax.axis('off')  # 关闭坐标轴

                creation_time = time.strftime("%Y-%m-%d %H:%M", time.localtime(path.stat().st_ctime))
                ax.set_title(f'File Created at: {creation_time}')

                plt.show(block=False)

                # 显示倒计时
                duration = 55
                text_obj = None
                for remaining in range(duration, 0, -1):
                    if not paused:
                        break
                    time.sleep(1)
                    if text_obj is not None:
                        text_obj.remove()  # 直接移除文本对象
                    text_obj = ax.text(0.5, 0.15, f"Timing: {remaining}s", transform=ax.transAxes, ha='center', va='center', color='red', fontsize=8)
                    fig.canvas.draw_idle()
                    plt.pause(0.001)  # 更新图形界面

                plt.close()

                while paused:
                    time.sleep(0.1)  # 等待恢复
            else:
                img = plt.imread(str(path))
                fig, ax = plt.subplots()
                ax.imshow(img)
                ax.axis('off')  # 关闭坐标轴

                creation_time = time.strftime("%Y-%m-%d %H:%M", time.localtime(path.stat().st_ctime))
                ax.set_title(f'File Created at: {creation_time}')

                plt.show(block=False)

                # 显示倒计时
                duration = 60
                text_obj = None
                for remaining in range(duration, 0, -1):
                    time.sleep(1)
                    if text_obj is not None:
                        text_obj.remove()  # 直接移除文本对象
                    text_obj = ax.text(0.5, 0.15, f"Timing: {remaining}s", transform=ax.transAxes, ha='center', va='center', color='red', fontsize=8)
                    fig.canvas.draw_idle()
                    plt.pause(0.001)  # 更新图形界面

                plt.close()

def main(input_directory, output_directory):
    # 开始运行提示
    logging.info("-----开始运行-----")

    # 定义传感器数据所在的目录
    sensor_dir = Path(input_directory)

    # 获取传感器目录下的所有文件列表
    files = list(sensor_dir.glob('*.csv'))

    # 输出文件列表
    logging.info("即将进行文件读取...")
    for i, f in enumerate(files, start=1):
        logging.info(f"文件读取中 {i}/{len(files)}")
        logging.info(f.name)

    # 定义输出图像的目录
    fig_dir = Path(output_directory)

    # 检查是否存在 Fig 目录,如果不存在则创建
    if not fig_dir.exists():
        try:
            fig_dir.mkdir(parents=True, exist_ok=True)
        except FileExistsError:
            logging.info("目录已存在。")

    # 打印当前时间
    current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    logging.info(f"读取完毕,读取时间: {current_time}  ^_^ 存储图片进行中... ")

    # 使用并行处理
    with ProcessPoolExecutor() as executor:
        futures = []
        for file_path in files:
            future = executor.submit(process_file, file_path, input_directory, output_directory)
            futures.append(future)

        # 等待所有任务完成
        for future in as_completed(futures):
            future.result()

    # 结束提示
    logging.info("存储完毕")

    # 显示最近两张图片
    animate_charts(output_directory)

if __name__ == "__main__":
    # 定义默认配置值
    input_directory = 'C:\\Users\\Administrator\\Desktop\\Sensor'
    output_directory = 'C:\\Users\\Administrator\\Desktop\\Fig'

    # 解析命令行参数
    parser = argparse.ArgumentParser(description="Process CSV files and generate charts.")
    parser.add_argument('--input_directory', type=str, default=input_directory, help='Input directory containing CSV files.')
    parser.add_argument('--output_directory', type=str, default=output_directory, help='Output directory to save generated charts.')
    args = parser.parse_args()

    # 主函数调用
    main(args.input_directory, args.output_directory)


    


http://www.mrgr.cn/news/62250.html

相关文章:

  • 国标GB28181视频平台EasyCVR使用obs推流报错“无法找到主机”是什么原因?
  • 无动画基础如何高效输出虚拟数字人短视频?
  • 循环--基于范围的for循环
  • 重磅新品丨Fortinet 发布 Lacework FortiCNAPP,强化云原生应用安全
  • Android13预置应用及授权开发
  • vue3+vite使用dataV后项目运行报错、页面空白问题
  • Redis 淘汰策略 问题
  • leetcode hot100【LeetCode 230. 二叉搜索树中第K小的元素】java实现
  • DOM---鼠标事件类型(移入移出)
  • Java AQS Semaphore 源码
  • 天润融通突破AI客服局限,三大关键提升文本机器人问答效果
  • [SWPUCTF 2021 新生赛]easy_sql的write up
  • 虚拟机Ubuntu实现和宿主机之间的数据传输(只能复制粘贴,包过)
  • JVM系列之内存布局
  • RK3568平台(PWM篇)红外遥控适配
  • 高效构建仓库AGV管理系统:基于Python的路径规划与货架管理
  • 电动车进入电梯数据集、自行车进入电梯数据集 电动车进入电梯VOC数据标注数据集
  • 带你用Go实现二维码小游戏(中)
  • Java AQS 源码
  • 利用双指针法解题
  • RNN在训练中存在的问题
  • 大模型入门综述---从模型,训练,部署全方面认识大模型
  • 如何解决Matplotlib报错:none of the following families were found: SimHei
  • ReactNative Fabric渲染器和组件(5)
  • 统信UOS下启动图形界面应用工具monitor报JAVA相关错:An error has occurred. See the log file
  • 《高频电子线路》 —— 高频谐振功放