一步一图学信号可视化:用Python绘制多频率信号对比图
一、引言:信号可视化——从抽象到直观的桥梁
在电子通信、振动监测、生物医学等领域,我们经常需要分析不同频率的信号特征。例如:
- 通信系统中,不同频率的载波信号承载着不同信息;
- 机械故障诊断中,异常振动往往对应特定频率的成分;
- 脑电信号(EEG)中,α波(8-13Hz)与放松状态相关,β波(14-30Hz)与活跃思维相关。
然而,原始的信号数据(如一组时间序列的数值)是抽象的,直接阅读数值难以快速获取关键信息。这时候,信号可视化就成了连接数据与认知的桥梁——通过图像直观展示信号的频率、振幅、相位等特征,能大幅降低分析成本。
本文将以三个不同频率的正弦信号为例,手把手教你用Python绘制多信号对比图,并通过调整颜色、线型、标注等细节,让图表既专业又易读。
二、核心概念:正弦信号的数学表达
我们选择最基础的正弦信号作为示例,其数学表达式为:
y ( t ) = A ⋅ sin ( 2 π f t + ϕ ) y(t) = A \cdot \sin(2\pi f t + \phi) y(t)=A⋅sin(2πft+ϕ)
其中:
- ( A ):振幅(信号的最大波动幅度)
- ( f ):频率(每秒完成的周期数,单位Hz)
- ( t ):时间(单位秒)
- ( \phi ):相位(决定信号的起始位置)
本文中,我们固定振幅 ( A=1 )、相位 ( \phi=0 ),仅改变频率 ( f ),生成三个信号:
- 信号1:( f_1=1\text{Hz} )(低频)
- 信号2:( f_2=2\text{Hz} )(中频)
- 信号3:( f_3=5\text{Hz} )(高频)
三、实战步骤:用Python绘制多频率信号图
3.1 环境准备与库导入
我们需要使用以下Python库:
numpy
:生成时间序列和信号数据matplotlib
:绘制图表
import numpy as np
import matplotlib.pyplot as plt
3.2 生成信号数据
步骤1:定义时间轴
为了清晰展示信号的周期性,我们选择时间范围 ( t \in [0, 2]\text{秒} )(覆盖高频信号的10个周期),并设置足够高的采样率(根据奈奎斯特采样定理,采样率需至少为信号最高频率的2倍)。这里我们取采样率 ( \text{Fs}=100\text{Hz} )(即每秒采集100个点)。
# 时间参数设置
t_start = 0 # 起始时间(秒)
t_end = 2 # 结束时间(秒)
Fs = 100 # 采样率(Hz)
t = np.linspace(t_start, t_end, int(Fs*(t_end - t_start))) # 时间序列
步骤2:生成三个频率的正弦信号
根据正弦公式,生成三个信号的数值序列:
# 信号参数
A = 1 # 振幅
phi = 0 # 相位# 生成信号
y1 = A * np.sin(2 * np.pi * 1 * t + phi) # 1Hz信号
y2 = A * np.sin(2 * np.pi * 2 * t + phi) # 2Hz信号
y3 = A * np.sin(2 * np.pi * 5 * t + phi) # 5Hz信号
3.3 绘制多信号对比图
关键绘图参数说明:
- 颜色:使用高对比度颜色(如红色、蓝色、绿色)区分不同信号;
- 线型:通过实线(
-
)、虚线(--
)、点划线(-.
)增强可区分性; - 标签:为每条曲线添加标签,用于生成图例;
- 网格:添加浅灰色网格线,辅助读取数值;
- 坐标轴标签:明确横纵坐标含义(时间/秒,振幅);
- 标题:简洁概括图表内容。
# 创建画布
plt.figure(figsize=(12, 6)) # 画布尺寸(宽12英寸,高6英寸)# 绘制三条信号曲线
plt.plot(t, y1, color='red', linestyle='-', linewidth=2, label='1Hz信号')
plt.plot(t, y2, color='blue', linestyle='--', linewidth=2, label='2Hz信号')
plt.plot(t, y3, color='green', linestyle='-.', linewidth=2, label='5Hz信号')# 添加图例(显示标签)
plt.legend(fontsize=12, loc='upper right') # 图例位置:右上角# 设置坐标轴标签
plt.xlabel('时间 (秒)', fontsize=14) # 横轴:时间,单位秒
plt.ylabel('振幅', fontsize=14) # 纵轴:信号振幅# 设置标题
plt.title('不同频率正弦信号对比图', fontsize=16, fontweight='bold')# 添加网格(浅灰色虚线)
plt.grid(linestyle='--', alpha=0.6, color='lightgray')# 设置坐标轴刻度字体大小
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)# 显示图表
plt.show()
3.4 输出结果与解读
运行代码后,将得到如下图表:
关键观察:
- 频率与周期的关系:频率越高,信号完成一个周期的时间越短。例如,1Hz信号周期为1秒(2秒内完成2个周期),5Hz信号周期为0.2秒(2秒内完成10个周期);
- 线型与颜色的区分:即使信号部分重叠(如1Hz与2Hz在t=0.5秒附近),不同的颜色和线型仍能清晰区分;
- 网格的作用:通过网格线可快速读取特定时间点的振幅值(如t=1秒时,1Hz信号振幅为0,2Hz信号振幅为0,5Hz信号振幅为0)。
四、细节优化:让图表更专业
4.1 颜色选择的注意事项
- 避免使用色盲友好度低的颜色组合(如红绿搭配),可通过ColorBrewer工具验证;
- 深色背景下使用浅色线条(如白色、黄色),浅色背景下使用深色线条(如深蓝、深绿)。
4.2 线型的最佳实践
- 常用线型:实线(
-
)、虚线(--
)、点划线(-.
)、点线(:
); - 避免同时使用过多线型(一般不超过4种),否则会降低可读性。
4.3 标签与图例的优化
- 标签内容应包含关键参数(如频率值);
- 图例位置避免遮挡信号(如选择
loc='upper right'
或loc='lower left'
); - 可通过
bbox_to_anchor
参数微调图例位置(如plt.legend(bbox_to_anchor=(1.05, 1))
将图例放在图表右侧)。
五、扩展:绘制其他类型的信号
除了正弦信号,我们还可以绘制方波、三角波等其他类型的信号。以下是一个方波绘制的示例(使用scipy
库的signal.square
函数):
from scipy import signal# 生成5Hz方波信号(占空比0.5)
y_square = signal.square(2 * np.pi * 5 * t)# 绘制方波与正弦波对比图
plt.figure(figsize=(12, 6))
plt.plot(t, y3, color='green', linestyle='-.', linewidth=2, label='5Hz正弦波')
plt.plot(t, y_square, color='purple', linestyle=':', linewidth=2, label='5Hz方波')
plt.legend(fontsize=12)
plt.xlabel('时间 (秒)', fontsize=14)
plt.ylabel('振幅', fontsize=14)
plt.title('正弦波与方波对比(5Hz)', fontsize=16)
plt.grid(linestyle='--', alpha=0.6, color='lightgray')
plt.show()
六、总结
本文通过详细的步骤和代码示例,演示了如何用Python绘制多个不同频率的信号对比图。核心要点包括:
- 信号生成:利用
numpy
生成时间序列和正弦信号; - 绘图设置:通过颜色、线型、标签区分不同信号;
- 细节优化:添加网格、调整坐标轴标签和图例,提升图表专业性。
信号可视化是工程分析和科学研究的基础技能,掌握本文方法后,你可以进一步探索:
- 带噪声的信号绘制(添加
np.random.normal
噪声); - 多子图绘制(同时展示时域和频域特征);
- 动态信号绘制(使用
matplotlib.animation
实现实时更新)。
完整代码:
import numpy as np
import matplotlib.pyplot as plt# 生成时间序列
t_start, t_end, Fs = 0, 2, 100
t = np.linspace(t_start, t_end, int(Fs*(t_end - t_start)))# 生成三个频率的正弦信号
y1 = np.sin(2 * np.pi * 1 * t) # 1Hz
y2 = np.sin(2 * np.pi * 2 * t) # 2Hz
y3 = np.sin(2 * np.pi * 5 * t) # 5Hz# 绘制对比图
plt.figure(figsize=(12, 6))
plt.plot(t, y1, 'r-', linewidth=2, label='1Hz信号')
plt.plot(t, y2, 'b--', linewidth=2, label='2Hz信号')
plt.plot(t, y3, 'g-.', linewidth=2, label='5Hz信号')plt.xlabel('时间 (秒)', fontsize=14)
plt.ylabel('振幅', fontsize=14)
plt.title('不同频率正弦信号对比图', fontsize=16, fontweight='bold')
plt.grid(linestyle='--', alpha=0.6, color='lightgray')
plt.legend(fontsize=12)
plt.show()
动手运行代码,你会看到三个频率不同的信号在同一图表中清晰呈现——这就是信号可视化的魅力!