4
votes

Problem

I cannot seem to get savefig() to actually save a PNG file without a transparent figure background.

This is having read and tried all the suggestions previously posted, answered, cursed about and also going through the API docs a bunch of times. I've read it all, but still can't get non-transparent figure faces

Background

I'm using matplotlib and savefig to create a PNG file. (env: macos - latest anaconda modules using PY 3.7).

I am trying this out of jupyter however - so hopefully it's not something completely screwed up with only how ipython in jupyter does it - though I don't see how that could be the case

I did read through the previous many posts about the (confusing as hell) nature of savefig doing it's own thing with backgrounds, and did/tried everything as suggested (and as written in the latest savefig api docs).

In particular, I've tried all the following without sucess:

  • specifying facecolor in the savefig() call (with/without transparency)
  • savefig.facecolor: white in the style mpl file I'm using

When savefig'ing my figure background is always transparent.


Can anyone tell me what the !@#$!# I'm missing here???

Code

Here's what I''m using, which spits out figure with transparent background, regardless of what I do.

In particular the 2nd call below (with savefig(..., transparent=False)) will make the axes not transparent - but the figure itself is still transparent!)

import numpy as np
import matplotlib as mpl
import matplotlib.style as style

a = np.array([-3.2, 0.1, 1.5, 3.3, 8.5])
b = np.array([1.1, 1.8, 1.95, 2.3, 4.3])
labels = ['a', 'bc', 'def', 'g', 'ggghhh']

stylefile = './util/plot_config/aqs_default.mplstyle'
# the file above does contain an entry of:
# savefig.facecolor: white
#
to_res = 1024
dpi = 100
inches = (to_res/dpi, to_res/dpi)

style.use(stylefile)
%matplotlib   

fig = mpl.figure.Figure(figsize=inches, dpi=dpi, facecolor='white')
ax = fig.subplots()

for x, y, l in zip(a,b,labels):
    ax.scatter(x,y,label=l)
ax.legend()
ax.set_xlabel('Some x')
ax.set_ylabel('Attenuation $\mu$ (cm$^{-1}$)')

ax.set_title('blah', y=1.03)
fig.suptitle('Linearity $\mu$')

# for me, _both_ calls below result in the figure having a transparent background:

fig.savefig('a.png', facecolor=fig.get_facecolor(), transparent=True)
fig.savefig('b.png', facecolor=fig.get_facecolor(), transparent=False)
2
what errors do you get? did you try absolute path - Arun K
I don't get any errors at all - there isn't anything wrong in the code. The problem is my output PNG files always have a transparent figure background, regardless of everything I do to make it otherwise (make it white) - Richard
What does fig.get_facecolor() print? - ImportanceOfBeingErnest
fig.get_facecolor() returns the color set for the figure's facecolor (which get's set when I declare fig about 10 lines up). ...it doesn't print anything. So here it's telling fig.savefig to use the facecolor of the fig object, but querying fig to find out what it's facecolor is set to. - Richard
I want to know what print(fig.get_facecolor()) shows on screen in your case. Best incoorporate that line in your code and report about the result inside the question. - ImportanceOfBeingErnest

2 Answers

10
votes

Unfortunately, it seems that frameon is not supported anymore as of matplotlib 3.3.

I solved the transparency issue by setting facecolor='white', transparent=False options in savefig()

2
votes

FYI for anyone else with a similiar problem.

The cause (and fix) turned out to be because I was creating a figure with frameon set to False. I had actually had this set to False in a style file I was using.

Changing frameon to True fixed the problem.

This was confusing and not very obvious at all from any documentation - here is some background on the issue from the MPL github issues: https://github.com/matplotlib/matplotlib/issues/14339