Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib figure facecolor alpha while saving (background color, transparency)

A previous question dealt with using savefig() to save with the same facecolor (background color) as is displayed on screen, namely:

fig = plt.figure()
fig.patch.set_facecolor('blue')
fig.savefig('foo.png', facecolor=fig.get_facecolor())

Matplotlib figure facecolor (background color)

(Using savefig() requires us to respecify the background color.)

I can also specify an alpha for transparency, e.g.: How to set opacity of background colour of graph wit Matplotlib

fig.patch.set_alpha(0.5)

I can't find a way to make the figure with a transparent facecolor save as it appears onscreen. The documentation seems incomplete on this: http://matplotlib.org/faq/howto_faq.html#save-transparent-figures - the actual saving isn't showing. Using transparent=True with savefig() does not have the desired effect of making the facecolor transparent, instead it seems to make everything except axes legend transparent on top of that color (including graph backgrounds).

EDIT: Some relevant extracts of code:

def set_face_color(fig, facecolor):
    if facecolor is False:
        # Not all graphs get color-coding
        facecolor = fig.get_facecolor()
        alpha = 1
    else:
        alpha = 0.5
    color_with_alpha = colorConverter.to_rgba(
        facecolor, alpha)
    fig.patch.set_facecolor(color_with_alpha)

def save_and_show(plt, fig, save, disp_on, save_as):
    if save:
        plt.savefig(save_as, dpi=dpi_file, facecolor=fig.get_facecolor(),
                    edgecolor='none')
    if disp_on is True:
        figManager = plt.get_current_fig_manager()
        figManager.window.showMaximized()
        plt.show()
    else:
        plt.close('all')

It might be possible to combine these, but I often call set_face_color() at the beginning of a graphing function before I build up a grid of subplots and then save_and_show() toward the end. I guess it should work in either place, but optimally I'd prefer to keep the functions separate and be able to extract the alpha to pass to savefig() from the final fig.

EDIT 2 - Worth a thousand words

Alpha = 0.5 on the left, 1 on the right.

image of code below

t = [1, 2, 3, 4, 5]
fig = plt.figure()
fig.patch.set_alpha(0.5)
fig.set_facecolor('b')
plt.plot(t, t)
fig2 = plt.figure()
fig2.set_facecolor('b')
plt.plot(t,t)
like image 711
schodge Avatar asked Jul 02 '14 23:07

schodge


1 Answers

I ran your code on Matplotlib 1.5 and found that it produced the expected output for me. For all happening on upon this in the future I give two concise ways of achieving this below.

A quick note, you definitely don't want to set transparent=True as an option for savefig as this will override the facecolors as you can see in the matplotlib.figure.savefig source.

To actually solve your problem the second link you posted How to set opacity of background colour of graph wit Matplotlib actually solves the problem. The issue with the code snippet in the question is the use of fig.set_facecolor as opposed to fig.patch.set_facecolor

Fix 1:

From the above linked question use the facecolor argument to savefig

import matplotlib.pyplot as plt

fig = plt.figure()
fig.patch.set_facecolor('b') # instead of fig.patch.set_facecolor
fig.patch.set_alpha(0.5)

plt.plot([1,3], [1,3])
plt.tight_layout()
plt.show()
plt.savefig('method1.png', facecolor=fig.get_facecolor())

Fix 2:

You can also specify the savefig facecolor through the rcParams.

import matplotlib.pyplot as plt
import matplotlib as mpl

fig = plt.figure()

col = 'blue'
#specify color of plot when showing in program. 
#fig.set_facecolor(col) also works
fig.patch.set_facecolor(col)
#specify color of background in saved figure
mpl.rcParams['savefig.facecolor'] = col 

#set the alpha for both plot in program and saved image
fig.patch.set_alpha(0.5)
plt.plot([1,3], [1,3])
plt.tight_layout()
plt.show()
plt.savefig('method2.png')

If you you would like your axes to have a background these solution should leave that background (such as produced by seaborn in Erotemic's comment) intact. If you want to be more explicit about it add:

ax.patch.set_color('palegoldenrod') # or whatever color you like
ax.patch.set_alpha(.7)

The axis patch alpha will transfer to savefig without extra effort.

Note that in both cases I used plt.tight_layout() to eliminate useless extra space in the saved figure. You can read more on that in the matplotlib documentation.

like image 102
Ianhi Avatar answered Sep 27 '22 03:09

Ianhi