Reputation: 358
I've been plotting spectrograms and waveforms using matplotlib and scipy. The spectrogram figures (plotted with matplotlib.pyplot.pcolormesh()
) are saved correctly, as I show here, with this code:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
from matplotlib import cm
from scipy import signal
from scipy.io import wavfile
sample_rate, samples = wavfile.read('audio-mono.wav')
frequencies, times, spectrogram = signal.spectrogram(samples[:700000], sample_rate)
cMap = cm.get_cmap('gray', 3000)
new_colors = cMap(np.linspace(0.5, 1, 3000))
black = [0, 0, 0, 1]
new_colors[0, :] = black
new_cmp = ListedColormap(new_colors)
fig = plt.figure(figsize=(4,2), dpi=400, frameon=False)
plt.pcolormesh(times, frequencies, spectrogram, cmap=cMap)
plt.savefig('spectrogram.png')
However, when I try to plot a waveform and save the figure, I get the plot in the plots pane (I'm using Spyder), but the figure is saved blank. If I click the save button that corresponds to that figure in Spyder's plots pane, I can save it successfully and see it, but I need to know why the my code is failing to save it correctly. Here it is:
import matplotlib.pyplot as plt
from scipy.io import wavfile
sample_rate, samples = wavfile.read('audio-mono.wav')
fig = plt.figure(figsize=(4,1), dpi=500, frameon=False)
ax = plt.Axes(fig, [2, 2, 2, 2])
ax.set_facecolor((0,0,0))
fig.add_axes(ax)
plt.tick_params(axis='both', which='both', bottom=False,
top=False, left=False, right=False,
labelbottom=False, labeltop=False,
labelright=False, labelleft=False)
plt.plot(samples)
plt.savefig('waveform.png')
Thanks in advance.
EDIT 1
Please note that I'm setting the figure size to 4x1 (inches). The blank figure that's being saved is 2000x500 (pixels), actually the exact same size of the spectrogram figures that are being saved correctly. I assume this means I am saving the figure I'm creating with plt.figure()
, but somehow the axes doesn't appear there.
EDIT 2
Based on the answer accepted as solution, I am posting two figures of the same plot with different rectangles passed to the Axes
instance.
First, the image I was originally creating with the code posted above (saved with the 'save' button of the IDE).
Second, the figure saved with the Axes
object created with a different rectangle (the one proposed in the solution). ax = plt.Axes(fig, [0, 0, 1, 1])
As said in the comment in the accepted answer, I had chosen to pass this rectangle to the instance of the Axes
object because it seemed to give me a much better resolution.
Upvotes: 1
Views: 156
Reputation: 25363
The rectangle that you pass as the position of the axes is not in the figure. From the documentation:
plt.axes(rect, projection=None, polar=False, **kwargs)
- 4-tuple of floats rect = [left, bottom, width, height]. A new axes is added with dimensions rect in normalized (0, 1) units using
add_axes
on the current figure.
Therefore, you need to proved a rectangle that starts at (0, 0) in figure coordinates, and goes to the edge of the figure, which will mean that height and width will be 1.
So change:
ax = plt.Axes(fig, [2, 2, 2, 2])
to
ax = plt.Axes(fig, [0, 0, 1, 1])
Upvotes: 1