Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

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

I am working with audio timeseries and want to better label areas that are being plotted. I believe this question is general to labelling timeseries data in matplotlib, but it may be important that I am also using librosa.display.waveplot to initially plot the waveform. Currently, I am able to make the following plot using librosa and matplotlib (in a jupyter notebook):

enter image description here

I would like to make something like the following: enter image description here

The code I used is as follows, where x[1] is a simple vector containing the audio data (happens to be stereo), and target_len is the length of a recording that is repeated 3 times with some filtering. The audio file was imported using 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()

My attempts at drawing rectangles directly above the audio waveform have failed, and the best I could do is create another figure above the audio figure produced by librosa, drawing a rectangle using a patch. Unfortunately the rectangle is being placed way too far away from where I want it.

enter image description here

The code for this rectangle is here (with ax.axis('off') commented out so you can see the poor placement of the figure):

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

Again, this question is fundamentally about matplotlib and figure annotation, and specifically about how to annotate the plots that librosa (or any other consumer of matplotlib for that matter) makes. It seems like librosa applies some of it's own formatting to the figure so it does not align well with what I try to draw in a new figure above it.

question from:https://stackoverflow.com/questions/65680166/how-can-i-add-rectangles-and-labels-above-an-audio-timeseries-plot

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I am not very experienced in customizing matplotlib. I created the code by referring to this page. I think there is a better way to adjust the position as it is set manually.

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.]])))))

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...