Reputation: 445
I'm trying to get a Spectrogram plot with colorbar like this for a .wav
file:
So, I wrote the following:
from matplotlib.figure import Figure
from scipy.io.wavfile import read as readWav
wavfile1 = 'Speech.wav'
wavFs, wavData = readWav(wavfile1)
figSG = Figure(figsize=[15, 8], facecolor='lightgrey')
axSG = figSG.add_subplot(2, 1, 1, position=[0, 0, 1, 0.85])
axCB = figSG.add_subplot(2, 1, 2, position=[0.2, 0.0, 0.6, 0.05])
pltlinescurves = axSG.specgram(wavData, NFFT=256, Fs=8000)
figSG.colorbar(pltlinescurves[3], label='Intensity (in dB)', cax=axCB, orientation='horizontal')
which gives me this:
As evident from the code above, I have added the position
argument as mentioned here, as per my understanding is same as:
axSG = figSG.add_axes([0, 0, 1, 0.85])
axCB = figSG.add_axes([0.2, 0.0, 0.6, 0.05])
Is my understanding wrong? If yes, how do I achieve this using subplots?
P.S.: For my implementation convenience, I'm avoiding pyplot
and dealing with Figure
and Axes
classes.
Upvotes: 0
Views: 184
Reputation: 5912
The usual way to do this is
fig, ax = plt.subplots(figsize=[15, 8], layout='constrained')
cb = ax.pcolormesh(np.random.randn(100, 300))
ax.set_xlabel('Time (s)')
ax.set_ylabel('f [Hz]')
ax.set_title('Spectrogram')
fig.colorbar(cb, ax=ax, label='Intensity in dB',
location='bottom', shrink=0.75, aspect=50, pad=0.02)
Upvotes: 1
Reputation: 445
I managed to use Jody's inputs above and solve the problem partially:
from matplotlib.figure import Figure
from scipy.io.wavfile import read as readWav
wavfile1 = 'Speech.wav'
wavFs, wavData = readWav(wavfile1)
figSG = Figure(figsize=[15, 8], facecolor='lightgrey')
axSG, axCB = figSG.subplots(2, 1, gridspec_kw={'height_ratios': [1, 0.1], 'width_ratios': [1]})
axSG.set_xlabel('Time (s)', fontsize=14)
axSG.set_ylabel('Frequency (Hz)', fontsize=14)
axSG.set_title('Spectrogram (Hz vs s)', fontsize=18)
pltlinescurves = axSG.specgram(wavData, NFFT=256, Fs=wavFs)
cbar = figSG.colorbar(pltlinescurves[3], cax=axCB, orientation='horizontal', pad=1.5)
cbar.set_label('Intensity (in dB)',size=14)
cbaspect = get_aspect(ax=axCB) * 0.5
axCB.set_aspect(cbaspect, anchor='C')
figSG.tight_layout()
where the function get_aspect()
used above is from here and is defined as:
def get_aspect(ax):
fig = ax.figure
ll, ur = ax.get_position() * fig.get_size_inches()
width, height = ur - ll
axes_ratio = height / width
aspect = axes_ratio / ax.get_data_ratio()
return aspect
which gives me the following output:
Still, I'm unable to shrink the colorbar (to about 75%-85% would be ideal) as shown in the post above. Any leads would be much appreciated.
Upvotes: 0