diff --git a/lib/matplotlib/backends/backend_mixed.py b/lib/matplotlib/backends/backend_mixed.py index 7bfc51bceb2e..575030a45b67 100644 --- a/lib/matplotlib/backends/backend_mixed.py +++ b/lib/matplotlib/backends/backend_mixed.py @@ -62,27 +62,16 @@ def __init__(self, figure, width, height, dpi, vector_renderer, self._bbox_inches_restore = bbox_inches_restore - self._set_current_renderer(vector_renderer) - - _methods = """ - close_group draw_image draw_markers draw_path - draw_path_collection draw_quad_mesh draw_tex draw_text - finalize flipy get_canvas_width_height get_image_magnification - get_texmanager get_text_width_height_descent new_gc open_group - option_image_nocomposite points_to_pixels strip_math - start_filter stop_filter draw_gouraud_triangle - draw_gouraud_triangles option_scale_image - _text2path _get_text_path_transform height width - """.split() - - def _set_current_renderer(self, renderer): - self._renderer = renderer - - for method in self._methods: - if hasattr(renderer, method): - setattr(self, method, getattr(renderer, method)) - renderer.start_rasterizing = self.start_rasterizing - renderer.stop_rasterizing = self.stop_rasterizing + self._renderer = vector_renderer + + def __getattr__(self, attr): + # Proxy everything that hasn't been overridden to the base + # renderer. Things that *are* overridden can call methods + # on self._renderer directly, but must not cache/store + # methods (because things like RendererAgg change their + # methods on the fly in order to optimise proxying down + # to the underlying C implementation). + return getattr(self._renderer, attr) def start_rasterizing(self): """ @@ -105,7 +94,7 @@ def start_rasterizing(self): if self._rasterizing == 0: self._raster_renderer = self._raster_renderer_class( self._width*self.dpi, self._height*self.dpi, self.dpi) - self._set_current_renderer(self._raster_renderer) + self._renderer = self._raster_renderer self._rasterizing += 1 def stop_rasterizing(self): @@ -119,7 +108,7 @@ def stop_rasterizing(self): """ self._rasterizing -= 1 if self._rasterizing == 0: - self._set_current_renderer(self._vector_renderer) + self._renderer = self._vector_renderer height = self._height * self.dpi buffer, bounds = self._raster_renderer.tostring_rgba_minimized() diff --git a/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.pdf b/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.pdf new file mode 100644 index 000000000000..46275f180bc4 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.png b/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.png new file mode 100644 index 000000000000..dce047707da8 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_agg_filter/agg_filter_alpha.png differ diff --git a/lib/matplotlib/tests/test_agg_filter.py b/lib/matplotlib/tests/test_agg_filter.py new file mode 100644 index 000000000000..913034636603 --- /dev/null +++ b/lib/matplotlib/tests/test_agg_filter.py @@ -0,0 +1,30 @@ +import numpy as np + +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison + + +@image_comparison(baseline_images=['agg_filter_alpha'], + extensions=['png', 'pdf']) +def test_agg_filter_alpha(): + ax = plt.axes() + x, y = np.mgrid[0:7, 0:8] + data = x**2 - y**2 + mesh = ax.pcolormesh(data, cmap='Reds', zorder=5) + + def manual_alpha(im, dpi): + im[:, :, 3] *= 0.6 + print('CALLED') + return im, 0, 0 + + # Note: Doing alpha like this is not the same as setting alpha on + # the mesh itself. Currently meshes are drawn as independent patches, + # and we see fine borders around the blocks of color. See the SO + # question for an example: https://stackoverflow.com/questions/20678817 + mesh.set_agg_filter(manual_alpha) + + # Currently we must enable rasterization for this to have an effect in + # the PDF backend. + mesh.set_rasterized(True) + + ax.plot([0, 4, 7], [1, 3, 8])
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: