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

使用shading='flat'时pcolormesh维度不匹配错误求助

解决matplotlib pcolormesh维度不匹配错误(audiosegment生成频谱图场景)

我在用audiosegment生成频谱图,通过matplotlib的pcolormesh绘图保存时,一直遇到维度不匹配的错误。我清楚pcolormesh要求C数组(即amplitudes)的维度要比X(times)和Y(freqs)数组小1,也尝试了扩展times和freqs数组,但报错依旧。

我的初始代码:

import os 
import shutil
import audiosegment
import numpy as np
import matplotlib.pyplot as plt

def spectrogram(file, output_dir):
    seg = audiosegment.from_file(file)
    freqs, times, amplitudes = seg.spectrogram(window_length_s=0.03, overlap=0.5)
    amplitudes = 10 * np.log10(amplitudes + 1e-9)
    times_new = np.resize(times, times.size + 1)
    freqs_new = np.resize(freqs, freqs.size + 1)
    print(len(times))
    plt.figure(figsize=(10, 4))
    plt.pcolormesh(times_new, freqs_new, amplitudes, shading='auto')
    plt.title("spectrogram " + file.split("/")[-1].split(".")[0])
    plt.xlabel("Time [s]")
    plt.ylabel("Frequency [Hz]")
    plt.savefig(os.path.join(output_dir, "spectrogram_" + file.split("/")[-1].split(".")[0]))
    plt.clf()
    plt.close()

之后我尝试直接扩展数组:

times = np.append(times, times[-1] + (times[-1] - times[-2]))
freqs = np.append(freqs, freqs[-1] + (freqs[-1] - freqs[-2]))
...
plt.pcolormesh(times, freqs, amplitudes, shading='auto')

问题分析

  1. np.resize的使用错误:它会重复原数组元素填充新长度,导致扩展后的times_new和freqs_new最后一个元素是原数组末尾的重复值,并非正确的边界值。
  2. 需确认维度对应关系:audiosegment返回的amplitudes维度是(freqs.size, times.size),所以扩展后的times长度必须是times.size + 1,freqs长度必须是freqs.size + 1,才能和amplitudes匹配。

正确解决方案

改用np.append添加正确的边界值,同时加入极端情况的容错处理:

import os 
import audiosegment
import numpy as np
import matplotlib.pyplot as plt

def spectrogram(file, output_dir):
    seg = audiosegment.from_file(file)
    freqs, times, amplitudes = seg.spectrogram(window_length_s=0.03, overlap=0.5)
    amplitudes = 10 * np.log10(amplitudes + 1e-9)
    
    # 扩展时间轴:计算最后一个时间边界
    if len(times) >= 2:
        time_step = times[-1] - times[-2]
        times_extended = np.append(times, times[-1] + time_step)
    else:
        times_extended = np.append(times, times[0] + 0.01)
    
    # 扩展频率轴:计算最后一个频率边界
    if len(freqs) >= 2:
        freq_step = freqs[-1] - freqs[-2]
        freqs_extended = np.append(freqs, freqs[-1] + freq_step)
    else:
        freqs_extended = np.append(freqs, freqs[0] + 100)
    
    plt.figure(figsize=(10, 4))
    plt.pcolormesh(times_extended, freqs_extended, amplitudes, shading='auto')
    plt.title(f"spectrogram {file.split('/')[-1].split('.')[0]}")
    plt.xlabel("Time [s]")
    plt.ylabel("Frequency [Hz]")
    plt.savefig(os.path.join(output_dir, f"spectrogram_{file.split('/')[-1].split('.')[0]}"))
    plt.close()

额外说明

  • shading='auto'在matplotlib 3.3+版本中会自动适配维度,但前提是X/Y数组长度确实比C数组对应维度大1。
  • 极端情况处理是为了避免音频过短时,times或freqs仅含单个元素导致的索引错误。
  • 用f-string替代字符串拼接,代码更简洁易读。

内容的提问来源于stack exchange,提问作者swaggerMan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:02:24