GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fixes Agg/Cairo antialiased rendering of contourf/pcolor/pcolormesh by using a blend group by ayshih · Pull Request #32256 · matplotlib/matplotlib

Conversation

@ayshih

@ayshih ayshih commented Aug 28, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

PR summary

This PR fixes Agg/Cairo antialiased rendering of contourf/pcolor/pcolormesh by using a blend group (see #31162, where these fixes were separated out of). In the examples below, look at the right-most panel and see how the faint lines between antialiased patches are fixed by this PR. The middle panel shows why it is desirable to turn on antialiasing when alpha < 1.

Since these fixes require #31162, this PR cannot be backported to 3.11.x.

contourf

import matplotlib
#matplotlib.use('TkCairo')

import numpy as np

import matplotlib.pyplot as plt

x = np.arange(1, 6)
y = x.reshape(-1, 1)
data = (x * y).astype(float)
data[2, 2] = np.nan

fig, axs = plt.subplots(1, 3, figsize=(5, 2), layout="constrained")

for i, antialiased in enumerate([None, False, True]):
    kwargs = {'cmap': 'jet', 'alpha': 0.5}
    if antialiased is not None:
        kwargs['antialiased'] = antialiased

    axs[i].contourf(data, levels=np.arange(1, 25, 1), extend="both", **kwargs)

    axs[i].set_aspect("equal")
    axs[i].set_axis_off()
    axs[i].set_title(f"antialiased={antialiased}" if antialiased is not None else "default")

plt.show()

Before this PR

1 before

After this PR

1 after

pcolor/pcolormesh

import matplotlib
#matplotlib.use('TkCairo')

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

N = 5
data = np.arange(N**2, dtype=float).reshape((N, N))
data[2, 2] = np.nan

x, y = np.meshgrid(np.arange(N + 1), np.arange(N + 1))

rotation = Affine2D().rotate(1)

fig, axs = plt.subplots(2, 3, figsize=(5, 3.5), layout="constrained")

for i, antialiased in enumerate([None, False, True]):
    kwargs = {'cmap': 'jet', 'alpha': 0.5}
    if antialiased is not None:
        kwargs['antialiased'] = antialiased

    axs[0, i].pcolormesh(x, y, data, transform=rotation + axs[0, i].transData,
                         **kwargs)
    axs[1, i].pcolor(x, y, data, transform=rotation + axs[1, i].transData, **kwargs)

    for j in range(2):
        axs[j, i].set_aspect("equal")
        axs[j, i].set_axis_off()
    axs[0, i].set_title(f"antialiased={antialiased}" if antialiased is not None else "default")

plt.show()

Before this PR

2 before

After this PR

2 after

AI Disclosure

No AI was used

PR quality check

  • Use an expressive title, e.g. "Fix title font property precedence"
  • New and changed code is tested
  • [N/A] Plotting related features are demonstrated in an example
  • New features and API changes have release notes
  • [N/A] Documentation complies with general and docstring guidelines

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

rcomer reacted with heart emoji
All reactions
  • ❤️ 1 reaction
@github-actions github-actions Bot added backend: agg backend: cairo topic: collections and mappables topic: contour topic: canvas and figure manager labels Aug 28, 2026
@ayshih
ayshih force-pushed the fixes_using_blending branch 2 times, most recently from 7741f0b to 3c1da25 Compare August 28, 2026 20:14
@ayshih
ayshih marked this pull request as ready for review August 28, 2026 20:35
@QuLogic QuLogic added this to the v3.12.0 milestone Aug 28, 2026
@QuLogic

QuLogic commented Aug 29, 2026

Copy link
Copy Markdown
Member

Would it make sense/work to apply this to all Collections?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iccir

iccir commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Can you explain what exactly is happening and why it's fixed via a plus blend mode? I think that may have gotten buried in the other PR.

My first reaction was "this makes basic sense, but I need to look up the formula for Plus again."

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer rcomer mentioned this pull request Aug 29, 2026
contourf workaround SciTools/iris#7261
Open
iccir
iccir approved these changes Aug 29, 2026
View reviewed changes

@iccir iccir left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment about why "plus" was chosen, but there are also existing comments in the source base about this + intermediate buffers.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rcomer

rcomer commented Aug 29, 2026

Copy link
Copy Markdown
Member

The pcolor docstring states

matplotlib/lib/matplotlib/axes/_axes.py

Lines 6697 to 6699 in 17552e2

The default *antialiaseds* is False if the default
*edgecolors*\ ="none" is used. This eliminates artificial lines
at patch boundaries, and works regardless of the value of alpha.

Those artificial lines are now gone, so this explanation no longer makes sense. Should we change the default? The default for pcolormesh and contourfis alsoFalse, but I have not found statements about why for those.

iccir reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iccir

iccir commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Those artificial lines are now gone, so this explanation no longer makes sense. Should we change the default? The default for pcolormesh and contourfis alsoFalse, but I have not found statements about why for those.

I'm +1 on "default to the more-correct-looking option", unless there are other concerns.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ayshih

ayshih commented Aug 31, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

Can you explain what exactly is happening and why it's fixed via a plus blend mode?

It's because the alpha at the edge of an antialiased patch represents how much the edge fills the pixel. When two patches are exactly adjacent and should fill the pixel entirely to a resulting alpha_combined, the alphas ought to be added up (alpha_1 + alpha_2 = alpha_combined). However, standard blend modes treat the alphas as unrelated opacities, so the resulting blended alpha is alpha_1 + alpha_2 - alpha_1 * alpha_2, which is less than alpha_combined. That's why the existing code produces lighter lines at patch edges; the alpha is smaller than it should be. So, the "plus" blend mode, which is actually a Porter-Duff compositing operator, is exactly what is needed to get the correct result.

Maybe add a comment about why "plus" was chosen, but there are also existing comments in the source base about this + intermediate buffers.

I've added (fairly wordy) comments in the code, which should help future maintainers.

Would it make sense/work to apply this to all Collections?

No. I believe these are the only collections where the patches are expressly constructed to be abutting with no overlaps. A collection in general could have overlapping patches, and the "plus" blend mode would give a bad result.

Those artificial lines are now gone, so this explanation no longer makes sense. Should we change the default? The default for pcolormesh and contourfis alsoFalse, but I have not found statements about why for those.

I've changed all three so they no longer forcefully disable antialiasing by default, and now the default is simply rcParams["patch.antialiased"].

iccir reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ayshih
ayshih force-pushed the fixes_using_blending branch from f796bc6 to 0f876cf Compare August 31, 2026 12:12
@rcomer

rcomer commented Aug 31, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Would it make sense/work to apply this to all Collections?

No. I believe these are the only collections where the patches are expressly constructed to be abutting with no overlaps. A collection in general could have overlapping patches, and the "plus" blend mode would give a bad result.

Is there a way that downstream libraries could take advantage of this functionality for their own collections? For example, Cartopy has a collection that enables drawing choropleth maps.
https://cartopy.readthedocs.io/stable/gallery/scalar_data/geometry_data.html

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ayshih
ayshih marked this pull request as draft August 31, 2026 15:17
@ayshih

ayshih commented Aug 31, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

I'm dropping this PR back to draft in order to revise the approach. I realized that Axes.tricontourf() and Axes.tripcolor() also need these fixes, plus as @rcomer noted, it'd be nice if an external package can indicate that this type of rendering is appropriate for a collection.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iccir
iccir self-requested a review August 31, 2026 17:54
@github-actions github-actions Bot added the topic: tri label Aug 31, 2026
@ayshih
ayshih force-pushed the fixes_using_blending branch 2 times, most recently from b34d542 to 5d84818 Compare September 1, 2026 04:02
@github-actions github-actions Bot added the topic: mplot3d label Sep 1, 2026
@ayshih
ayshih force-pushed the fixes_using_blending branch 5 times, most recently from da320b8 to 3c48df7 Compare September 2, 2026 16:58
@ayshih
ayshih force-pushed the fixes_using_blending branch 3 times, most recently from 4b5f5ca to 32b1c1c Compare September 5, 2026 05:55
@github-actions github-actions Bot added the status: needs rebase label Oct 9, 2026
@ayshih
ayshih force-pushed the fixes_using_blending branch from 32b1c1c to 5933db1 Compare October 9, 2026 13:15
@github-actions github-actions Bot removed the status: needs rebase label Oct 9, 2026
@ayshih
ayshih force-pushed the fixes_using_blending branch from 5933db1 to 819940b Compare October 9, 2026 15:12
ayshih added 6 commits October 9, 2026 14:57
@ayshih
Remove the forced disabling of antialiasing in contourf/pcolormesh/pc…
b806969
…olor/tripcolor
@ayshih
Fix Agg/Cairo pcolormesh by using an isolated blend group
0445841
@ayshih
Fix Agg/Cairo contiguous collections by using an isolated blend group
4e3fee4
@ayshih
Change hexbin default edgecolor to none
a0bc455
@ayshih
Update baseline images
be52ea4
@ayshih
change approach to use a context manager
3fac1dc
@ayshih
ayshih force-pushed the fixes_using_blending branch from 819940b to 3fac1dc Compare October 9, 2026 19:17
@github-actions github-actions Bot added the topic: pyplot API label Oct 9, 2026
@ayshih ayshih mentioned this pull request Oct 12, 2026
Add blend modes that maximize/minimize the pixel coverage #32469
Draft
1 of 5 tasks
@github-actions github-actions Bot added the status: needs rebase label Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@iccir iccir Awaiting requested review from iccir

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

backend: agg backend: cairo status: needs rebase topic: canvas and figure manager topic: collections and mappables topic: contour topic: mplot3d topic: pyplot API topic: tri

Projects

None yet

Milestone

v3.12.0

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@ayshih @QuLogic @iccir @rcomer
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.