Skip to content

Commit 7bd97de

Browse files
pelsontacaswell
authored andcommitted
Undesirable behaviour of MixedModeRenderer (#13021)
* FIX: Correctly proxy the renderers in MixedModeRenderer. Squash-merged to flatted out additional test images
1 parent 71338e3 commit 7bd97de

File tree

4 files changed

+41
-23
lines changed

4 files changed

+41
-23
lines changed

lib/matplotlib/backends/backend_mixed.py

+12-23
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,16 @@ def __init__(self, figure, width, height, dpi, vector_renderer,
6262

6363
self._bbox_inches_restore = bbox_inches_restore
6464

65-
self._set_current_renderer(vector_renderer)
66-
67-
_methods = """
68-
close_group draw_image draw_markers draw_path
69-
draw_path_collection draw_quad_mesh draw_tex draw_text
70-
finalize flipy get_canvas_width_height get_image_magnification
71-
get_texmanager get_text_width_height_descent new_gc open_group
72-
option_image_nocomposite points_to_pixels strip_math
73-
start_filter stop_filter draw_gouraud_triangle
74-
draw_gouraud_triangles option_scale_image
75-
_text2path _get_text_path_transform height width
76-
""".split()
77-
78-
def _set_current_renderer(self, renderer):
79-
self._renderer = renderer
80-
81-
for method in self._methods:
82-
if hasattr(renderer, method):
83-
setattr(self, method, getattr(renderer, method))
84-
renderer.start_rasterizing = self.start_rasterizing
85-
renderer.stop_rasterizing = self.stop_rasterizing
65+
self._renderer = vector_renderer
66+
67+
def __getattr__(self, attr):
68+
# Proxy everything that hasn't been overridden to the base
69+
# renderer. Things that *are* overridden can call methods
70+
# on self._renderer directly, but must not cache/store
71+
# methods (because things like RendererAgg change their
72+
# methods on the fly in order to optimise proxying down
73+
# to the underlying C implementation).
74+
return getattr(self._renderer, attr)
8675

8776
def start_rasterizing(self):
8877
"""
@@ -105,7 +94,7 @@ def start_rasterizing(self):
10594
if self._rasterizing == 0:
10695
self._raster_renderer = self._raster_renderer_class(
10796
self._width*self.dpi, self._height*self.dpi, self.dpi)
108-
self._set_current_renderer(self._raster_renderer)
97+
self._renderer = self._raster_renderer
10998
self._rasterizing += 1
11099

111100
def stop_rasterizing(self):
@@ -119,7 +108,7 @@ def stop_rasterizing(self):
119108
"""
120109
self._rasterizing -= 1
121110
if self._rasterizing == 0:
122-
self._set_current_renderer(self._vector_renderer)
111+
self._renderer = self._vector_renderer
123112

124113
height = self._height * self.dpi
125114
buffer, bounds = self._raster_renderer.tostring_rgba_minimized()
Binary file not shown.
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import numpy as np
2+
3+
import matplotlib.pyplot as plt
4+
from matplotlib.testing.decorators import image_comparison
5+
6+
7+
@image_comparison(baseline_images=['agg_filter_alpha'])
8+
def test_agg_filter_alpha():
9+
ax = plt.axes()
10+
x, y = np.mgrid[0:7, 0:8]
11+
data = x**2 - y**2
12+
mesh = ax.pcolormesh(data, cmap='Reds', zorder=5)
13+
14+
def manual_alpha(im, dpi):
15+
im[:, :, 3] *= 0.6
16+
print('CALLED')
17+
return im, 0, 0
18+
19+
# Note: Doing alpha like this is not the same as setting alpha on
20+
# the mesh itself. Currently meshes are drawn as independent patches,
21+
# and we see fine borders around the blocks of color. See the SO
22+
# question for an example: https://stackoverflow.com/questions/20678817
23+
mesh.set_agg_filter(manual_alpha)
24+
25+
# Currently we must enable rasterization for this to have an effect in
26+
# the PDF backend.
27+
mesh.set_rasterized(True)
28+
29+
ax.plot([0, 4, 7], [1, 3, 8])

0 commit comments

Comments
 (0)