TheSprinter
TheSprinter

Reputation: 358

Why aren't my pyplot.plot figures saved correctly?

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

Figure with rectangle for the axes 2, 2, 2, 2

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

Figure with rectangle for the axes 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

Answers (1)

DavidG
DavidG

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

Related Questions