如何用Python的Matplotlib从示波器CSV自动绘制1-2个周期正弦波
自动提取示波器CSV中1-2个正弦波周期的解决方案
问题分析
手动阈值定位效率极低,而用最小正数值作为阈值的方案失效,核心原因是该阈值只能筛选接近零点的零散数据点,无法准确定位完整周期的起止边界。最优方案是通过上升沿过零点检测自动识别周期起始位置,无需任何手动参数调整。
实现思路
- 检测上升沿过零点:找到CH1信号从负值切换到正值的位置,这些点就是正弦波每个周期的起始点。
- 确定周期范围:取前2个(或1个)过零点之间的区间,即可得到完整的1-2个周期数据。
- 提取并绘制数据:根据定位的区间提取时间和振幅数据,完成绘图。
完整代码实现
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 读取示波器CSV数据,跳过表头行(根据实际CSV格式调整skiprows) df = pd.read_csv("tek0000.csv", skiprows=20) time = df['TIME'].values ch1 = df['CH1'].values # 1. 检测上升沿过零点:信号从负变正的位置 # 标记所有符号变化的点 sign_changes = np.where(np.diff(np.sign(ch1)))[0] # 筛选上升沿(前一个点为负,后一个点为正) rising_zero_crossings = [idx for idx in sign_changes if ch1[idx] < 0 and ch1[idx+1] > 0] # 2. 提取1-2个周期的区间 if len(rising_zero_crossings) >= 2: # 取1个周期 start_idx = rising_zero_crossings[0] end_idx = rising_zero_crossings[1] elif len(rising_zero_crossings) >= 3: # 取2个周期 start_idx = rising_zero_crossings[0] end_idx = rising_zero_crossings[2] else: raise ValueError("数据中检测到的上升沿过零点不足,无法提取完整周期") # 3. 提取对应区间的时间和振幅数据 selected_time = time[start_idx:end_idx] selected_ch1 = ch1[start_idx:end_idx] # 绘图 plt.plot(selected_time, selected_ch1) plt.title('1-2个周期的正弦波') plt.xlabel('时间') plt.ylabel('CH1振幅') plt.grid(True, which='both') plt.axhline(y=0, color='k') plt.show()
代码说明
- 过零点检测:用
np.diff(np.sign(ch1))捕捉信号符号变化的位置,再筛选出从负到正的上升沿,这些点是正弦波周期的准确起始点。 - 鲁棒性处理:增加过零点数量判断,避免数据不足时出现错误。
- 无手动参数:整个过程无需设置振幅阈值,完全自动适配不同幅值的正弦波数据。
补充优化建议
- 如果CSV存在噪声,可先对CH1数据做平滑处理(比如用
np.convolve做滑动平均),再进行过零点检测,提升稳定性。 - 批量处理20组数据时,可将上述逻辑封装成函数,循环遍历所有CSV文件即可。
内容的提问来源于stack exchange,提问作者Tam
相关产品推荐
相关产品推荐

