一、误差线图
一、误差线的本质与含义
误差线图(Error Bars)是一种在数据点上下(或左右)添加线段的图表,用于直观展示数据的不确定性、误差范围或置信区间。它在科学实验、统计分析等场景中非常实用,能帮助读者理解数据的可靠性。
误差线并非简单的装饰,它承载着数据可靠性的关键信息,常见的误差表示方式及其适用场景:
-
标准差(Standard Deviation, SD)
描述数据本身的离散程度,反映数据点与均值的平均距离。
适用场景:展示一组数据的自然波动(如重复测量的实验数据分布)。
计算方式:np.std(data, ddof=1)(样本标准差,ddof=1表示自由度为 n-1)。 -
标准误(Standard Error of the Mean, SEM)
描述均值的抽样误差,反映均值的可靠程度(标准误越小,均值越可信)。
适用场景:比较不同组的均值差异(如对照组与实验组的效果对比)。
计算方式:SEM = SD / √n(n 为样本量)。 -
置信区间(Confidence Interval, CI)
通常取 95% 置信区间,表示 “真实均值有 95% 概率落在该区间内”。
适用场景:需要量化均值估计可靠性的统计分析。
计算方式:CI = SEM × t临界值(小样本用 t 分布,大样本可用 1.96 近似)。 -
自定义误差
如仪器测量误差、人为设定的允许误差范围(如 ±0.5),适用于已知固定误差来源的场景。
二、误差线图的核心参数与视觉设计
plt.errorbar() 函数的参数众多,合理设置可显著提升图表可读性,重点参数详解:
| 参数 | 作用 | 实用设置示例 |
|---|---|---|
fmt | 数据点和连线样式 | 'o-'(圆形点 + 实线)、'^--'(三角形点 + 虚线) |
yerr/xerr | 误差范围 | 标量(统一误差)、数组(每个点单独误差) |
ecolor | 误差线颜色 | 'red'、'#FF5733'(与数据点区分开) |
elinewidth | 误差线宽度 | 1.5(避免过细看不清) |
capsize | 误差线末端横线长度 | 3~6(过短不明显,过长显杂乱) |
capthick | 误差线末端横线厚度 | 与 elinewidth 保持一致或略粗 |
markersize | 数据点大小 | 5~10(根据画布尺寸调整) |
markerfacecolor | 数据点填充色 | 'white'(配合边缘色增强对比度) |
视觉设计原则
- 误差线颜色应与数据点 / 连线有区分(如数据用蓝色,误差线用红色),但避免过于刺眼。
- 误差线末端的横线(caps)必须保留,否则难以区分误差线方向和范围。
- 当数据点密集时,可通过
errorevery=N参数设置 “每隔 N 个点显示误差线”,避免图表拥挤。
基本语法
Matplotlib 中使用 plt.errorbar() 函数绘制误差线图,基本语法:
plt.errorbar(x, y, yerr=None, xerr=None, fmt='', ...)
x,y:数据点的坐标yerr:y 轴方向的误差范围(可以是标量或数组)xerr:x 轴方向的误差范围(可选)fmt:数据点和连线的样式格式(与plt.plot()相同)
常见参数说明
capsize:误差线末端横线的长度capthick:误差线末端横线的粗细elinewidth:误差线的线宽ecolor:误差线的颜色errorevery:指定每隔多少个点绘制误差线(大数据集时有用)
三、实验与多组数据对比
1.温度对化学反应速率影响的误差线图绘制示例
下面是一个展示不同温度下实验数据及其误差范围的示例:
temperature = np.arange(10, 60, 10) # 温度:10,20,30,40,50
reaction_rate = [2.1, 3.8, 5.2, 4.9, 3.5] # 反应速率
rate_error = [0.3, 0.5, 0.4, 0.6, 0.3]
temperature:生成 10 到 50°C 的温度数据(间隔 10°C)reaction_rate:对应各温度下的反应速率数据rate_error:每个数据点的误差范围(可能是标准差或标准误)
plt.errorbar(
temperature, reaction_rate, # 数据点坐标
yerr=rate_error, # y方向误差
fmt='o-', # 数据点样式(o)和连线样式(-)
ecolor='red', # 误差线颜色
elinewidth=2, # 误差线宽度
capsize=5, # 误差线末端横线长度
capthick=2, # 误差线末端横线厚度
markersize=8, # 数据点大小
markerfacecolor='white', # 数据点填充色
markeredgewidth=2, # 数据点边缘宽度
label='反应速率'
plt.errorbar()函数用于绘制带误差线的图表,主要参数包括:yerr=rate_error:指定 y 轴方向的误差范围fmt='o-':设置数据点为圆形 ('o') 并使用实线 ('-') 连接- 误差线样式设置:颜色 (red)、宽度 (2)、末端横线长度 (capsize=5) 等
- 数据点样式设置:大小 (8)、填充色 (white)、边缘宽度 (2) 等

- 折线与数据点:蓝色折线连接着不同温度对应的反应速率数据点(蓝色圆点),直观呈现反应速率随温度变化的趋势。可以看到,反应速率随温度升高先上升,在 30°C 左右达到峰值后,又随温度继续升高而下降。
- 误差线:每个数据点旁的红色竖线是误差线,用于表示对应温度下反应速率数据的不确定性(比如可能是实验测量的误差范围等),误差线的长度反映了数据的离散程度或误差大小。
完整代码
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
temperature = np.arange(10, 60, 10) # 温度:10,20,30,40,50
reaction_rate = [2.1, 3.8, 5.2, 4.9, 3.5] # 反应速率
# 误差范围(可以是标准差、标准误等)
rate_error = [0.3, 0.5, 0.4, 0.6, 0.3]
# 创建画布
plt.figure(figsize=(10, 6))
# 绘制误差线图
plt.errorbar(
temperature, reaction_rate, # 数据点坐标
yerr=rate_error, # y方向误差
fmt='o-', # 数据点样式(o)和连线样式(-)
ecolor='red', # 误差线颜色
elinewidth=2, # 误差线宽度
capsize=5, # 误差线末端横线长度
capthick=2, # 误差线末端横线厚度
markersize=8, # 数据点大小
markerfacecolor='white', # 数据点填充色
markeredgewidth=2, # 数据点边缘宽度
label='反应速率'
)
# 添加图表元素
plt.title('不同温度下的化学反应速率', fontsize=14)
plt.xlabel('温度 (°C)', fontsize=12)
plt.ylabel('反应速率', fontsize=12)
plt.grid(alpha=0.3) # 网格线(透明度0.3)
plt.legend(fontsize=12)
# 设置坐标轴范围
plt.xlim(5, 55)
plt.ylim(0, 7)
# 显示图表
plt.tight_layout() # 自动调整布局
plt.show()
2. 分组误差线图(多组数据对比)
当需要对比多组数据的误差时,可结合偏移坐标避免重叠,清晰展示组间差异:
# 三组实验数据
groups = ['A', 'B', 'C']
x = np.arange(len(groups)) # 组坐标:0,1,2
# 每组的均值和误差(标准差)
means = [2.5, 4.2, 3.1]
errors = [0.4, 0.6, 0.3]
# 为了对比更清晰,添加一组对照数据
means_control = [3.0, 3.8, 2.7]
errors_control = [0.3, 0.5, 0.4]
# 坐标偏移(避免两组点重叠)
offset = 0.2
plt.figure(figsize=(10, 6))
- 定义三组实验类别(A、B、C)
- 生成 x 轴坐标(0、1、2)对应三个组别
- 准备实验组的均值数据
means和误差范围errors - 准备对照组的均值数据
means_control和误差范围errors_control - 设置一个偏移量
offset,用于在水平方向上错开两组数据点,避免重叠(使对比更加清晰直观)
# 绘制实验组
plt.errorbar(
x - offset, means, yerr=errors,
fmt='o-', capsize=5, label='实验组',
color='blue', markerfacecolor='white'
)
# 绘制对照组
plt.errorbar(
x + offset, means_control, yerr=errors_control,
fmt='s--', capsize=5, label='对照组',
color='green', markerfacecolor='white'
)
- 绘制实验组数据:
- x 坐标向左偏移
offset(x - offset) - 使用蓝色圆形标记点和实线连接(
fmt='o-') - 白色填充的圆形标记,带误差线和末端横线
- x 坐标向左偏移
- 绘制对照组数据:
- x 坐标向右偏移
offset(x + offset) - 使用绿色方形标记点和虚线连接(
fmt='s--') - 白色填充的方形标记,同样带误差线和末端横线
- x 坐标向右偏移

- 横轴(X 轴):代表 “实验组别”,包含 A、B、C 三组,是分组对比的依据。
- 纵轴(Y 轴):代表 “测量结果”,数值体现测量的量化产出。
- 实验组(蓝色实线、圆形标记):
- 折线走势:在 A 组测量结果约为 2.5,B 组上升至约 4.2,C 组下降到约 3.1,整体呈现先升后降的趋势。
- 误差线:每个数据点旁的蓝色竖线为误差线,反映该组测量结果的不确定性(比如实验误差范围),B 组误差线最长,说明该组测量结果的波动或误差相对更大。
- 对照组(绿色虚线、方形标记):
- 折线走势:A 组测量结果约为 3.0,B 组上升至约 3.8,C 组下降到约 2.7,同样有先升后降的变化规律。
- 误差线:绿色竖线为误差线,B 组误差线长度也相对突出,体现该组数据的不确定性情况。
完整代码
import matplotlib.pyplot as plt
import numpy as np
# 三组实验数据
groups = ['A', 'B', 'C']
x = np.arange(len(groups)) # 组坐标:0,1,2
# 每组的均值和误差(标准差)
means = [2.5, 4.2, 3.1]
errors = [0.4, 0.6, 0.3]
# 为了对比更清晰,添加一组对照数据
means_control = [3.0, 3.8, 2.7]
errors_control = [0.3, 0.5, 0.4]
# 坐标偏移(避免两组点重叠)
offset = 0.2
plt.figure(figsize=(10, 6))
# 绘制实验组
plt.errorbar(
x - offset, means, yerr=errors,
fmt='o-', capsize=5, label='实验组',
color='blue', markerfacecolor='white'
)
# 绘制对照组
plt.errorbar(
x + offset, means_control, yerr=errors_control,
fmt='s--', capsize=5, label='对照组',
color='green', markerfacecolor='white'
)
# 设置x轴标签为组名
plt.xticks(x, groups)
plt.xlabel('实验组别')
plt.ylabel('测量结果')
plt.title('实验组与对照组的误差对比')
plt.legend()
plt.grid(alpha=0.3)
plt.show()
四、误差线图的常见误区
-
误用误差类型:将标准差(展示数据离散)与标准误(展示均值可靠性)混淆,导致读者误判数据差异。
- 例如:比较两组均值时应使用标准误,而非标准差。
-
忽略样本量:误差线相同的两组数据,样本量大的更可靠,但误差线无法直接体现样本量,需在图表注释中说明。
-
过度拥挤:数据点过多时不调整
errorevery,导致误差线重叠,难以分辨。 -
误差线缺失关键元素:省略末端横线(caps),使读者无法判断误差范围的起止。
二、频谱图
频谱图(Spectrogram)是一种用于分析信号频率随时间变化的可视化图表,广泛应用于音频处理、声学分析、雷达信号、地震学等领域。它能将一维的时间信号转换为 “时间 - 频率 - 能量” 的三维表示,直观展示信号在不同时刻的频率成分及其强度。
一、频谱图的核心原理
频谱图基于短时傅里叶变换(STFT) 实现,核心思想是:
- 将连续的时间信号分割成多个重叠的短窗口(如 20ms-50ms 的片段)
- 对每个窗口内的信号做傅里叶变换,得到该时间段的频率分布
- 将所有窗口的结果按时间顺序排列,用颜色表示频率成分的能量(振幅)
这种处理方式解决了傅里叶变换无法同时体现时间和频率信息的缺陷,平衡了时间分辨率和频率分辨率(窗口越短,时间分辨率越高但频率分辨率越低,反之亦然)。
二、频谱图的关键参数
在 Matplotlib 中,plt.specgram() 函数用于绘制频谱图,核心参数如下:
| 参数 | 作用说明 | 常用设置 |
|---|---|---|
x | 输入的一维信号数据(如音频波形、振动信号) | 必需参数 |
Fs | 采样频率(单位:Hz),用于将横轴从采样点转换为实际时间 | 如音频常用 Fs=44100 |
NFFT | 每个窗口的傅里叶变换点数,影响频率分辨率(值越大,频率分辨率越高) | 256, 512, 1024 |
noverlap | 相邻窗口的重叠点数,影响时间连续性(重叠率通常取 50%-75%) | NFFT//2(50% 重叠) |
window | 窗口函数(减少频谱泄漏) | np.hanning(NFFT)(汉宁窗) |
cmap | 颜色映射,用于表示能量强度(默认 'jet') | 'viridis', 'magma' |
scale | 能量刻度类型(线性 / 对数) | 'dB'(对数刻度,更符合人耳感知) |
三、完整示例:音频信号频谱分析
以下示例生成一个包含不同频率成分的模拟音频信号,并绘制其频谱图:
音频信号的本质是 随时间变化的振幅序列
Fs = 44100
duration = 5
t = np.linspace(0, duration, int(Fs * duration), endpoint=False)
- 采样频率(Fs):每秒采集的信号点数,44.1kHz 是 CD、MP3 等音频的标准格式,确保信号不丢失人耳可听频率。
- 时间轴(t):用
np.linspace生成连续的时间点,例如 5 秒 ×44100Hz = 220500 个采样点,每个点对应一个 “时间 - 振幅” 数据。
signal = np.zeros_like(t) # 初始化信号数组(全0,长度与时间轴一致)
# ① 0-1秒:500Hz纯正弦波(单一频率,模拟纯音)
signal[t < 1] = np.sin(2 * np.pi * 500 * t[t < 1])
# 正弦波公式:A*sin(2πft + φ),A=1(振幅)、f=500Hz(频率)、φ=0(初相位)
# t[t < 1]:筛选出时间在0-1秒内的所有采样点,只对这部分赋值
-
初始化信号数组:
signal = np.zeros_like(t)- 功能:创建一个与时间轴
t长度完全一致的全 0 数组,用于后续分时段填充信号数据,确保信号的时间维度与时间轴匹配。
- 功能:创建一个与时间轴
-
0-1 秒:500Hz 纯正弦波(单一频率,模拟纯音)
- 代码逻辑:
signal[t < 1] = np.sin(2 * np.pi * 500 * t[t < 1]) - 关键说明:
- 正弦波公式遵循
A*sin(2πft + φ),其中振幅A=1(默认)、频率f=500Hz(单一固定频率)、初相位φ=0(默认); t[t < 1]是 numpy 布尔索引,筛选出时间在 0-1 秒内的所有采样点,仅对这部分数组元素赋值,不影响其他时间段。
- 正弦波公式遵循
- 代码逻辑:
-
1-2 秒:500Hz + 1500Hz 混合正弦波(双频率,模拟和声、乐器泛音)
# ② 1-2秒:500Hz + 1500Hz 混合正弦波(双频率,模拟和声、乐器泛音) signal[(t >= 1) & (t < 2)] = ( 0.7 * np.sin(2 * np.pi * 500 * t[(t >= 1) & (t < 2)]) + # 500Hz为主频率(振幅0.7,占比70%) 0.3 * np.sin(2 * np.pi * 1500 * t[(t >= 1) & (t < 2)]) # 1500Hz为次频率(振幅0.3,占比30%) )- 代码逻辑:
signal[(t >= 1) & (t < 2)] = 0.7*sin(...) + 0.3*sin(...) - 关键说明:
- 两个不同频率的正弦波叠加,模拟真实声音中 “基频 + 泛音” 的结构(如钢琴、人声的音色构成);
- 500Hz 为主频率(振幅 0.7,能量占比 70%),1500Hz 为次频率(振幅 0.3,能量占比 30%),通过振幅差异体现频率的主次关系;
(t >= 1) & (t < 2)筛选 1-2 秒的采样点,实现时间段精准
- 代码逻辑:
-
2-3 秒:线性调频信号(频率从 800Hz 升到 1200Hz,模拟滑音、警笛声)
# ③ 2-3秒:线性调频信号(频率从800Hz升到1200Hz,模拟滑音、警笛声) freq_mod = 800 + 400 * (t[(t >= 2) & (t < 3)] - 2) # 频率随时间线性变化:t=2时800Hz,t=3时1200Hz # 线性调频信号的振幅计算:需对频率积分(因为频率是“变化率”,积分得到相位) signal[(t >= 2) & (t < 3)] = np.sin(2 * np.pi * np.cumsum(freq_mod) / Fs) # np.cumsum(freq_mod):对频率序列累加(积分近似),除以Fs是将“采样点频率”转换为“实际相位”- 频率计算:
freq_mod = 800 + 400*(t[(t >= 2) & (t < 3)] - 2)- 功能:生成随时间线性变化的频率序列,
t=2时频率为 800Hz,t=3时频率为 1200Hz,每秒频率增加 400Hz;
- 功能:生成随时间线性变化的频率序列,
- 信号赋值:
signal[(t >= 2) & (t < 3)] = np.sin(2 * np.pi * np.cumsum(freq_mod) / Fs)- 关键说明:
- 线性调频信号的相位需通过频率积分计算(频率是相位的变化率),
np.cumsum(freq_mod)对频率序列累加,实现积分近似; - 除以采样频率
Fs,是将 “采样点维度的频率累加值” 转换为 “实际物理维度的相位值”,确保正弦函数的相位计算正确。
- 线性调频信号的相位需通过频率积分计算(频率是相位的变化率),
- 关键说明:
- 频率计算:
-
3-5 秒:白噪声(宽频信号,模拟环境噪音、杂音)
# ④ 3-5秒:白噪声(宽频信号,模拟环境噪音、杂音) signal[t >= 3] = 0.5 * np.random.randn(len(t[t >= 3])) # np.random.randn():生成符合标准正态分布的随机数(均值0,标准差1),乘以0.5控制噪声振幅(避免过强) # 白噪声的特点是“所有频率成分能量均匀”,对应频谱图中“全频段亮色”- 代码逻辑:
signal[t >= 3] = 0.5 * np.random.randn(len(t[t >= 3])) - 关键说明:
np.random.randn()生成符合标准正态分布(均值 0、标准差 1)的随机数,模拟白噪声的随机特性;- 乘以 0.5 是为了控制噪声振幅(避免噪声能量过强掩盖其他信号特征);
- 白噪声的核心特点是 “所有频率成分能量均匀分布”,对应频谱图中 “全频段均匀亮色” 的视觉效果。
- 代码逻辑:
-
全局添加小幅度噪声:
# ⑤ 全局添加小幅度噪声(模拟真实录音中的环境干扰) signal += 0.1 * np.random.randn(len(signal))- 代码逻辑:
signal += 0.1 * np.random.randn(len(signal)) - 功能:为整个 5 秒的信号添加低振幅(0.1 倍标准差)的随机噪声,模拟真实录音场景中的环境干扰(如电流声、背景杂音),让信号更贴近实际情况。
- 代码逻辑:
plt.subplot(2, 1, 2)
freqs, times, spectrogram, _ = plt.specgram(
signal, # 输入信号(必须是1维数组)
Fs=Fs, # 采样频率(用于计算实际频率和时间)
NFFT=2048, # 每个窗口的傅里叶变换点数(决定频率分辨率:Fs/NFFT ≈ 21.5Hz/点)
noverlap=1536, # 相邻窗口的重叠点数(1536=2048×0.75,75%重叠率,保证时间连续性)
window=np.hanning(2048), # 窗口函数:汉宁窗(减少“频谱泄漏”,避免频率计算偏差)
cmap='viridis', # 颜色映射:用不同颜色表示能量强度(viridis是视觉友好的渐变色)
scale='dB' # 能量刻度:对数刻度(dB),符合人耳对声音强度的感知(对数敏感)
)
# 自定义频谱图坐标轴
plt.xlabel('时间(秒)') # x轴:时间(与波形图一致)
plt.ylabel('频率(Hz)') # y轴:频率(信号包含的频率成分)
plt.ylim(0, 4000) # 限制频率范围为0-4000Hz(人耳对200-4000Hz最敏感,聚焦核心频段)
cbar = plt.colorbar(label='能量(dB)') # 添加颜色条:解释“颜色-能量”对应关系(dB值越高,能量越强)
- NFFT(傅里叶变换点数):频谱图的 “频率分辨率” 由
Fs/NFFT决定,例如 44100/2048 ≈ 21.5Hz,意味着每一个 “频率点” 代表 21.5Hz 的范围,NFFT 越大,频率分辨率越高(但时间分辨率越低)。 - noverlap(窗口重叠率):
specgram()本质是 “将信号分割成多个小窗口,每个窗口做傅里叶变换”,重叠率越高,相邻窗口的频率变化越连续(避免出现 “断层”),75% 是兼顾效率和连续性的常用值。 - window(窗口函数):直接对信号切分会导致 “频谱泄漏”(频率计算不准),汉宁窗(Hanning)通过 “两端平滑衰减” 减少泄漏,是信号分析的标准选择。
- scale='dB':声音的能量范围极广(从 0 到 10¹² 倍),用对数刻度(dB)可压缩范围,让弱信号和强信号的差异同时可见(符合人耳 “对数感知” 特性)。
四、频谱图解读
- 横轴(时间):信号的时间进程,从左到右为时间流逝
- 纵轴(频率):信号包含的频率成分,从下到上频率升高
- 颜色:表示对应时间和频率点的能量强度(颜色越亮 / 深,能量越强)

一、波形图(上半部分)
- 横轴:时间(秒),范围 0 - 5 秒,与模拟信号的时长一致。
- 纵轴:振幅,反映信号在不同时刻的强度。
- 各时段特征:
- 0 - 1 秒:波形呈现规律的正弦波动,振幅稳定在 ±1 左右,对应代码中 “500Hz 纯正弦波” 的生成逻辑,是单一频率的平稳振动。
- 1 - 2 秒:波形波动复杂度提升,振幅变化更频繁,对应 “500Hz + 1500Hz 混合正弦波”,双频率叠加使波形不再是单纯的正弦形态。
- 2 - 3 秒:波形的 “波动密度” 逐渐增加(频率升高的体现),对应 “线性调频(800Hz→1200Hz)”,频率随时间上升导致波形变化加快。
- 3 - 5 秒:波形呈现无规律的杂乱波动,振幅范围扩大(甚至接近 ±2),对应 “白噪声 + 全局小噪声”,随机噪声的加入让信号失去了周期性。

二、频谱图(下半部分)
- 横轴:时间(秒),与波形图时间轴同步。
- 纵轴:频率(Hz),范围 0 - 4000Hz,聚焦人耳敏感的频率区间。
- 颜色条:能量(dB),颜色越亮(如黄色)代表能量越强,颜色越暗(如蓝色、紫色)代表能量越弱。
- 各时段特征:
- 0 - 1 秒:仅在 500Hz 处有一条明亮的水平黄线,说明此时间段信号只有 500Hz 这一单一频率成分,且能量集中(与 “500Hz 纯正弦波” 逻辑一致)。
- 1 - 2 秒:除了 500Hz 的黄线,1500Hz 附近也出现了较亮的区域,体现 “500Hz + 1500Hz 混合” 的双频率特征,两个频率的能量都较为显著。
- 2 - 3 秒:一条从 500Hz 附近斜向上升至 1200Hz 左右的亮线,直观展示了 “线性调频” 的过程 —— 频率从较低值随时间逐渐升高,与代码中 “800Hz→1200Hz 线性变化” 的逻辑匹配(因频率计算存在近似,视觉上起始频率接近 500Hz 是正常现象)。
- 3 - 5 秒:全频段(0 - 4000Hz)都呈现出均匀的亮色,符合 “白噪声”“所有频率成分能量均匀” 的特点,说明此时间段信号是宽频的随机噪声。
完整代码
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FuncFormatter
# 1. 解决中文显示问题:设置支持中文的字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False
# 2. 切换Matplotlib后端(解决PyCharm兼容性问题)
plt.switch_backend('TkAgg') # 使用Tkinter后端,兼容性更好
# 1. 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 2. 生成模拟音频信号
Fs = 44100 # 采样频率:44.1kHz(标准音频)
duration = 5 # 信号时长:5秒
t = np.linspace(0, duration, int(Fs * duration), endpoint=False) # 时间轴
# 构建复合信号(不同时间段含不同频率)
signal = np.zeros_like(t)
# 0-1秒:500Hz正弦波
signal[t < 1] = np.sin(2 * np.pi * 500 * t[t < 1])
# 1-2秒:500Hz + 1500Hz 混合
signal[(t >= 1) & (t < 2)] = (
0.7 * np.sin(2 * np.pi * 500 * t[(t >= 1) & (t < 2)]) +
0.3 * np.sin(2 * np.pi * 1500 * t[(t >= 1) & (t < 2)])
)
# 2-3秒:线性调频(频率从800Hz升到1200Hz)
freq_mod = 800 + 400 * (t[(t >= 2) & (t < 3)] - 2) # 线性变化的频率
signal[(t >= 2) & (t < 3)] = np.sin(2 * np.pi * np.cumsum(freq_mod) / Fs)
# 3-5秒:白噪声(宽频信号)
signal[t >= 3] = 0.5 * np.random.randn(len(t[t >= 3]))
# 添加小幅度噪声模拟真实环境
signal += 0.1 * np.random.randn(len(signal))
# 3. 绘制原始信号波形(上半部分)
plt.figure(figsize=(12, 8))
# 原始波形子图
plt.subplot(2, 1, 1)
plt.plot(t, signal, linewidth=0.5)
plt.xlabel('时间(秒)')
plt.ylabel('振幅')
plt.title('原始音频信号波形与频谱图')
plt.xlim(0, duration)
plt.grid(alpha=0.3)
# 4. 绘制频谱图(下半部分)
plt.subplot(2, 1, 2)
# 修正:接收4个返回值,忽略不需要的图像对象(用_占位)
freqs, times, spectrogram, _ = plt.specgram(
signal,
Fs=Fs, # 采样频率
NFFT=2048, # 傅里叶变换点数
noverlap=1536, # 重叠点数(75%重叠率)
window=np.hanning(2048), # 汉宁窗
cmap='viridis', # 颜色映射
scale='dB' # 对数能量刻度
)
# 自定义坐标轴
plt.xlabel('时间(秒)')
plt.ylabel('频率(Hz)')
plt.ylim(0, 4000) # 限制频率范围
cbar = plt.colorbar(label='能量(dB)') # 添加颜色条
# 调整布局
plt.tight_layout()
plt.show()
五、实际应用场景
- 音频分析:识别语音中的元音(不同元音对应不同频率模式)、乐器音色分析
- 声学检测:机械故障诊断(异常振动会产生特定频率)、环境噪声监测
- 雷达与通信:信号调制识别、多普勒效应分析
- 生物医学:脑电信号(EEG)分析、心音信号特征提取
三、总结
误差线图的核心价值在于 “量化不确定性”,通过合理选择误差类型、优化视觉设计,能让数据的可靠性一目了然。在实际应用中,需根据数据性质(如是否对比均值、是否有不对称误差)选择合适的参数和展示方式,同时避免常见误区,确保图表传递准确信息。
频谱图的核心价值在于揭示信号的 “时频特征”,是分析非平稳信号(频率随时间变化的信号)的强大工具。通过调整参数,可以平衡时间和频率分辨率,适应不同类型信号的分析需求。
1610

被折叠的 条评论
为什么被折叠?



