简体   繁体   中英

Cannot change background color of matplotlib Figure (when saving as image)?

The actual problem that I have, is that - in the code I'm working on: when I try to save the plot image, I get the plot background in the image as fully transparent, so it looks like this in an image viewer (here eom<\/code> , Mate's version of eog<\/code> ):

Ok, found the solution - this required some debugging and drilling down of code; it turns out, one of the forest of libraries I include in my code, decided to change matplotlib figure properties - so here is a bit of a writeup:

So, after my attempt to use pdb to debug this failed ( Inspecting a variable value in other stack frames in pdb? ), I found How do you watch a variable in pdb - which recommended the watchpoints library.

So basically, after my figure init ( self.fig = plt.figure(... ), I did:

watch(self.fig.patch._facecolor)

... and ran the code; and finally I got something like this in the terminal printout:

====== Watchpoints Triggered ======
Call Stack (most recent call last):
...
>   figure.patch.set_alpha(0)
  set_alpha (~/venv/lib/python3.8/site-packages/matplotlib/patches.py:394):
>   self._set_facecolor(self._original_facecolor)
  to_rgba (~/venv/lib/python3.8/site-packages/matplotlib/colors.py:192):
>   return rgba
self.fig.patch._facecolor:
(1.0, 1.0, 1.0, 1.0)
->
(1.0, 1.0, 1.0, 0)

So, one of these libraries ended up calling figure.patch.set_alpha(0) - which turns out to be a bit nastier than one would deduce from the naming alone; namely, once it is set to 0 - it will prohibit entering any other alpha value, whenever you want to set the face color!!! Here is a code that reproduces that, based on the OP code:

import matplotlib as mpl
print(f"{mpl.__version__}")
import matplotlib.pyplot as plt
import numpy as np
import io

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)

subplotpars = dict(left = 0.05, right=0.99, top=0.89, wspace=0.1)
gss = mpl.gridspec.GridSpec(2,1, height_ratios=(2, 1), **subplotpars),

fig = plt.figure()
gs = gss[0]
ax = fig.add_subplot(gs[0,0])

ax.plot(t, s, color=(0.4, 0.2, 0.6, 0.6))

print(f"A {fig.get_facecolor()=}, {fig.get_alpha()=}")
print(f"A {fig.patch.get_facecolor()=}, {fig.patch.get_alpha()=}")

fig.patch.set_alpha(0)

print(f"B {fig.get_facecolor()=}, {fig.get_alpha()=}")
print(f"B {fig.patch.get_facecolor()=}, {fig.patch.get_alpha()=}")

fig.patch.set_facecolor( (0.9, 0.9, 0.9, 1.0) )

print(f"C {fig.get_facecolor()=}, {fig.get_alpha()=}")
print(f"C {fig.patch.get_facecolor()=}, {fig.patch.get_alpha()=}")

with io.BytesIO() as buf:
    fig.savefig(buf, dpi=120, format="png", facecolor=(1.0, 1.0, 1.0, 1.0))
    buf.seek(0)
    fig_rgba = plt.imread(buf)

plt.imsave('example_io.png', fig_rgba, dpi=120)

This prints:

3.5.1
A fig.get_facecolor()=(1.0, 1.0, 1.0, 1.0), fig.get_alpha()=None
A fig.patch.get_facecolor()=(1.0, 1.0, 1.0, 1.0), fig.patch.get_alpha()=None
B fig.get_facecolor()=(1.0, 1.0, 1.0, 0), fig.get_alpha()=None
B fig.patch.get_facecolor()=(1.0, 1.0, 1.0, 0), fig.patch.get_alpha()=0
C fig.get_facecolor()=(0.9, 0.9, 0.9, 0), fig.get_alpha()=None
C fig.patch.get_facecolor()=(0.9, 0.9, 0.9, 0), fig.patch.get_alpha()=0

So - with fig.patch.set_alpha(0) having ran once, even if I set fig.patch.set_facecolor( (0.9, 0.9, 0.9, 1.0) ) afterward (which explicitly sets alpha to 0) - the actual fill color that ends up in the object, still has alpha=0 (as printout C shows)!

So if you run that code, you still get transparent background in the image.

The solution turns out to be - just set fig.patch.set_alpha(1.0) right before the fig.savefig call:

# ...
with io.BytesIO() as buf:
    fig.patch.set_alpha(1.0)
    fig.savefig(buf, dpi=120, format="png", facecolor=(1.0, 1.0, 1.0, 1.0))
    # ...

Boy.... Now those were some wasted hours of my life... I wish someone would invent some machines, that you could program ... oh wait

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM