matplotlib绘制y轴为非线性Bark频率刻度语谱图的实现咨询
非线性间隔频率仓的语谱图绘制方法
问题原因
imshow仅支持均匀网格的坐标映射,仅通过extent参数设置频率范围会将所有频率仓线性拉伸到指定区间,无法适配Bark、Mel等非线性分布的频率仓间隔。
解决方案
使用matplotlib的pcolormesh接口实现非均匀网格的热力图绘制,具体步骤如下:
- 准备三类输入数据
- 语谱图数据:维度为
[4238, 263]的PyTorch张量先调用.numpy()转为numpy数组 - 时间轴数组:长度为4238,对应每个时间帧的实际秒数,可根据帧移、采样率计算生成
- 非线性频率数组:你已有的263个Bark尺度对应的实际Hz值
- 语谱图数据:维度为
- (可选)计算网格边界
pcolormesh默认传入的X/Y轴参数为网格边界坐标,长度需要比对应数据维度大1,可通过相邻坐标取中点的方式生成边界数组,避免边缘频率仓被截断,代码示例:import numpy as np # 替换为你的263个实际频率值 freq_axis = np.array([0, 32.9, 42.67268041, 52.45663684, ...]) freq_bound = np.concatenate([ [freq_axis[0] - (freq_axis[1]-freq_axis[0])/2], (freq_axis[1:] + freq_axis[:-1])/2, [freq_axis[-1] + (freq_axis[-1]-freq_axis[-2])/2] ]) # 生成时间边界,总时长可根据实际场景调整 time_axis = np.linspace(0, 20, 4238) time_bound = np.concatenate([ [time_axis[0] - (time_axis[1]-time_axis[0])/2], (time_axis[1:] + time_axis[:-1])/2, [time_axis[-1] + (time_axis[-1]-time_axis[-2])/2] ]) - 调用
pcolormesh绘图import matplotlib.pyplot as plt import torch # 替换为你的语谱图张量 spec = torch.randn(4238, 263).numpy() # 绘图时需要转置语谱图,匹配matplotlib的X/Y轴维度规则 plt.pcolormesh(time_bound, freq_bound, spec.T, shading='flat') plt.xlabel('Time (s)') plt.ylabel('Frequency (Hz)') plt.colorbar(label='Spectral Amplitude') plt.show()
注意事项
如果不需要严格对齐网格边界,可直接传入原始的
time_axis和freq_axis,同时设置参数shading='nearest',无需额外计算边界数组。
内容的提问来源于stack exchange,提问作者Sevag
相关产品推荐
相关产品推荐

