Matplotlib convert canvas to RGBA

Question:

I am trying to modify the robotics toolbox to display the animation with a specific background colour. I manage to succeed in the real-time display, which renders the colour in RGBA, but while saving it to GIF, I lost the transparency.

As far as I understood, here is the function that displays the images and generates them. I added the self.fig.set_facecolor(color) (color is a tuple of four values between 0 and 1).

def getframe(self, color=False):
        global _pil

        if _pil is None:
            try:
                import PIL

                _pil = PIL.Image.frombytes
            except ImportError:  # pragma nocover
                pass

            if _pil is None:
                raise RuntimeError(
                    "to save movies PIL must be installed:npip3 install PIL"
                )

        # make the background white, looks better than grey stipple
        if isinstance(color, Boolean):
            self.ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
            self.ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
            self.ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
        else:
            self.ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
            self.ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
            self.ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
            self.fig.set_facecolor(color)
            
        plt.gcf().canvas.draw()

        # render the frame and save as a PIL image in the list
        canvas = self.fig.canvas
        return _pil("RGB", canvas.get_width_height(), canvas.tostring_rgb())

I tried to change the last line to

return _pil("RGBA", canvas.get_width_height(), canvas.tostring_rgb())

But I get a ValueError: not enough image data, I guess it’s because the function tostring_rgb remove the transparency.

Then I saw in the documentation there is a tostring_argb function, but, because the Alpha is at the beginning, the image is completely wrong. How to convert my canvas to RGBA (or to convert the ARGB to RGBA)?

Thanks in advance

Asked By: Dark Patate

||

Answers:

I found the way to transform the canvas to RGBA, the return should be replaced by:

return _pil("RGBA", canvas.get_width_height(), bytes(canvas.get_renderer().buffer_rgba())

However, I realised that GIF doesn’t use alpha transparency (it can be fully transparent, or fully opaque, but not in the middle). Then, I changed the format to .apng (animated PNG).

Answered By: Dark Patate