Skip to content

Commit 3fac1dc

Browse files
committed
change approach to use a context manager
1 parent be52ea4 commit 3fac1dc

2 files changed

Lines changed: 80 additions & 79 deletions

File tree

‎lib/matplotlib/collections.py‎

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
they are meant to be fast for common use cases (e.g., a large set of solid
99
line segments).
1010
"""
11-
11+
import contextlib
1212
import itertools
1313
import functools
1414
import math
@@ -363,6 +363,32 @@ def _prepare_points(self):
363363

364364
return transform, offset_trf, offsets, paths
365365

366+
@contextlib.contextmanager
367+
def _prep_for_contiguous_drawing(self, renderer, gc):
368+
# Context manager to wrap the specific rendering commands within draw()
369+
370+
# If supported by the renderer, draw contiguous patches (must be antialiased
371+
# and not stroked) using the "plus" blend mode in an isolated blend group so
372+
# that the fractional alphas at edges are added to make the proper total alpha.
373+
# If the alphas were instead blended as if they were unrelated opacities,
374+
# the resulting alpha would be smaller (i.e., more transparent), which would
375+
# manifest as slightly transparent line artifacts along shared patch edges.
376+
isolate = (renderer._supports_isolated_group_and_plus_blend_mode
377+
and self._treat_patches_as_contiguous
378+
and np.all(self._antialiaseds)
379+
and (self._edgecolors.size == 0
380+
or np.all(self._edgecolors[:, 3] == 0)))
381+
if isolate:
382+
blend_mode = gc.get_blend_mode()
383+
gc.set_blend_mode("plus")
384+
renderer.open_blend_group(blend_mode)
385+
try:
386+
yield
387+
finally:
388+
if isolate:
389+
renderer.close_blend_group()
390+
gc.set_blend_mode(blend_mode)
391+
366392
@artist.allow_rasterization
367393
def draw(self, renderer):
368394
if not self.get_visible():
@@ -379,21 +405,6 @@ def draw(self, renderer):
379405

380406
transform, offset_trf, offsets, paths = self._prepare_points()
381407

382-
# If supported by the renderer, draw contiguous, antialiased patches without
383-
# strokes using the "plus" blend mode in an isolated blend group so that the
384-
# fractional alphas at edges are added to make the intended total alpha.
385-
# If the alphas were instead blended as if they were unrelated opacities,
386-
# the resulting alpha would be smaller (i.e., more transparent), which would
387-
# manifest as slightly transparent line artifacts along patch edges.
388-
isolate = (renderer._supports_isolated_group_and_plus_blend_mode
389-
and self._treat_patches_as_contiguous
390-
and np.all(self._antialiaseds)
391-
and (self._edgecolors.size == 0 or self._edgecolors[0][3] == 0))
392-
if isolate:
393-
blend_mode = self.get_blend_mode()
394-
self.set_blend_mode("plus")
395-
renderer.open_blend_group(blend_mode)
396-
397408
gc = renderer.new_gc()
398409
self._set_gc_clip(gc)
399410
gc.set_blend_mode(self.get_blend_mode())
@@ -447,9 +458,10 @@ def draw(self, renderer):
447458
gc.set_dashes(*self._linestyles[0])
448459
gc.set_antialiased(self._antialiaseds[0])
449460
gc.set_url(self._urls[0])
450-
renderer.draw_markers(
451-
gc, paths[0], combined_transform.frozen(),
452-
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
461+
with self._prep_for_contiguous_drawing(renderer, gc):
462+
renderer.draw_markers(
463+
gc, paths[0], combined_transform.frozen(),
464+
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
453465
else:
454466
# The current new API of draw_path_collection() is provisional
455467
# and will be changed in a future PR.
@@ -512,29 +524,28 @@ def draw(self, renderer):
512524
self._linewidths, self._linestyles, self._antialiaseds, self._urls,
513525
"screen"]
514526

515-
if hatchcolors_arg_supported:
516-
renderer.draw_path_collection(gc, transform.frozen(), paths,
517-
self.get_transforms(), *args,
518-
hatchcolors=self.get_hatchcolor())
519-
else:
520-
if hatchcolors_not_needed:
527+
with self._prep_for_contiguous_drawing(renderer, gc):
528+
if hatchcolors_arg_supported:
521529
renderer.draw_path_collection(gc, transform.frozen(), paths,
522-
self.get_transforms(), *args)
530+
self.get_transforms(), *args,
531+
hatchcolors=self.get_hatchcolor())
523532
else:
524-
path_ids = renderer._iter_collection_raw_paths(
525-
transform.frozen(), paths, self.get_transforms())
526-
for xo, yo, path_id, gc0, rgbFace in renderer._iter_collection(
527-
gc, list(path_ids), *args, hatchcolors=self.get_hatchcolor(),
528-
):
529-
path, transform = path_id
530-
if xo != 0 or yo != 0:
531-
transform = transform.frozen()
532-
transform.translate(xo, yo)
533-
renderer.draw_path(gc0, path, transform, rgbFace)
533+
if hatchcolors_not_needed:
534+
renderer.draw_path_collection(gc, transform.frozen(), paths,
535+
self.get_transforms(), *args)
536+
else:
537+
path_ids = renderer._iter_collection_raw_paths(
538+
transform.frozen(), paths, self.get_transforms())
539+
for xo, yo, path_id, gc0, rgbFace in renderer._iter_collection(
540+
gc, list(path_ids), *args,
541+
hatchcolors=self.get_hatchcolor(),
542+
):
543+
path, transform = path_id
544+
if xo != 0 or yo != 0:
545+
transform = transform.frozen()
546+
transform.translate(xo, yo)
547+
renderer.draw_path(gc0, path, transform, rgbFace)
534548

535-
if isolate:
536-
renderer.close_blend_group()
537-
self.set_blend_mode(blend_mode)
538549
gc.restore()
539550
renderer.close_group(self.__class__.__name__)
540551
self.stale = False
@@ -2548,11 +2559,13 @@ def __init__(self, coordinates, *, antialiased=True, shading='flat',
25482559
super().__init__(coordinates=coordinates, shading=shading)
25492560
Collection.__init__(self, **kwargs)
25502561

2551-
self._antialiased = antialiased
2562+
self._antialiaseds = antialiased
25522563
self._bbox = transforms.Bbox.unit()
25532564
self._bbox.update_from_data_xy(self._coordinates.reshape(-1, 2))
25542565
self.set_mouseover(False)
25552566

2567+
self._treat_patches_as_contiguous = True
2568+
25562569
def get_paths(self):
25572570
if self._paths is None:
25582571
self.set_paths()
@@ -2570,7 +2583,6 @@ def draw(self, renderer):
25702583
if not self.get_visible():
25712584
return
25722585
renderer.open_group(self.__class__.__name__, self.get_gid())
2573-
25742586
transform = self.get_transform()
25752587
offset_trf = self.get_offset_transform()
25762588
offsets = self.get_offsets()
@@ -2600,34 +2612,19 @@ def draw(self, renderer):
26002612
gc.set_blend_mode(self.get_blend_mode())
26012613
gc.set_linewidth(self.get_linewidth()[0])
26022614

2603-
if self._shading == 'gouraud':
2604-
triangles, colors = self._convert_mesh_to_triangles(coordinates)
2605-
renderer.draw_gouraud_triangles(
2606-
gc, triangles, colors, transform.frozen())
2607-
else:
2608-
# If supported by the renderer, draw antialiased patches without strokes
2609-
# using the "plus" blend mode in an isolated blend group so that the
2610-
# fractional alphas at edges are added to make the intended total alpha.
2611-
# If the alphas were instead blended as if they were unrelated opacities,
2612-
# the resulting alpha would be smaller (i.e., more transparent), which would
2613-
# manifest as slightly transparent line artifacts along patch edges.
2614-
isolate = (renderer._supports_isolated_group_and_plus_blend_mode
2615-
and self._antialiased
2616-
and (self._edgecolors.size == 0 or self._edgecolors[0][3] == 0))
2617-
if isolate:
2618-
gc.set_blend_mode("plus")
2619-
renderer.open_blend_group(self.get_blend_mode())
2620-
2621-
renderer.draw_quad_mesh(
2622-
gc, transform.frozen(),
2623-
coordinates.shape[1] - 1, coordinates.shape[0] - 1,
2624-
coordinates, offsets, offset_trf,
2625-
# Backends expect flattened rgba arrays (n*m, 4) for fc and ec
2626-
self.get_facecolor().reshape((-1, 4)),
2627-
self._antialiased, self.get_edgecolors().reshape((-1, 4)))
2628-
2629-
if isolate:
2630-
renderer.close_blend_group()
2615+
with self._prep_for_contiguous_drawing(renderer, gc):
2616+
if self._shading == 'gouraud':
2617+
triangles, colors = self._convert_mesh_to_triangles(coordinates)
2618+
renderer.draw_gouraud_triangles(
2619+
gc, triangles, colors, transform.frozen())
2620+
else:
2621+
renderer.draw_quad_mesh(
2622+
gc, transform.frozen(),
2623+
coordinates.shape[1] - 1, coordinates.shape[0] - 1,
2624+
coordinates, offsets, offset_trf,
2625+
# Backends expect flattened rgba arrays (n*m, 4) for fc and ec
2626+
self.get_facecolor().reshape((-1, 4)),
2627+
self._antialiaseds, self.get_edgecolors().reshape((-1, 4)))
26312628
gc.restore()
26322629
renderer.close_group(self.__class__.__name__)
26332630
self.stale = False

‎lib/matplotlib/contour.py‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,19 +1285,23 @@ def draw(self, renderer):
12851285
super().draw(renderer)
12861286
return
12871287
# In presence of hatching, draw contours one at a time.
1288+
linewidths = self.get_linewidths()
1289+
linestyles = self.get_linestyles()
12881290
edgecolors = self.get_edgecolors()
12891291
if edgecolors.size == 0:
12901292
edgecolors = ("none",)
1291-
for idx in range(n_paths):
1292-
with self._cm_set(
1293-
paths=[paths[idx]],
1294-
hatch=self.hatches[idx % len(self.hatches)],
1295-
array=[self.get_array()[idx]],
1296-
linewidths=[self.get_linewidths()[idx % len(self.get_linewidths())]],
1297-
linestyles=[self.get_linestyles()[idx % len(self.get_linestyles())]],
1298-
edgecolors=edgecolors[idx % len(edgecolors)],
1299-
):
1300-
super().draw(renderer)
1293+
# Give self instead of gc to the context manager since gc is not passed on
1294+
with self._prep_for_contiguous_drawing(renderer, self):
1295+
for idx in range(n_paths):
1296+
with self._cm_set(
1297+
paths=[paths[idx]],
1298+
hatch=self.hatches[idx % len(self.hatches)],
1299+
array=[self.get_array()[idx]],
1300+
linewidths=[linewidths[idx % len(linewidths)]],
1301+
linestyles=[linestyles[idx % len(linestyles)]],
1302+
edgecolors=edgecolors[idx % len(edgecolors)],
1303+
):
1304+
super().draw(renderer)
13011305

13021306

13031307
@_docstring.interpd

0 commit comments

Comments
 (0)