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

Skip to content

Commit d85adce

Browse files
authored
Merge pull request #16090 from greglucas/pcolormesh_snapping
Change pcolormesh snapping (fixes alpha colorbar/grid issues) [AGG]
2 parents 5a9191b + f31c51a commit d85adce

19 files changed

+156
-9
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
pcolormesh has improved transparency handling by enabling snapping
2+
------------------------------------------------------------------
3+
4+
Due to how the snapping keyword argument was getting passed to the AGG backend,
5+
previous versions of Matplotlib would appear to show lines between the grid
6+
edges of a mesh with transparency. This version now applies snapping
7+
by default. To restore the old behavior (e.g., for test images), you may set
8+
:rc:`pcolormesh.snap` to `False`.
9+
10+
.. plot::
11+
12+
import matplotlib.pyplot as plt
13+
import numpy as np
14+
15+
# Use old pcolormesh snapping values
16+
plt.rcParams['pcolormesh.snap'] = False
17+
fig, ax = plt.subplots()
18+
xx, yy = np.meshgrid(np.arange(10), np.arange(10))
19+
z = (xx + 1) * (yy + 1)
20+
mesh = ax.pcolormesh(xx, yy, z, shading='auto', alpha=0.5)
21+
fig.colorbar(mesh, orientation='vertical')
22+
ax.set_title('Before (pcolormesh.snap = False)')
23+
24+
Note that there are lines between the grid boundaries of the main plot which
25+
are not the same transparency. The colorbar also shows these lines when a
26+
transparency is added to the colormap because internally it uses pcolormesh
27+
to draw the colorbar. With snapping on by default (below), the lines
28+
at the grid boundaries disappear.
29+
30+
.. plot::
31+
32+
import matplotlib.pyplot as plt
33+
import numpy as np
34+
35+
fig, ax = plt.subplots()
36+
xx, yy = np.meshgrid(np.arange(10), np.arange(10))
37+
z = (xx + 1) * (yy + 1)
38+
mesh = ax.pcolormesh(xx, yy, z, shading='auto', alpha=0.5)
39+
fig.colorbar(mesh, orientation='vertical')
40+
ax.set_title('After (default: pcolormesh.snap = True)')

lib/matplotlib/axes/_axes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6090,6 +6090,8 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
60906090
collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords,
60916091
antialiased=antialiased, shading=shading,
60926092
**kwargs)
6093+
snap = kwargs.get('snap', rcParams['pcolormesh.snap'])
6094+
collection.set_snap(snap)
60936095
collection.set_alpha(alpha)
60946096
collection.set_array(C)
60956097
collection.set_cmap(cmap)

lib/matplotlib/collections.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,6 +2036,7 @@ def draw(self, renderer):
20362036
transOffset = transOffset.get_affine()
20372037

20382038
gc = renderer.new_gc()
2039+
gc.set_snap(self.get_snap())
20392040
self._set_gc_clip(gc)
20402041
gc.set_linewidth(self.get_linewidth()[0])
20412042

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ def _convert_validator_spec(key, conv):
11131113

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

11171118
## patch props
11181119
"patch.linewidth": validate_float, # line width in points

lib/matplotlib/tests/test_agg_filter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
@image_comparison(baseline_images=['agg_filter_alpha'],
88
extensions=['png', 'pdf'])
99
def test_agg_filter_alpha():
10+
# Remove this line when this test image is regenerated.
11+
plt.rcParams['pcolormesh.snap'] = False
12+
1013
ax = plt.axes()
1114
x, y = np.mgrid[0:7, 0:8]
1215
data = x**2 - y**2

lib/matplotlib/tests/test_axes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,10 @@ def test_hexbin_pickable():
731731
@image_comparison(['hexbin_log.png'], style='mpl20')
732732
def test_hexbin_log():
733733
# Issue #1636 (and also test log scaled colorbar)
734+
735+
# Remove this line when this test image is regenerated.
736+
plt.rcParams['pcolormesh.snap'] = False
737+
734738
np.random.seed(19680801)
735739
n = 100000
736740
x = np.random.standard_normal(n)
@@ -992,6 +996,9 @@ def test_pcolorargs_5205():
992996

993997
@image_comparison(['pcolormesh'], remove_text=True)
994998
def test_pcolormesh():
999+
# Remove this line when this test image is regenerated.
1000+
plt.rcParams['pcolormesh.snap'] = False
1001+
9951002
n = 12
9961003
x = np.linspace(-1.5, 1.5, n)
9971004
y = np.linspace(-1.5, 1.5, n*2)
@@ -1014,6 +1021,9 @@ def test_pcolormesh():
10141021
@image_comparison(['pcolormesh_alpha'], extensions=["png", "pdf"],
10151022
remove_text=True)
10161023
def test_pcolormesh_alpha():
1024+
# Remove this line when this test image is regenerated.
1025+
plt.rcParams['pcolormesh.snap'] = False
1026+
10171027
n = 12
10181028
X, Y = np.meshgrid(
10191029
np.linspace(-1.5, 1.5, n),
@@ -1046,6 +1056,9 @@ def test_pcolormesh_alpha():
10461056
@image_comparison(['pcolormesh_datetime_axis.png'],
10471057
remove_text=False, style='mpl20')
10481058
def test_pcolormesh_datetime_axis():
1059+
# Remove this line when this test image is regenerated.
1060+
plt.rcParams['pcolormesh.snap'] = False
1061+
10491062
fig = plt.figure()
10501063
fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15)
10511064
base = datetime.datetime(2013, 1, 1)
@@ -1750,6 +1763,9 @@ def test_contour_hatching():
17501763

17511764
@image_comparison(['contour_colorbar'], style='mpl20')
17521765
def test_contour_colorbar():
1766+
# Remove this line when this test image is regenerated.
1767+
plt.rcParams['pcolormesh.snap'] = False
1768+
17531769
x, y, z = contour_dat()
17541770

17551771
fig = plt.figure()
@@ -1773,6 +1789,9 @@ def test_contour_colorbar():
17731789

17741790
@image_comparison(['hist2d', 'hist2d'], remove_text=True, style='mpl20')
17751791
def test_hist2d():
1792+
# Remove this line when this test image is regenerated.
1793+
plt.rcParams['pcolormesh.snap'] = False
1794+
17761795
np.random.seed(0)
17771796
# make it not symmetric in case we switch x and y axis
17781797
x = np.random.randn(100)*2+5
@@ -1790,6 +1809,9 @@ def test_hist2d():
17901809

17911810
@image_comparison(['hist2d_transpose'], remove_text=True, style='mpl20')
17921811
def test_hist2d_transpose():
1812+
# Remove this line when this test image is regenerated.
1813+
plt.rcParams['pcolormesh.snap'] = False
1814+
17931815
np.random.seed(0)
17941816
# make sure the output from np.histogram is transposed before
17951817
# passing to pcolorfast

lib/matplotlib/tests/test_colorbar.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ def _colorbar_extension_length(spacing):
101101
'colorbar_extensions_shape_proportional.png'])
102102
def test_colorbar_extension_shape():
103103
"""Test rectangular colorbar extensions."""
104+
# Remove this line when this test image is regenerated.
105+
plt.rcParams['pcolormesh.snap'] = False
106+
104107
# Create figures for uniform and proportionally spaced colorbars.
105108
_colorbar_extension_shape('uniform')
106109
_colorbar_extension_shape('proportional')
@@ -110,6 +113,9 @@ def test_colorbar_extension_shape():
110113
'colorbar_extensions_proportional.png'])
111114
def test_colorbar_extension_length():
112115
"""Test variable length colorbar extensions."""
116+
# Remove this line when this test image is regenerated.
117+
plt.rcParams['pcolormesh.snap'] = False
118+
113119
# Create figures for uniform and proportionally spaced colorbars.
114120
_colorbar_extension_length('uniform')
115121
_colorbar_extension_length('proportional')
@@ -124,6 +130,9 @@ def test_colorbar_extension_length():
124130
extensions=['png'], remove_text=True,
125131
savefig_kwarg={'dpi': 40})
126132
def test_colorbar_positioning(use_gridspec):
133+
# Remove this line when this test image is regenerated.
134+
plt.rcParams['pcolormesh.snap'] = False
135+
127136
data = np.arange(1200).reshape(30, 40)
128137
levels = [0, 200, 400, 600, 800, 1000, 1200]
129138

@@ -232,6 +241,9 @@ def test_colorbarbase():
232241

233242
@image_comparison(['colorbar_closed_patch'], remove_text=True)
234243
def test_colorbar_closed_patch():
244+
# Remove this line when this test image is regenerated.
245+
plt.rcParams['pcolormesh.snap'] = False
246+
235247
fig = plt.figure(figsize=(8, 6))
236248
ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1])
237249
ax2 = fig.add_axes([0.1, 0.65, 0.75, 0.1])

lib/matplotlib/tests/test_colors.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,9 @@ def _mask_tester(norm_instance, vals):
608608

609609
@image_comparison(['levels_and_colors.png'])
610610
def test_cmap_and_norm_from_levels_and_colors():
611+
# Remove this line when this test image is regenerated.
612+
plt.rcParams['pcolormesh.snap'] = False
613+
611614
data = np.linspace(-2, 4, 49).reshape(7, 7)
612615
levels = [-1, 2, 2.5, 3]
613616
colors = ['red', 'green', 'blue', 'yellow', 'black']
@@ -625,6 +628,8 @@ def test_cmap_and_norm_from_levels_and_colors():
625628
@image_comparison(baseline_images=['boundarynorm_and_colorbar'],
626629
extensions=['png'])
627630
def test_boundarynorm_and_colorbarbase():
631+
# Remove this line when this test image is regenerated.
632+
plt.rcParams['pcolormesh.snap'] = False
628633

629634
# Make a figure and axes with dimensions as desired.
630635
fig = plt.figure()

lib/matplotlib/tests/test_constrainedlayout.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def test_constrained_layout2():
5151
@image_comparison(['constrained_layout3.png'])
5252
def test_constrained_layout3():
5353
"""Test constrained_layout for colorbars with subplots"""
54+
# Remove this line when this test image is regenerated.
55+
plt.rcParams['pcolormesh.snap'] = False
56+
5457
fig, axs = plt.subplots(2, 2, constrained_layout=True)
5558
for nn, ax in enumerate(axs.flat):
5659
pcm = example_pcolor(ax, fontsize=24)
@@ -64,6 +67,9 @@ def test_constrained_layout3():
6467
@image_comparison(['constrained_layout4'])
6568
def test_constrained_layout4():
6669
"""Test constrained_layout for a single colorbar with subplots"""
70+
# Remove this line when this test image is regenerated.
71+
plt.rcParams['pcolormesh.snap'] = False
72+
6773
fig, axs = plt.subplots(2, 2, constrained_layout=True)
6874
for ax in axs.flat:
6975
pcm = example_pcolor(ax, fontsize=24)
@@ -76,6 +82,9 @@ def test_constrained_layout5():
7682
Test constrained_layout for a single colorbar with subplots,
7783
colorbar bottom
7884
"""
85+
# Remove this line when this test image is regenerated.
86+
plt.rcParams['pcolormesh.snap'] = False
87+
7988
fig, axs = plt.subplots(2, 2, constrained_layout=True)
8089
for ax in axs.flat:
8190
pcm = example_pcolor(ax, fontsize=24)
@@ -87,6 +96,9 @@ def test_constrained_layout5():
8796
@image_comparison(['constrained_layout6.png'])
8897
def test_constrained_layout6():
8998
"""Test constrained_layout for nested gridspecs"""
99+
# Remove this line when this test image is regenerated.
100+
plt.rcParams['pcolormesh.snap'] = False
101+
90102
fig = plt.figure(constrained_layout=True)
91103
gs = fig.add_gridspec(1, 2, figure=fig)
92104
gsl = gs[0].subgridspec(2, 2)
@@ -126,6 +138,9 @@ def test_constrained_layout7():
126138
@image_comparison(['constrained_layout8.png'])
127139
def test_constrained_layout8():
128140
"""Test for gridspecs that are not completely full"""
141+
# Remove this line when this test image is regenerated.
142+
plt.rcParams['pcolormesh.snap'] = False
143+
129144
fig = plt.figure(figsize=(10, 5), constrained_layout=True)
130145
gs = gridspec.GridSpec(3, 5, figure=fig)
131146
axs = []
@@ -153,6 +168,9 @@ def test_constrained_layout8():
153168
@image_comparison(['constrained_layout9.png'])
154169
def test_constrained_layout9():
155170
"""Test for handling suptitle and for sharex and sharey"""
171+
# Remove this line when this test image is regenerated.
172+
plt.rcParams['pcolormesh.snap'] = False
173+
156174
fig, axs = plt.subplots(2, 2, constrained_layout=True,
157175
sharex=False, sharey=False)
158176
for ax in axs.flat:
@@ -176,6 +194,9 @@ def test_constrained_layout10():
176194
@image_comparison(['constrained_layout11.png'])
177195
def test_constrained_layout11():
178196
"""Test for multiple nested gridspecs"""
197+
# Remove this line when this test image is regenerated.
198+
plt.rcParams['pcolormesh.snap'] = False
199+
179200
fig = plt.figure(constrained_layout=True, figsize=(13, 3))
180201
gs0 = gridspec.GridSpec(1, 2, figure=fig)
181202
gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0])
@@ -195,6 +216,9 @@ def test_constrained_layout11():
195216
@image_comparison(['constrained_layout11rat.png'])
196217
def test_constrained_layout11rat():
197218
"""Test for multiple nested gridspecs with width_ratios"""
219+
# Remove this line when this test image is regenerated.
220+
plt.rcParams['pcolormesh.snap'] = False
221+
198222
fig = plt.figure(constrained_layout=True, figsize=(10, 3))
199223
gs0 = gridspec.GridSpec(1, 2, figure=fig, width_ratios=[6, 1])
200224
gsl = gridspec.GridSpecFromSubplotSpec(1, 2, gs0[0])
@@ -236,6 +260,9 @@ def test_constrained_layout12():
236260
@image_comparison(['constrained_layout13.png'], tol=2.e-2)
237261
def test_constrained_layout13():
238262
"""Test that padding works."""
263+
# Remove this line when this test image is regenerated.
264+
plt.rcParams['pcolormesh.snap'] = False
265+
239266
fig, axs = plt.subplots(2, 2, constrained_layout=True)
240267
for ax in axs.flat:
241268
pcm = example_pcolor(ax, fontsize=12)
@@ -246,6 +273,9 @@ def test_constrained_layout13():
246273
@image_comparison(['constrained_layout14.png'])
247274
def test_constrained_layout14():
248275
"""Test that padding works."""
276+
# Remove this line when this test image is regenerated.
277+
plt.rcParams['pcolormesh.snap'] = False
278+
249279
fig, axs = plt.subplots(2, 2, constrained_layout=True)
250280
for ax in axs.flat:
251281
pcm = example_pcolor(ax, fontsize=12)
@@ -374,6 +404,8 @@ def test_colorbar_location():
374404
Test that colorbar handling is as expected for various complicated
375405
cases...
376406
"""
407+
# Remove this line when this test image is regenerated.
408+
plt.rcParams['pcolormesh.snap'] = False
377409

378410
fig, axs = plt.subplots(4, 5, constrained_layout=True)
379411
for ax in axs.flat:

lib/matplotlib/tests/test_contour.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ def test_contour_labels_size_color():
137137

138138
@image_comparison(['contour_manual_colors_and_levels.png'], remove_text=True)
139139
def test_given_colors_levels_and_extends():
140+
# Remove this line when this test image is regenerated.
141+
plt.rcParams['pcolormesh.snap'] = False
142+
140143
_, axs = plt.subplots(2, 4)
141144

142145
data = np.arange(12).reshape(3, 4)
@@ -318,6 +321,9 @@ def test_clabel_zorder(use_clabeltext, contour_zorder, clabel_zorder):
318321
@image_comparison(['contour_log_extension.png'],
319322
remove_text=True, style='mpl20')
320323
def test_contourf_log_extension():
324+
# Remove this line when this test image is regenerated.
325+
plt.rcParams['pcolormesh.snap'] = False
326+
321327
# Test that contourf with lognorm is extended correctly
322328
fig = plt.figure(figsize=(10, 5))
323329
fig.subplots_adjust(left=0.05, right=0.95)
@@ -357,6 +363,9 @@ def test_contourf_log_extension():
357363
# tolerance is because image changed minutely when tick finding on
358364
# colorbars was cleaned up...
359365
def test_contour_addlines():
366+
# Remove this line when this test image is regenerated.
367+
plt.rcParams['pcolormesh.snap'] = False
368+
360369
fig, ax = plt.subplots()
361370
np.random.seed(19680812)
362371
X = np.random.rand(10, 10)*10000
@@ -371,6 +380,9 @@ def test_contour_addlines():
371380
@image_comparison(baseline_images=['contour_uneven'],
372381
extensions=['png'], remove_text=True, style='mpl20')
373382
def test_contour_uneven():
383+
# Remove this line when this test image is regenerated.
384+
plt.rcParams['pcolormesh.snap'] = False
385+
374386
z = np.arange(24).reshape(4, 6)
375387
fig, axs = plt.subplots(1, 2)
376388
ax = axs[0]

lib/matplotlib/tests/test_image.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,9 @@ def test_image_preserve_size2():
800800

801801
@image_comparison(['mask_image_over_under.png'], remove_text=True)
802802
def test_mask_image_over_under():
803+
# Remove this line when this test image is regenerated.
804+
plt.rcParams['pcolormesh.snap'] = False
805+
803806
delta = 0.025
804807
x = y = np.arange(-3.0, 3.0, delta)
805808
X, Y = np.meshgrid(x, y)

lib/matplotlib/tests/test_pickle.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ def test_simple():
4343
@image_comparison(['multi_pickle.png'], remove_text=True, style='mpl20',
4444
tol=0 if platform.machine() == 'x86_64' else 0.082)
4545
def test_complete():
46+
# Remove this line when this test image is regenerated.
47+
plt.rcParams['pcolormesh.snap'] = False
48+
4649
fig = plt.figure('Figure with a label?', figsize=(10, 6))
4750

4851
plt.suptitle('Can you fit any more in a figure?')

lib/matplotlib/tests/test_streamplot.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ def test_startpoints():
4141
@image_comparison(['streamplot_colormap'],
4242
tol=.04, remove_text=True, style='mpl20')
4343
def test_colormap():
44+
# Remove this line when this test image is regenerated.
45+
plt.rcParams['pcolormesh.snap'] = False
46+
4447
X, Y, U, V = velocity_field()
4548
plt.streamplot(X, Y, U, V, color=U, density=0.6, linewidth=2,
4649
cmap=plt.cm.autumn)

lib/matplotlib/tests/test_transforms.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ def test_pre_transform_plotting():
7373
# a catch-all for as many as possible plot layouts which handle
7474
# pre-transforming the data NOTE: The axis range is important in this
7575
# plot. It should be x10 what the data suggests it should be
76+
77+
# Remove this line when this test image is regenerated.
78+
plt.rcParams['pcolormesh.snap'] = False
79+
7680
ax = plt.axes()
7781
times10 = mtransforms.Affine2D().scale(10)
7882

0 commit comments

Comments
 (0)