-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Transparency always on for PNG in version 3.1.0 #14339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I would say that this is actually closer to the indended behavior: you requested that the figure has no frame, and then the Again, this points to the issue of having multiple kwargs that control the same thing: what happens when they are set in a conflicting manner? I guess, in the meantime, we could make |
There are two options:
2 is the current behavior and I'm leaning towards it. 1) doesn't make it possible to have axes patches but not figure patches visible. |
The main issue, for me, is that the new behavior breaks a test in a project of mine (comparing a generated image with a reference). Is there an, preferably easy, or simple mitigation, or migration path? |
The
would result in a plot without a transparent background because background transparency would be read from As argued elsewhere I think You can work around this (I think) with
|
@tacaswell I think you were going to write an explanation and close this, with the idea that the present behavior is intended. Correct? |
I'm going to claim that this is the intended behavior (see discussion above) and close this, especially as a workaround is available. |
Would it be possible to print a warning when Also it looks like fig = pyplot.figure()
pyplot.scatter([1,2,3], [1,3,2])
# Convert the image to an RGB array
fig.canvas.draw()
pixels = numpy.fromstring(fig.canvas.tostring_rgb(), dtype="uint8")
rgb = pixels.reshape(*fig.canvas.get_width_height()[::-1], 3)
pyplot.close()
pyplot.figure(dpi=100)
pyplot.imshow(rgb) |
The source of the problem with import matplotlib.pyplot as pyplot
import matplotlib as mpl
from matplotlib.backends.backend_agg import FigureCanvas
import numpy
# make the figure "by hand" to avoid hi-dpi issues
fig = mpl.figure.Figure(facecolor=(1, 1, 1, 0))
cv = FigureCanvas(fig)
fig.gca().scatter([1, 2, 3], [1, 3, 2])
fig.canvas.draw()
pixels = np.asarray(fig.canvas.buffer_rgba()) / 255
pyplot.close()
demo_fig, ax_d = pyplot.subplot_mosaic(
[["r", "g", "b", "a"], ["rgb", "rgba", ".", "blend"]], constrained_layout=True
)
for k, v in ax_d.items():
v.set_title(k)
for indx, k in enumerate("rgba"):
ax_d[k].imshow(pixels[:, :, indx])
ax_d["rgb"].imshow(pixels[:, :, :3])
ax_d["rgba"].imshow(pixels)
ax_d["blend"].imshow(pixels[:, :, 0:3] * pixels[:, :, 3:] + 1 * (1 - pixels[:, :, 3:]))
for k, v in ax_d.items():
v.set_title(k)
v.set_xlim(480, 600)
v.set_ylim(480, 300)
pyplot.show() @michaelosthege It is also not clear to me in what set of conditions you would want a warning? |
@tacaswell thanks for the explanation! I got bitten by this behavior pretty hard today, when I tried to make a GIF. My strategy of writing individual frames with Only when I found my files from January and compared the intermediate frames (good thing I saved them to disk), I noticed that even though they were all PNG, the new ones were transparent.
Generally something like All the solutions one finds when searching for "pyplot figure to numpy array" are really verbose code with buffers and reshaping. And they all suffer from #5336. |
As of 3.1.0 you can do: pixels = np.asarray(fig.canvas.buffer_rgba()) / 255 which gets you the full images as an array. The docs on this are:
which says setting this to True will make the axes and figure patches transparent if it is True, it makes no claims as to what it will do you you set the value False. On one hand I see the motivation "False means the patch is forced to be not transparent", but "False means do nothing" is also reasonable (and is what it actually does! One key problem with trying to implement anything for The default value of I'm going to open a PR adding "If False this will do nothing" to the docstring as I think that is the best course forward and will hopefully prevent future confusion / frustration. |
Just another +1 to the visibility of this issue, because upgrading matplotlib broke all my graphs. I tried for several hours to fix it before I found this bug, and the solution wasn't any of the things I expected. To fix it, I added Simple 1-line change, but definitely not obvious. |
Bug report
Bug summary
While saving a figure using
savefig
, the flag for transparency is ignored, and the resulting PNG has a transparent background, even though transparency is set toFalse
.Note: This affect matplotlib 3.1.0. The error did not occur in 3.0.3 on the same machine as described bellow.
Code for reproduction
Actual outcome
An empty PNG file, that is transparent.
Expected outcome
An empty PNG file with only a white background.
Matplotlib version
print(matplotlib.get_backend())
): module://backend_interaggPython was installed via pyenv (compiled from source), and matplotlib was installed through pipenv.
The text was updated successfully, but these errors were encountered: