You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:47:58