Skip to content

Doc update antialiasing #18749

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

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions examples/images_contours_and_fields/image_antialiasing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.cm as cm

###############################################################################
# First we generate a 500x500 px image with varying frequency content:
Expand Down Expand Up @@ -72,6 +74,81 @@
ax.set_title(f"interpolation='{interp}'")
plt.show()

###############################################################################
# Data antialiasing and RGBA antialiasing
Copy link
Member

Choose a reason for hiding this comment

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

I'd name this "Antialiasing colormapped data" and add a same-level "Antialiasing grayscale images".

And make some subsubsections here for "Data antialiasing" and "RGBA antialiasing".

// Well technically, grayscale is also a colormapping. The real difference is whether the colormapping is a straight line in RGB space or not. But I wouldn't go into the details here. Almost all colorful maps have quite some curve in RGB space.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not quite sure what you mean here? The first section was all about data antialiasing, with black and white chosen to make it obvious what was going one. This section is pointing out that this antialiasing is not the same as visual anti-aliasing.

# ----------------------------------------
#
# The examples above all used grayscale. When colormapping is added there
# is the complication that downsampling and the antialiasing filters are
# applied to the data in Matplotlib, before the data is mapped to
# colors. So in the following note how the corners fade to white, the middle
# of the colormap, because the data is being smoothed and the high and low
# values are averaging out to the middle of the colormap.

f0 = 10
k = 150
a = np.sin(np.pi * 2 * (f0 * R + k * R**2 / 2))

fig, axs = plt.subplots(1, 2, figsize=(7, 4), sharex=True, sharey=True,
constrained_layout=True)
for ax, interp in zip(axs, ['nearest', 'antialiased']):
pc = ax.imshow(a, interpolation=interp, cmap='RdBu_r', vmin=-1, vmax=1)
ax.set_title(f"'{interp}'")
fig.colorbar(pc, ax=axs)
plt.show()

###############################################################################
# Sometimes, however, we want the antialiasing to occur in RGBA space. In
# this case purple is actually the perceptual mixture of red and blue.
# Matplotlib doesn't allow this to be directly achieved, but we can pass
# RGBA data to `~.Axes.imshow`, and then the antialiasing filter will be
# applied to the RGBA data:

fig, axs = plt.subplots(1, 2, figsize=(7, 4), sharex=True, sharey=True,
constrained_layout=True)
norm = mcolors.Normalize(vmin=-1, vmax=1)
cmap = cm.RdBu_r
a_rgba = cmap(norm(a))
for ax, interp in zip(axs, ['nearest', 'antialiased']):
pc = ax.imshow(a_rgba, interpolation=interp)
ax.set_title(f"'{interp}'")
plt.show()

###############################################################################
# A concrete example of where antialiasing in data space may not be desirable
# is given here. The middle circle is all -1 (maps to blue), and the outer
# large circle is all +1 (maps to red). Data anti-aliasing smooths the
# large jumps from -1 to +1 and makes some zeros in between that map to white.
# While this is an accurate smoothing of the data, it is not a perceptually
# correct antialiasing of the border between red and blue. The RGBA
# anti-aliasing smooths in colorspace instead, and creates some purple pixels
# on the border between the two circles. While purple is not in the colormap,
# it indeed makes the transition between the two circles look correct.
# The same can be argued for the striped region, where the background fades to
# purple rather than fading to white.

fig, axs = plt.subplots(1, 3, figsize=(5.5, 2.3), sharex=True, sharey=True,
constrained_layout=True)
f0 = 10
k = 100
a = np.sin(np.pi * 2 * (f0 * R + k * R**2 / 2))

aa = a
aa[np.sqrt(R) < 0.6] = 1
aa[np.sqrt(R) < 0.5] = -1

norm = mcolors.Normalize(vmin=-1, vmax=1)
cmap = cm.RdBu_r
a_rgba = cmap(norm(aa))

axs[0].imshow(aa, interpolation='nearest', cmap='RdBu_r')
axs[0].set_title('No antialiasing')
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, CL sometimes has burbles like that if it is shrinking to fit rather than growing to fit. I just made the figure a bit bigger

axs[1].imshow(aa, interpolation=interp, cmap='RdBu_r')
axs[1].set_title('Data antialiasing')
pc = axs[2].imshow(a_rgba, interpolation=interp)
axs[2].set_title('RGBA antialiasing')
plt.show()


#############################################################################
#
Expand Down