如何用Python绘制模拟示波器输出的连续正弦波?
嘿,我完全懂你想纯Python模拟示波器显示连续正弦波的需求——不用对接真实硬件,就靠生成数据来还原那种实时滚动的效果对吧?之前我也折腾过类似的模拟,结合你的参数(1MHz正弦波、200MHz-1GS/s采样率、微秒级时间轴),给你拆解下关键步骤和可能踩的坑:
第一步:先理清楚核心参数逻辑
首先得明确几个关键数值的关系,避免生成的数据不符合示波器的显示逻辑:
- 采样率选中间值比如500MHz就行(在200M-1G区间内,既保证每个周期足够采样点,又不会让数据量过大导致卡顿)
- 1MHz正弦波意味着每1微秒完成一个周期,所以我们的时间轴用微秒单位刚好能清晰看到完整周期
- 振幅1V,所以电压范围在-1V到1V之间
第二步:生成基础正弦波数据(静态验证)
先从静态绘图开始,确保数据生成没问题,再搞连续动画。用numpy生成时间数组和正弦波数据,代码如下:
import numpy as np import matplotlib.pyplot as plt # 固定参数设置 sampling_rate = 500e6 # 500MHz采样率 freq = 1e6 # 1MHz正弦波 amplitude = 1 # 1V振幅 total_duration = 10e-6 # 生成10微秒的数据,刚好显示10个完整周期 # 计算采样间隔和总采样点数 sample_interval = 1 / sampling_rate num_samples = int(total_duration / sample_interval) # 生成时间轴(转成微秒更直观) time_us = np.linspace(0, total_duration * 1e6, num_samples) # 生成正弦波数据 sin_wave = amplitude * np.sin(2 * np.pi * freq * (time_us / 1e6)) # 静态绘图 plt.figure(figsize=(10, 4)) plt.plot(time_us, sin_wave, linewidth=1.5) plt.xlabel('时间 (μs)') plt.ylabel('电压 (V)') plt.title('1MHz正弦波模拟显示(10个周期)') plt.grid(True, linestyle='--', alpha=0.7) plt.xlim(0, 10) # 限制x轴到10微秒 plt.ylim(-1.1, 1.1) # 给上下留点余量 plt.show()
运行这段代码应该能看到10个整齐的正弦波周期,要是这里出问题,大概率是时间轴单位没转对(比如忘了把秒转微秒),或者采样点数计算错误。
第三步:实现连续滚动的示波器效果
静态图搞定后,就可以模拟示波器的实时滚动显示了。这里用matplotlib的FuncAnimation来实现,每次更新一小段数据,然后滚动显示最近的几个微秒内容:
from matplotlib.animation import FuncAnimation # 初始化画布和坐标轴 fig, ax = plt.subplots(figsize=(10, 4)) line, = ax.plot([], [], linewidth=1.5) ax.set_xlabel('时间 (μs)') ax.set_ylabel('电压 (V)') ax.set_title('连续滚动的1MHz正弦波模拟') ax.grid(True, linestyle='--', alpha=0.7) ax.set_xlim(0, 5) # 固定显示最近5微秒的内容 ax.set_ylim(-1.1, 1.1) # 初始化函数,清空数据 def init(): line.set_data([], []) return line, # 动画更新函数,模拟实时采样 def update(frame): # 每次生成1微秒的新数据 new_duration_us = 1 new_samples = int((new_duration_us / 1e6) * sampling_rate) # 计算新数据的时间轴(基于当前frame) new_time_us = np.linspace(frame * new_duration_us, (frame+1)*new_duration_us, new_samples) new_wave = amplitude * np.sin(2 * np.pi * freq * (new_time_us / 1e6)) # 获取当前已显示的数据,追加新数据 current_time = line.get_xdata() current_wave = line.get_ydata() updated_time = np.append(current_time, new_time_us) updated_wave = np.append(current_wave, new_wave) # 只保留最近5微秒的数据,实现滚动效果 mask = updated_time >= (updated_time[-1] - 5) line.set_data(updated_time[mask], updated_wave[mask]) return line, # 启动动画,interval控制更新速度(单位毫秒,这里设10ms接近实时感) ani = FuncAnimation(fig, update, init_func=init, interval=10, blit=True, save_count=100) plt.show()
可能踩的坑和优化建议
- 采样率过高导致卡顿:如果选1GS/s,每个微秒有1000个采样点,数据量太大动画会卡。可以适当降采样(比如每2个点取一个),或者增大每次更新的时间窗口(比如每次更新2微秒的数据)
- 混叠问题:虽然你的采样率远高于奈奎斯特频率(2MHz),但如果不小心选了低于2MHz的采样率,会出现混叠波形,一定要确保采样率≥2倍信号频率
- 动画更新不流畅:可以把
blit=True打开,减少重绘区域;也可以调整interval参数,平衡显示流畅度和真实感
内容的提问来源于stack exchange,提问作者Imas
相关产品推荐
相关产品推荐

