Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Change pcolormesh snapping (fixes alpha colorbar/grid issues) [AGG] #16090

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

Merged
merged 5 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
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
40 changes: 40 additions & 0 deletions doc/users/next_whats_new/pcolormesh_alpha_improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
pcolormesh has improved transparency handling by enabling snapping
------------------------------------------------------------------

Due to how the snapping keyword argument was getting passed to the AGG backend,
previous versions of Matplotlib would appear to show lines between the grid
edges of a mesh with transparency. This version now applies snapping
by default. To restore the old behavior (e.g., for test images), you may set
:rc:`pcolormesh.snap` to `False`.

.. plot::

import matplotlib.pyplot as plt
import numpy as np

# Use old pcolormesh snapping values
plt.rcParams['pcolormesh.snap'] = False
fig, ax = plt.subplots()
xx, yy = np.meshgrid(np.arange(10), np.arange(10))
z = (xx + 1) * (yy + 1)
mesh = ax.pcolormesh(xx, yy, z, shading='auto', alpha=0.5)
fig.colorbar(mesh, orientation='vertical')
ax.set_title('Before (pcolormesh.snap = False)')

Note that there are lines between the grid boundaries of the main plot which
are not the same transparency. The colorbar also shows these lines when a
transparency is added to the colormap because internally it uses pcolormesh
to draw the colorbar. With snapping on by default (below), the lines
at the grid boundaries disappear.

.. plot::

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
xx, yy = np.meshgrid(np.arange(10), np.arange(10))
z = (xx + 1) * (yy + 1)
mesh = ax.pcolormesh(xx, yy, z, shading='auto', alpha=0.5)
fig.colorbar(mesh, orientation='vertical')
ax.set_title('After (default: pcolormesh.snap = True)')
2 changes: 2 additions & 0 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6089,6 +6089,8 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords,
antialiased=antialiased, shading=shading,
**kwargs)
snap = kwargs.get('snap', rcParams['pcolormesh.snap'])
collection.set_snap(snap)
collection.set_alpha(alpha)
collection.set_array(C)
collection.set_cmap(cmap)
Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -2036,6 +2036,7 @@ def draw(self, renderer):
transOffset = transOffset.get_affine()

gc = renderer.new_gc()
gc.set_snap(self.get_snap())
self._set_gc_clip(gc)
gc.set_linewidth(self.get_linewidth()[0])

Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,7 @@ def _convert_validator_spec(key, conv):

## pcolor(mesh) props:
"pcolor.shading": ["auto", "flat", "nearest", "gouraud"],
"pcolormesh.snap": validate_bool,

## patch props
"patch.linewidth": validate_float, # line width in points
Expand Down
3 changes: 3 additions & 0 deletions lib/matplotlib/tests/test_agg_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
@image_comparison(baseline_images=['agg_filter_alpha'],
extensions=['png', 'pdf'])
def test_agg_filter_alpha():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

ax = plt.axes()
x, y = np.mgrid[0:7, 0:8]
data = x**2 - y**2
Expand Down
22 changes: 22 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,10 @@ def test_hexbin_pickable():
@image_comparison(['hexbin_log.png'], style='mpl20')
def test_hexbin_log():
# Issue #1636 (and also test log scaled colorbar)

# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

np.random.seed(19680801)
n = 100000
x = np.random.standard_normal(n)
Expand Down Expand Up @@ -992,6 +996,9 @@ def test_pcolorargs_5205():

@image_comparison(['pcolormesh'], remove_text=True)
def test_pcolormesh():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

n = 12
x = np.linspace(-1.5, 1.5, n)
y = np.linspace(-1.5, 1.5, n*2)
Expand All @@ -1014,6 +1021,9 @@ def test_pcolormesh():
@image_comparison(['pcolormesh_alpha'], extensions=["png", "pdf"],
remove_text=True)
def test_pcolormesh_alpha():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

n = 12
X, Y = np.meshgrid(
np.linspace(-1.5, 1.5, n),
Expand Down Expand Up @@ -1046,6 +1056,9 @@ def test_pcolormesh_alpha():
@image_comparison(['pcolormesh_datetime_axis.png'],
remove_text=False, style='mpl20')
def test_pcolormesh_datetime_axis():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure()
fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15)
base = datetime.datetime(2013, 1, 1)
Expand Down Expand Up @@ -1745,6 +1758,9 @@ def test_contour_hatching():

@image_comparison(['contour_colorbar'], style='mpl20')
def test_contour_colorbar():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

x, y, z = contour_dat()

fig = plt.figure()
Expand All @@ -1768,6 +1784,9 @@ def test_contour_colorbar():

@image_comparison(['hist2d', 'hist2d'], remove_text=True, style='mpl20')
def test_hist2d():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

np.random.seed(0)
# make it not symmetric in case we switch x and y axis
x = np.random.randn(100)*2+5
Expand All @@ -1785,6 +1804,9 @@ def test_hist2d():

@image_comparison(['hist2d_transpose'], remove_text=True, style='mpl20')
def test_hist2d_transpose():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

np.random.seed(0)
# make sure the output from np.histogram is transposed before
# passing to pcolorfast
Expand Down
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ def _colorbar_extension_length(spacing):
'colorbar_extensions_shape_proportional.png'])
def test_colorbar_extension_shape():
"""Test rectangular colorbar extensions."""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

# Create figures for uniform and proportionally spaced colorbars.
_colorbar_extension_shape('uniform')
_colorbar_extension_shape('proportional')
Expand All @@ -110,6 +113,9 @@ def test_colorbar_extension_shape():
'colorbar_extensions_proportional.png'])
def test_colorbar_extension_length():
"""Test variable length colorbar extensions."""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

# Create figures for uniform and proportionally spaced colorbars.
_colorbar_extension_length('uniform')
_colorbar_extension_length('proportional')
Expand All @@ -124,6 +130,9 @@ def test_colorbar_extension_length():
extensions=['png'], remove_text=True,
savefig_kwarg={'dpi': 40})
def test_colorbar_positioning(use_gridspec):
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

data = np.arange(1200).reshape(30, 40)
levels = [0, 200, 400, 600, 800, 1000, 1200]

Expand Down Expand Up @@ -232,6 +241,9 @@ def test_colorbarbase():

@image_comparison(['colorbar_closed_patch'], remove_text=True)
def test_colorbar_closed_patch():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure(figsize=(8, 6))
ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1])
ax2 = fig.add_axes([0.1, 0.65, 0.75, 0.1])
Expand Down
5 changes: 5 additions & 0 deletions lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,9 @@ def _mask_tester(norm_instance, vals):

@image_comparison(['levels_and_colors.png'])
def test_cmap_and_norm_from_levels_and_colors():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

data = np.linspace(-2, 4, 49).reshape(7, 7)
levels = [-1, 2, 2.5, 3]
colors = ['red', 'green', 'blue', 'yellow', 'black']
Expand All @@ -618,6 +621,8 @@ def test_cmap_and_norm_from_levels_and_colors():
@image_comparison(baseline_images=['boundarynorm_and_colorbar'],
extensions=['png'])
def test_boundarynorm_and_colorbarbase():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

# Make a figure and axes with dimensions as desired.
fig = plt.figure()
Expand Down
32 changes: 32 additions & 0 deletions lib/matplotlib/tests/test_constrainedlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ def test_constrained_layout2():
@image_comparison(['constrained_layout3.png'])
def test_constrained_layout3():
"""Test constrained_layout for colorbars with subplots"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True)
for nn, ax in enumerate(axs.flat):
pcm = example_pcolor(ax, fontsize=24)
Expand All @@ -64,6 +67,9 @@ def test_constrained_layout3():
@image_comparison(['constrained_layout4'])
def test_constrained_layout4():
"""Test constrained_layout for a single colorbar with subplots"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
pcm = example_pcolor(ax, fontsize=24)
Expand All @@ -76,6 +82,9 @@ def test_constrained_layout5():
Test constrained_layout for a single colorbar with subplots,
colorbar bottom
"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
pcm = example_pcolor(ax, fontsize=24)
Expand All @@ -87,6 +96,9 @@ def test_constrained_layout5():
@image_comparison(['constrained_layout6.png'])
def test_constrained_layout6():
"""Test constrained_layout for nested gridspecs"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure(constrained_layout=True)
gs = fig.add_gridspec(1, 2, figure=fig)
gsl = gs[0].subgridspec(2, 2)
Expand Down Expand Up @@ -126,6 +138,9 @@ def test_constrained_layout7():
@image_comparison(['constrained_layout8.png'])
def test_constrained_layout8():
"""Test for gridspecs that are not completely full"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure(figsize=(10, 5), constrained_layout=True)
gs = gridspec.GridSpec(3, 5, figure=fig)
axs = []
Expand Down Expand Up @@ -153,6 +168,9 @@ def test_constrained_layout8():
@image_comparison(['constrained_layout9.png'])
def test_constrained_layout9():
"""Test for handling suptitle and for sharex and sharey"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True,
sharex=False, sharey=False)
for ax in axs.flat:
Expand All @@ -176,6 +194,9 @@ def test_constrained_layout10():
@image_comparison(['constrained_layout11.png'])
def test_constrained_layout11():
"""Test for multiple nested gridspecs"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure(constrained_layout=True, figsize=(13, 3))
gs0 = gridspec.GridSpec(1, 2, figure=fig)
gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0])
Expand All @@ -195,6 +216,9 @@ def test_constrained_layout11():
@image_comparison(['constrained_layout11rat.png'])
def test_constrained_layout11rat():
"""Test for multiple nested gridspecs with width_ratios"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure(constrained_layout=True, figsize=(10, 3))
gs0 = gridspec.GridSpec(1, 2, figure=fig, width_ratios=[6, 1])
gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0])
Expand Down Expand Up @@ -236,6 +260,9 @@ def test_constrained_layout12():
@image_comparison(['constrained_layout13.png'], tol=2.e-2)
def test_constrained_layout13():
"""Test that padding works."""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
pcm = example_pcolor(ax, fontsize=12)
Expand All @@ -246,6 +273,9 @@ def test_constrained_layout13():
@image_comparison(['constrained_layout14.png'])
def test_constrained_layout14():
"""Test that padding works."""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
pcm = example_pcolor(ax, fontsize=12)
Expand Down Expand Up @@ -374,6 +404,8 @@ def test_colorbar_location():
Test that colorbar handling is as expected for various complicated
cases...
"""
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, axs = plt.subplots(4, 5, constrained_layout=True)
for ax in axs.flat:
Expand Down
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ def test_contour_labels_size_color():

@image_comparison(['contour_manual_colors_and_levels.png'], remove_text=True)
def test_given_colors_levels_and_extends():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

_, axs = plt.subplots(2, 4)

data = np.arange(12).reshape(3, 4)
Expand Down Expand Up @@ -316,6 +319,9 @@ def test_clabel_zorder(use_clabeltext, contour_zorder, clabel_zorder):
@image_comparison(['contour_log_extension.png'],
remove_text=True, style='mpl20')
def test_contourf_log_extension():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

# Test that contourf with lognorm is extended correctly
fig = plt.figure(figsize=(10, 5))
fig.subplots_adjust(left=0.05, right=0.95)
Expand Down Expand Up @@ -355,6 +361,9 @@ def test_contourf_log_extension():
# tolerance is because image changed minutely when tick finding on
# colorbars was cleaned up...
def test_contour_addlines():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig, ax = plt.subplots()
np.random.seed(19680812)
X = np.random.rand(10, 10)*10000
Expand All @@ -369,6 +378,9 @@ def test_contour_addlines():
@image_comparison(baseline_images=['contour_uneven'],
extensions=['png'], remove_text=True, style='mpl20')
def test_contour_uneven():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

z = np.arange(24).reshape(4, 6)
fig, axs = plt.subplots(1, 2)
ax = axs[0]
Expand Down
3 changes: 3 additions & 0 deletions lib/matplotlib/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,9 @@ def test_image_preserve_size2():

@image_comparison(['mask_image_over_under.png'], remove_text=True)
def test_mask_image_over_under():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

delta = 0.025
x = y = np.arange(-3.0, 3.0, delta)
X, Y = np.meshgrid(x, y)
Expand Down
3 changes: 3 additions & 0 deletions lib/matplotlib/tests/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def test_simple():
@image_comparison(['multi_pickle.png'], remove_text=True, style='mpl20',
tol={'aarch64': 0.082}.get(platform.machine(), 0.0))
def test_complete():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

fig = plt.figure('Figure with a label?', figsize=(10, 6))

plt.suptitle('Can you fit any more in a figure?')
Expand Down
3 changes: 3 additions & 0 deletions lib/matplotlib/tests/test_streamplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ def test_startpoints():
@image_comparison(['streamplot_colormap'],
tol=.04, remove_text=True, style='mpl20')
def test_colormap():
# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

X, Y, U, V = velocity_field()
plt.streamplot(X, Y, U, V, color=U, density=0.6, linewidth=2,
cmap=plt.cm.autumn)
Expand Down
4 changes: 4 additions & 0 deletions lib/matplotlib/tests/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def test_pre_transform_plotting():
# a catch-all for as many as possible plot layouts which handle
# pre-transforming the data NOTE: The axis range is important in this
# plot. It should be x10 what the data suggests it should be

# Remove this line when this test image is regenerated.
plt.rcParams['pcolormesh.snap'] = False

ax = plt.axes()
times10 = mtransforms.Affine2D().scale(10)

Expand Down
Loading