因为毕设在做医疗类产品,想着拓展功能方面想要实现记录先前治疗数据。先前想着用小程序可视化,但无奈前端难度还是有些大,小程序一下想上手发现没那么容易,而后发现python这个好工具。(但想更加方便,家用医疗可能还是小程序方便得多,日后定学!)

存储数据功能实现

首先现在官网下载下python,他的安装有些不一样,在程序窗口里而且全英,可以跟着教程安装。随后安装完成后,先按win+R,输入cmd再按回车进入界面,输入pip install paho-mqtt安装相应库让电脑具备 MQTT 通信能力随后开始编写代码把对电脑通过mqtt协议接收到的数据进行监视存储。

新建一个文件夹(往后存储数据.db形式也会自动放在文件夹中),新建一个文本txt文件,将其改名为save_data.py,后缀需要改为.py。后续打开用继续用记事本打开改代码。代码如下:

import paho.mqtt.client as mqtt
import json
import sqlite3
import time

db_file = 'medical_wave_data.db'
last_save_time = ""  # 放在最顶格

def on_message(client, userdata, msg):
    global last_save_time  # 缩进 4 个空格
    try:
        data = json.loads(msg.payload.decode())
        current_time = time.strftime('%Y-%m-%d %H:%M:%S')
        
        # 防止 1 秒内重复存入
        if current_time == last_save_time:
            return 
        
        last_save_time = current_time 

        conn = sqlite3.connect(db_file)
        cursor = conn.cursor()
        cursor.execute("CREATE TABLE IF NOT EXISTS wave_records (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, freq INTEGER, wave TEXT)")
        cursor.execute("INSERT INTO wave_records (timestamp, freq, wave) VALUES (?, ?, ?)",
                       (current_time, data['freq'], json.dumps(data['data'])))
        cursor.execute("DELETE FROM wave_records WHERE timestamp < datetime('now', 'localtime', '-1 minutes')")
        conn.commit()
        
        cursor.execute("SELECT COUNT(*) FROM wave_records")
        count = cursor.fetchone()[0]
        conn.close()
        
        print(f"[{current_time}] 备份成功!当前总数: {count}")
    except Exception as e:
        print(f"处理数据时出错: {e}")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_message = on_message
client.connect("broker.emqx.io", 1883, 60)
client.subscribe("gdut/test/wave")

print("服务已重新启动,正在监听...")
client.loop_forever()

这里我代码是只保存1min内的数据,到一定数据量后开始删最旧的数据,防止数据太大。进行数据量控制。改时间直接把cursor.execute("DELETE FROM wave_records WHERE timestamp < datetime('now', 'localtime', '-1 minutes')")的'-1 minutes'改成'-1 days'即可。

而后按win+R,输入cmd再按回车进入界面。输入盘的位置,我的是D,所以输入D:然后按回车。然后在输入cd "D:\desktop\新建文件夹\datasaving",引号内为我存储py的文件夹位置,而后在输入python save_data.py,后面为自设的文件名。再按回车就跳至存储模式。

实时数据折线图可视化

先按照先前流程,进入界面直接输入pip install matplotlib回车,安装库。

然后在先前新建的文件夹下再新建一个txt,将其改名为draw_wave.py。

输入代码如下

import sqlite3
import json
import matplotlib.pyplot as plt

# 1. 连接数据库
conn = sqlite3.connect('medical_wave_data.db')
cursor = conn.cursor()

# 2. 取出最新的一条记录
try:
    cursor.execute("SELECT timestamp, wave FROM wave_records ORDER BY id DESC LIMIT 1")
    row = cursor.fetchone()
except Exception as e:
    print(f"数据库读取失败: {e}")
    row = None

conn.close()

if row:
    timestamp, wave_str = row
    wave_data = json.loads(wave_str) # 把存进去的文本转回数字列表
    
    # 3. 开始绘图
    plt.figure(figsize=(10, 5))
    plt.plot(wave_data, marker='o', linestyle='-', color='r', markersize=4)
    plt.title(f"Latest Pulse Waveform ({timestamp})")
    plt.xlabel("Sample Points (0-49)")
    plt.ylabel("ADC Value / Current")
    plt.grid(True)
    
    # 4. 展示图片
    print(f"正在显示时间点 {timestamp} 的波形...")
    plt.show() 
else:
    print("数据库还是空的,请先运行 save_data.py 存入一些数据!")

再按先前步骤,按win+R,输入cmd再按回车进入界面。输入你的盘的位置,我的是D,所以输入D:然后按回车。然后在输入cd "D:\desktop\新建文件夹\datasaving",引号内为我存储py的文件夹位置,而后在输入draw_wave.py,再回车即可得到下图。

然后可以发现,现在的图是具体时刻的一组数据,并非先前的数据全部一起显示出来。这里我一组数据是一个有50个数的数组,所以显示比较多,但实际上只是一组数据,所以这才又引入新的excel整合可视化先前所有数据。

将数据以excel形式表现

这里需要安装两个库pip install pandas,pip install openpyxl,其中pandas负责数据处理,并整理成csv格式的50列数据,openpyxl负责将其整理转化成xlsx格式。

然后再在那个新文件夹下,在新建个txt文本,改后缀为excel_history.py,再像先前一样运行,即可形成excel表格。代码如下:

import sqlite3
import pandas as pd
import json

# 1. 配置参数
db_name = 'medical_wave_data.db'
excel_name = '医疗波形历史数据导出.xlsx'

def export():
    try:
        # 2. 连接数据库并读取
        conn = sqlite3.connect(db_name)
        # 获取所有数据
        df = pd.read_sql_query("SELECT * FROM wave_records ORDER BY timestamp ASC", conn)
        conn.close()

        if df.empty:
            print("数据库目前是空的,没有数据可以导出。")
            return

        # 3. 处理波形数据(把字符串变成 Excel 的多列)
        print("正在解析波形点,请稍候...")
        
        # 定义一个函数:把 JSON 字符串转为 Series (多列)
        def parse_wave(wave_str):
            points = json.loads(wave_str)
            # 给这 50 个点取名:点1, 点2...
            return pd.Series(points, index=[f'Point_{i+1}' for i in range(len(points))])

        # 执行拆分:把原来的 'wave' 列拆掉,变成 50 列新数据
        wave_columns = df['wave'].apply(parse_wave)
        
        # 把时间戳、频率和拆分后的波形拼在一起
        final_df = pd.concat([df[['timestamp', 'freq']], wave_columns], axis=1)

        # 4. 保存为 Excel 文件
        final_df.to_excel(excel_name, index=False)
        print("-" * 30)
        print(f"导出成功!")
        print(f"文件名:{excel_name}")
        print(f"总计导出记录数:{len(final_df)} 条")
        print("-" * 30)

    except Exception as e:
        print(f"导出失败,错误原因: {e}")

if __name__ == "__main__":
    export()

生成表格如下:

更多推荐