如何利用Arduino串口数据更新气泡图并实现动态图形刷新?
动态更新气泡图的解决方案
你的代码核心问题是每次循环都会叠加新的散点,没有正确更新旧图形,另外还有几处小问题需要修正。以下是调整后的代码和关键说明:
问题分析
- 每次调用
plt.scatter()会在原有画布上新增点,导致气泡堆积 - 未定义的
i变量会触发报错 - 串口读取的数据可能包含换行符或空值,直接转整数会出错
- 注释掉的
plt.clf()会清除整个画布(包括坐标轴),其实可以更高效地只更新气泡大小
优化后的代码
import serial import matplotlib.pyplot as plt import numpy as np np.random.seed(19680801) colors = np.random.rand(1) # 开启交互模式 plt.ion() fig, ax = plt.subplots() # 先创建一个初始散点,后续只更新它的大小 scatter = ax.scatter(5, 10, s=0, c=colors, alpha=0.5) # 固定坐标轴范围,避免画面跳动 ax.set_xlim(0, 10) ax.set_ylim(0, 20) # 串口初始化 ser = serial.Serial('COM12', 9600) if ser.is_open: ser.close() ser.open() try: while True: # 读取并清洗串口数据,去掉换行和空白字符 data = ser.readline().decode().strip() if not data: continue try: y_val = int(data) print(y_val) # 计算气泡面积并更新散点大小 area = 10 * y_val scatter.set_sizes([area]) # 高效刷新画布 fig.canvas.draw_idle() plt.pause(0.01) except ValueError: # 处理非数字的无效数据 print(f"无效数据: {data}") finally: # 程序退出时关闭资源 ser.close() plt.ioff() plt.close()
关键改进点
- 提前创建单个散点对象,通过
set_sizes()直接更新大小,避免重复绘制 - 固定坐标轴范围,防止每次更新时自动缩放导致画面跳动
- 增加数据校验,处理串口读取到的空行、非数字等无效数据
- 使用
fig.canvas.draw_idle()替代重复调用plt.show(),刷新更高效 - 加入
try-finally块,确保程序退出时关闭串口和绘图窗口
内容的提问来源于stack exchange,提问作者Kasun Thushara
相关产品推荐
相关产品推荐

