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

如何让Matplotlib音频波形图X轴时间刻度自动适配精度?

解决方案

要实现X轴刻度随图形缩放自动切换精度(默认秒级,放大显示毫秒/微秒),可以放弃datetime64类型的时间戳,直接使用秒数作为X轴数值,再通过自定义格式化函数根据当前视图范围动态调整显示格式。以下是修改后的代码:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import dates as mdates
from scipy.io import wavfile
import functools

def time_formatter(x, pos, ax):
    # 获取当前轴的显示范围和音频总时长
    x_min, x_max = ax.get_xlim()
    display_duration = x_max - x_min
    total_duration = ax.get_lines()[0].get_xdata()[-1]

    # 根据总时长和显示范围选择格式
    if total_duration >= 3600:
        # 音频时长≥1小时
        if display_duration >= 1:
            # 显示到秒:HH:MM:SS
            hours = int(x // 3600)
            mins = int((x % 3600) // 60)
            secs = int(x % 60)
            return f"{hours:02d}:{mins:02d}:{secs:02d}"
        elif display_duration >= 0.001:
            # 显示到毫秒:HH:MM:SS.sss
            hours = int(x // 3600)
            mins = int((x % 3600) // 60)
            secs = x % 60
            return f"{hours:02d}:{mins:02d}:{secs:.3f}"
        else:
            # 显示到微秒:HH:MM:SS.ffffff
            hours = int(x // 3600)
            mins = int((x % 3600) // 60)
            secs = x % 60
            return f"{hours:02d}:{mins:02d}:{secs:.6f}"
    else:
        # 音频时长<1小时
        if display_duration >= 1:
            # 显示到秒:MM:SS
            mins = int(x // 60)
            secs = int(x % 60)
            return f"{mins:02d}:{secs:02d}"
        elif display_duration >= 0.001:
            # 显示到毫秒:MM:SS.sss
            mins = int(x // 60)
            secs = x % 60
            return f"{mins:02d}:{secs:.3f}"
        else:
            # 显示到微秒:MM:SS.ffffff
            mins = int(x // 60)
            secs = x % 60
            return f"{mins:02d}:{secs:.6f}"

# 读取音频文件
freq_audio_1, samples_1 = wavfile.read("audio1.wav")
samples_1 = samples_1[:, 0]  # 转为单声道
freq_audio_2, samples_2 = wavfile.read("audio2.wav")
samples_2 = samples_2[:, 0]  # 转为单声道

# 生成秒级时间戳(无需转datetime64)
t_audio_1 = np.arange(0, len(samples_1)) / freq_audio_1
t_audio_2 = np.arange(0, len(samples_2)) / freq_audio_2

# 创建画布和轴
fig, ax = plt.subplots(1, 2, constrained_layout=True)

# 为每个轴设置动态格式化函数
for axis in ax:
    # 绑定当前轴对象到格式化函数
    formatter = plt.FuncFormatter(functools.partial(time_formatter, ax=axis))
    axis.xaxis.set_major_formatter(formatter)
    # 自动调整刻度数量,避免重叠
    axis.xaxis.set_major_locator(mdates.AutoLocator())

# 绘制波形
ax[0].plot(t_audio_1, samples_1)
ax[1].plot(t_audio_2, samples_2)

plt.show()

关键改动说明

  1. 放弃datetime64类型:直接使用秒数作为X轴数值,避免datetime类型带来的刻度格式化限制,更灵活控制显示逻辑。
  2. 动态格式化函数:
    • 通过ax.get_xlim()获取当前视图的显示范围,判断是否需要显示更高精度(毫秒/微秒)。
    • 根据音频总时长自动切换小时级格式(HH:MM:SS)或分钟级格式(MM:SS)。
  3. 刻度优化:配合AutoLocator自动调整刻度数量,从根源避免刻度重叠问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:02:31