1

If I put pyplot.show() before I try to save an image, the file doesn't actually contain the image.

At first I thought it was a bug but then I switched pyplot.show() and pyplot.savefig('foo5.png') and it worked.

Here is an example code piece.

def plot(embeddings, labels):
  assert embeddings.shape[0] >= len(labels), 'More labels than embeddings'
  pyplot.figure(figsize=(20, 20))  # in inches
  for i, label in enumerate(labels):
    x, y = embeddings[i,:]
    pyplot.scatter(x, y)
    pyplot.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points',
                   ha='right', va='bottom')
  pyplot.savefig('foo4.png')
  pyplot.show()
  pyplot.savefig('foo5.png')

books = [bookDictionary[i] for i in range(1, num_points2+1)]
plot(two_d_embeddings, books)
print( os.listdir() )

foo4.png is just fine, but foo5.png is blank.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
SantoshGupta7
  • 5,607
  • 14
  • 58
  • 116

1 Answers1

3

As you found out yourself, using pyplot you need to save the figure before it is shown.

This is in fact only true for non-interactive mode (ioff), but that is the default and probably most common use case.

What happens is that once pyplot.show() is called, the figure is shown and an event loop is started, taking over the python even loop. Hence any command after pyplot.show() is delayed until the figure is closed. This means that pyplot.savefig(), which comes after show is not executed until the figure is closed. Once the figure is closed, there is no figure to save present inside the pyplot state machine anymore.

You may however save a particular figure, in case that is desired. E.g.

import matplotlib.pyplot as plt

plt.plot([1,2,3])
fig = plt.gcf()
plt.show()
fig.savefig("foo5.png")

Here, we call the savefig method of a particular figure (in this case the only one present) for which we need to obtain a handle (fig) to that figure.

Note that in such cases, where you need fine control over how matplotlib works it's always useful to not use pyplot, but rely mostly on the object oriented interface. Hence,

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([1,2,3])
plt.show()
fig.savefig("foo5.png")

would be the more natural way to save a figure after having shown it.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712