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> ):
<\/li><\/li>
<\/li>
<\/li><\/ul> Anyways, one problem is that I cannot<\/em> reproduce this with a minimal example. In my code, essentially I have to convert the figure to an image first, then process that image, then finally save it. So I tried making a minimal example, with a conversion to image data first, which is then being saved:
Ultimately, the image that is output by this code, for me, is with fully opaque white background - so this code does not demonstrate the problem.
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.