You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Agg alpha image compositor differs from Matplotlib's software image compositor #8847
Matplotlib can also force software composition of overlapping images, which is, I guess, faster for vector backends (only one image ends up written to the file). For Agg, this is disabled; the Agg renderer does the compositing itself. But you can switch Agg back to use software composition with the following patch:
diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py
index c6af41b19..580cf0cf8 100644
--- a/lib/matplotlib/backends/backend_agg.py
+++ b/lib/matplotlib/backends/backend_agg.py
@@ -302,7 +302,7 @@ class RendererAgg(RendererBase):
# It is generally faster to composite each image directly to
# the Figure, and there's no file size benefit to compositing
# with the Agg backend
- return True
+ return False
def option_scale_image(self):
"""
With the patch on, the result is clearly different.
I haven't looked much into which one is correct (it should be easy to manually compute the result), although https://github.com/anntzer/mpl_cairo seems to agree visually with Matplotlib, not Agg.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
I think I figured part of this out while investigating #29711 (comment) (this only took me 7.5 years...).
Currently, RGBA blending is implementing using a "fixed" blender (fixed_blender_rgba_plain in agg_workaround.h) forward-ported from an even older version of Agg in #3777, apparently because the upstream version (blender_rgba_plain in agg_pixfmt_rgba.h) has lower precision. But the two blenders don't actually implement the same blending formulas! blender_rgba_plain blends in premultiplied alpha space (before backconverting to straight alpha at the end, see the final call to demultiply() in blend_pix()) whereas fixed_blender_rgba_plain blends in straight rgba space. These blenders are used in two different places (_image_resample.h and _backend_agg.h).
Note that the software-compositing option provided by matplotlib fundamentally relies on the ability to composite multiple images together before compositing them against the background, rather than compositing them one at a time against the background (see the explanation in _draw_list_compositing_images()), i.e. composition should be associative. But I believe(?) that only composition in premultiplied alpha space is associative, not composition in straight alpha space(?).
So the fix is likely to switch the blenders to use the formulas of blender_rgba_plain (possibly tweaking them to improve their precision?). We should probably check carefully the consequences of switching _image_resample.h and _backend_agg.h separately...
Edit: Actually no, looks like the formulas in agg_workaround.h are correct too? But switching the blenders does change some results. Still to be investigated.
Activity
github-actions commentedon Apr 14, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
anntzer commentedon Apr 14, 2023
I have verified that the discrepancy is still present.
anntzer commentedon Mar 17, 2025
I think I figured part of this out while investigating #29711 (comment) (this only took me 7.5 years...).
Currently, RGBA blending is implementing using a "fixed" blender (fixed_blender_rgba_plain in agg_workaround.h) forward-ported from an even older version of Agg in #3777, apparently because the upstream version (blender_rgba_plain in agg_pixfmt_rgba.h) has lower precision. But the two blenders don't actually implement the same blending formulas! blender_rgba_plain blends in premultiplied alpha space (before backconverting to straight alpha at the end, see the final call to demultiply() in blend_pix()) whereas fixed_blender_rgba_plain blends in straight rgba space. These blenders are used in two different places (_image_resample.h and _backend_agg.h).
Note that the software-compositing option provided by matplotlib fundamentally relies on the ability to composite multiple images together before compositing them against the background, rather than compositing them one at a time against the background (see the explanation in _draw_list_compositing_images()), i.e. composition should be associative. But I believe(?) that only composition in premultiplied alpha space is associative, not composition in straight alpha space(?).
So the fix is likely to switch the blenders to use the formulas of blender_rgba_plain (possibly tweaking them to improve their precision?). We should probably check carefully the consequences of switching _image_resample.h and _backend_agg.h separately...
Edit: Actually no, looks like the formulas in agg_workaround.h are correct too? But switching the blenders does change some results. Still to be investigated.
QuLogic commentedon Jul 23, 2026
@ayshih Not sure if you've seen this over your blending/compositing mode PR.
ayshih commentedon Jul 23, 2026
Ah, thanks for putting this issue on my radar! I think I know where to look