pythonmatplotlibsavefig

How can I save a Matplotlib figure after changing the background color?


Using the Spyder IDE, I have created a matplotlib plot and changed the face (background) color of both the figure object and the axes object to black. When I try to save the figure using plt.savefig(...) the axes, title, and axes label are not included.

I have tried implementing the standard advice of adding bbox_inches='tight' to the plt.savefig() function for when the axes are cut off:

plt.savefig("my_fig_name.png", bbox_inches='tight')

To no avail. Others suggested that I change the plotting method to "inline" from "automatic" within either Jupyter Notebook or Spyder. This had no effect. I also tried to make sure there was enough room in the figure for my axes using:

fig.add_axes([0.1,0.1,0.75,0.75])

This does not work either. Below is enough to reproduce my experience.

import matplotlib.pyplot as plt

xs, ys = [0,1], [0,1]

fig = plt.figure(figsize=(6, 6)) # Adding tight_layout=True has no effect
ax = fig.add_subplot(1, 1, 1)

# When the following block is commented out, the color of the 
# plot is unchanged and the plt.savefig function works perfectly

fig.patch.set_facecolor("#121111")
ax.set_facecolor("#121111")
ax.spines['top'].set_color("#121111")
ax.spines['right'].set_color("#121111")
ax.spines['bottom'].set_color('white')
ax.spines['left'].set_color('white')
ax.xaxis.label.set_color('white')
ax.tick_params(axis='x', colors='white')
ax.yaxis.label.set_color('white')
ax.tick_params(axis='y', colors='white')

ax.set_title("My Graph's Title", color="white")

plt.plot(xs, ys)
plt.xlabel("x-label")
plt.ylabel("y-label")

plt.savefig("my_fig_name.png", bbox_inches="tight")

I am expecting to get an image like this:

What I Expect to Get

However, plt.savefig(...) gives me the following result:

What I Actually Get

Curiously, there seems to be white space around the plot which does not disappear even when I add the tight_layout=True parameter to the matplotlib figure constructor.

fig = plt.figure(figsize=(6, 6), tight_layout=True)

And, when I comment out the code which changes the face color of the plot, the figure is saved correctly with all the axes and labels displayed correctly.


Solution

  • In order to solve your problem, you just have to specify the facecolor keyword argument to your plt.savefig call, in this case :

    plt.savefig("my_fig_name.png", bbox_inches="tight", facecolor="#121111")
    

    which gives the intended .png output :

    correct_output

    For more information, see plt.savefig documentation.