Skip to content
mdehoon edited this page Jul 11, 2015 · 7 revisions

.. contents:: Table of Contents

.. author:: Michiel de Hoon

.. date:: July 11, 2015

Status

Discussion

Branches and Pull requests

None so far.

Abstract

To set the transparency (alpha component) of a graphics context, either gc.set_alpha(alpha) or gc.set_foreground(rgba, isRGBA=True) can be used. Currently, gc.set_alpha(alpha) forces the alpha value, meaning that gc.set_foreground(rgba, isRGBA=True) will ignore the alpha value of rgba if alpha was previously set through gc.set_alpha. Forcing alpha adds complexity to GraphicsContextBase as well as to the Cairo and MacOSX backends, in which this behavior is partially implemented.

Detailed description

Current API definition

In GraphicsContextBase, set_alpha is defined as follows:

    def set_alpha(self, alpha):
        """
        Set the alpha value used for blending - not supported on all backends.
        If ``alpha=None`` (the default), the alpha components of the
        foreground and fill colors will be used to set their respective
        transparencies (where applicable); otherwise, ``alpha`` will override
        them.
        """

while set_foreground is defined as

    def set_foreground(self, fg, isRGBA=False):
        """
        Set the foreground color.  fg can be a MATLAB format string, a
        html hex color string, an rgb or rgba unit tuple, or a float between 0
        and 1.  In the latter case, grayscale is used.

        If you know fg is rgba, set ``isRGBA=True`` for efficiency.
        """

As a concrete example,

a = 0.7
rgba = (1, 0, 0, 0.5) # red, 50% transparent
gc.set_alpha(a)
gc.set_foreground(rgba, isRGBA=True)

results in an alpha value of 0.7 being used; the 0.5 in rgba is ignored. While this is a trivial example, in cases where gc.set_alpha and gc.set_foreground appear in distant parts of the code (e.g. in different functions) it may not be obvious to the programmer that the alpha component of rgba is ignored.

Note that if in a particular case the programmer wants gc.set_alpha to override the alpha component in rgba, then simply passing the first three components of rgba will achieve the desired effect:

gc.set_alpha(a)
gc.set_foreground(rgba[:3], isRGBA=True)

results in an alpha value of 0.7 being used.

Actual usage of forced alpha in matplotlib

Calls to gc.set_alpha are made in:

  • In lib/matplotlib/image.py, in the draw methods of _AxesImageBase, PcolorImage, FigureImage, and BboxImage;
  • In lib/matplotlib/lines.py, in the draw method of Line2D (five calls total);
  • In lib/matplotlib/patches.py, in the draw methods of Patch and FancyArrowPatch;
  • In lib/matplotlib/patheffects.py, in the draw_path methods of SimplePatchShadow and SimpleLineShadow;
  • In lib/matplotlib/text.py, in the draw method of Text;
  • In lib/mpl_toolkits/axisartist/axis_artist.py, in the draw method of BezierPath and Ticks.

Note that these do not necessarily rely on the fact that gc.set_alpha(alpha) overrides gc.set_foreground(rgba); this remains to be verified.

Alternatives to forced alpha.

Implementation

  • Review the current usage of gc.set_alpha and make the required changes, if any;
  • Remove the _forced_alpha sections from GraphicsContextBase, RendererCairo, GraphicsContextCairo, RendererMac, GraphicsContextMac, and _macosx.GraphicsContext.

Backward compatibility

The proposal changes the usage of the graphics context only. Since the graphics context is part of the internal API of matplotlib, this proposal is not expected to affect end users.

Alternatives