Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib savefig background always transparent

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)
like image 305
Richard Avatar asked Dec 05 '19 23:12

Richard


People also ask

How do I make the background transparent in Matplotlib?

If you just want the entire background for both the figure and the axes to be transparent, you can simply specify transparent=True when saving the figure with fig. savefig . If you want more fine-grained control, you can simply set the facecolor and/or alpha values for the figure and axes background patch.

How do I get a white background in Matplotlib?

MatPlotLib with Python To change the axes background color, we can use set_facecolor() method.

How do I save an image with a transparent background in Python?

Note that the default argument for savefig() is transparent=False. By specifying transparent=True we can save a Matplotlib figure with a transparent background.


2 Answers

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

like image 61
EA304GT Avatar answered Nov 02 '22 12:11

EA304GT


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

like image 45
Richard Avatar answered Nov 02 '22 10:11

Richard