Skip to content
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

[Bug]: Gifs no longer create transparent background #27173

Open
JohannesWal opened this issue Oct 23, 2023 · 2 comments
Open

[Bug]: Gifs no longer create transparent background #27173

JohannesWal opened this issue Oct 23, 2023 · 2 comments

Comments

@JohannesWal
Copy link

Bug summary

Matplotlib is no longer able to create gifs with a transparent background.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], 'ro')

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)


savefig_kwargs = {
    "facecolor": "none",
}
ani.save("test.gif", savefig_kwargs=savefig_kwargs)

Actual outcome

With Matplotlib version 3.8.0 (and also 3.7.3) installed this is the ouput:
3 8 0

A gif-file with a white background

Expected outcome

In 3.6.3 and before the file had a transparent background

3 6 3

Additional information

I tried many different setups, different values for facecolor (e.g. (1,1,1,1)), set "transparent": True and googeling quite a lot - old solutions on github won't work.

Like in the expected outcome stated, this worked in the past (until Matplotlib 3.6.3).

There either seems to be an error in the fix for another issue in #21831 - or this is now the new correct behavior, but it seems like the transparency should still work for gifs, as this was an issue with different formats.

Operating system

Windows 11

Matplotlib Version

3.8.0

Matplotlib Backend

TkAgg

Python version

Python 3.12.0

Jupyter version

No response

Installation

pip

@cgadal
Copy link
Contributor

cgadal commented Oct 27, 2023

It seems it comes from:

def _pre_composite_to_white(color):
r, g, b, a = mcolors.to_rgba(color)
return a * np.array([r, g, b]) + 1 - a
savefig_kwargs['facecolor'] = _pre_composite_to_white(facecolor)

where pre_composite_to_white matches 'none' to a white color.

Is this intended behaviour @tacaswell (I think you added this ?)

@Wuzuw
Copy link

Wuzuw commented Nov 24, 2023

@cgadal @JohannesWal @tacaswell

Me and two fellow students have been looking into this issue as part of a project.
So far we have found that the fix you mentioned takes alpha and therefore transparency out of the equation. As far as we understand it simulates transparency by scaling the color and making it appear "faded" over a white background. But actually it transforms the rgba value to a rgb value (no transparency).

If you hardcode a rgba value then the previous problem returns (the blocky looks). However only if you don't use ffmpeg and only the pillowwriter.

We think this could be solved by checking which writer is used and only allowing "true" transparency when using ffmpeg and using the previous fix without it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants