如何在音频时间序列图上方添加矩形和标签?

How can I add rectangles and labels above an audio timeseries plot?

我正在处理音频时间序列,希望更好地标记正在绘制的区域。我相信这个问题对于在 matplotlib 中标记时间序列数据是通用的,但我也使用 librosa.display.waveplot 来最初绘制波形可能很重要。目前,我可以使用 librosamatplotlib(在 jupyter 笔记本中)制作以下图:

我想制作如下内容:

我使用的代码如下,其中x[1]是包含音频数据的简单向量(恰好是立体声),target_len是重复录音的长度3多次过滤。音频文件是使用 x, Fs = librosa.load("audiofile.wav", mono=False)

导入的
plt.figure(figsize=(12, 3))
librosa.display.waveplot(x[1], sr=Fs, color='black')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.axvspan(0, target_len, color = 'magenta', alpha=0.5, zorder=-100)
plt.axvspan(target_len, target_len*2, color = 'yellow', alpha=0.5, zorder=-100)
plt.axvspan(target_len*2, target_len*3,color = 'blue', alpha=0.5, zorder=-100)
plt.tight_layout()

我试图在音频波形正上方绘制矩形的尝试失败了,我能做的最好的事情就是在 librosa 生成的音频图形上方创建另一个图形,使用补丁绘制矩形。不幸的是,矩形放置的位置离我想要的位置太远了。

这个矩形的代码在这里(ax.axis('off') 被注释掉所以你可以看到图形的位置不佳):

from matplotlib.patches import Rectangle
fig = plt.figure(figsize=(12,3))
ax = fig.add_subplot(111) 
ax.add_patch(Rectangle((0.04, 0), 0.35, 0.05, facecolor="black"))
#ax.axis('off')
plt.tight_layout

同样,这个问题从根本上讲是关于 matplotlib 和图形注释,特别是关于如何注释 librosa(或与此相关的任何其他 matplotlib 使用者)绘制的图。似乎 librosa 将它自己的一些格式应用于图形,因此它与我尝试在其上方的新图形中绘制的内容不一致。

axvspan 有两个可选参数 yminymax,单位相对于 Y 轴的高度。 1.0 是 Y 轴的顶部,0.0 是 Y 轴的底部。 所以尝试使用 ymin=1.1ymax=1.2 或类似的东西。

我在定制matplotlib方面不是很有经验。我参考创建了代码。我认为有更好的方法来调整位置,因为它是手动设置的。

import librosa
import librosa.display
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import matplotlib as mpl

file_name = '/content/test.wav'
wav, sr = librosa.load(file_name, sr=44100)

target_len = 1.5

fig = plt.figure(figsize=(12,3))
ax = fig.add_subplot(111) 
librosa.display.waveplot(wav, sr, color='black')
ax.set_xlabel('Time (seconds)')
ax.set_ylabel('Amplitude')
ax.axvspan(0, target_len, color = 'magenta', alpha=0.5, zorder=-100)
ax.axvspan(target_len, target_len*2, color = 'yellow', alpha=0.5, zorder=-100)
ax.axvspan(target_len*2, target_len*3,color = 'blue', alpha=0.5, zorder=-100)
# t = fig.transFigure
# print(t)
a = ax.transAxes
print(a)
plt.text(0.25, 1.0, 'Audio 1', ha='center', va='top', transform=fig.transFigure)
plt.text(0.45, 1.0, 'Audio 2', ha='center', va='top', transform=fig.transFigure)
plt.text(0.70, 1.0, 'Audio 3', ha='center', va='top', transform=fig.transFigure)
rect1 = mpl.patches.Rectangle((0.0, 1.02), width=0.295, height=0.05, color="black", transform=ax.transAxes, clip_on=False)
rect2 = mpl.patches.Rectangle((0.30, 1.02), width=0.295, height=0.05, color="black", transform=ax.transAxes, clip_on=False)
rect3 = mpl.patches.Rectangle((0.60, 1.02), width=0.295, height=0.05, color="black", transform=ax.transAxes, clip_on=False)
ax.add_patch(rect1)
ax.add_patch(rect2)
ax.add_patch(rect3)
# plt.tight_layout()

plt.show()

BboxTransformTo(
    TransformedBbox(
        Bbox(x0=0.125, y0=0.125, x1=0.9, y1=0.88),
        BboxTransformTo(
            TransformedBbox(
                Bbox(x0=0.0, y0=0.0, x1=12.0, y1=3.0),
                Affine2D(
                    [[72.  0.  0.]
                     [ 0. 72.  0.]
                     [ 0.  0.  1.]])))))