Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cca039d

Browse filesBrowse files
authored
Merge pull request #24484 from leejjoon/draw-prevent-rasterization-by-default
Artist's draw method prevents rasterization by default
2 parents 4d52a3e + d8d2c68 commit cca039d
Copy full SHA for cca039d

File tree

Expand file treeCollapse file tree

5 files changed

+79
-12
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+79
-12
lines changed

‎doc/api/prev_api_changes/api_changes_3.3.0/deprecations.rst

Copy file name to clipboardExpand all lines: doc/api/prev_api_changes/api_changes_3.3.0/deprecations.rst
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ mathtext glues
273273
The *copy* parameter of ``mathtext.Glue`` is deprecated (the underlying glue
274274
spec is now immutable). ``mathtext.GlueSpec`` is deprecated.
275275

276-
Signatures of `.Artist.draw` and `.Axes.draw`
277-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278-
The *inframe* parameter to `.Axes.draw` is deprecated. Use
276+
Signatures of `.Artist.draw` and `matplotlib.axes.Axes.draw`
277+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278+
The *inframe* parameter to `matplotlib.axes.Axes.draw` is deprecated. Use
279279
`.Axes.redraw_in_frame` instead.
280280

281-
Not passing the *renderer* parameter to `.Axes.draw` is deprecated. Use
282-
``axes.draw_artist(axes)`` instead.
281+
Not passing the *renderer* parameter to `matplotlib.axes.Axes.draw` is
282+
deprecated. Use ``axes.draw_artist(axes)`` instead.
283283

284284
These changes make the signature of the ``draw`` (``artist.draw(renderer)``)
285285
method consistent across all artists; thus, additional parameters to

‎doc/api/prev_api_changes/api_changes_3.5.0/removals.rst

Copy file name to clipboardExpand all lines: doc/api/prev_api_changes/api_changes_3.5.0/removals.rst
+6-6Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ Arguments
260260

261261
- The *s* parameter to `.Axes.annotate` and `.pyplot.annotate` is no longer
262262
supported; use the new name *text*.
263-
- The *inframe* parameter to `.Axes.draw` has been removed; use
263+
- The *inframe* parameter to `matplotlib.axes.Axes.draw` has been removed; use
264264
`.Axes.redraw_in_frame` instead.
265265
- The *required*, *forbidden* and *allowed* parameters of
266266
`.cbook.normalize_kwargs` have been removed.
@@ -312,13 +312,13 @@ Arguments
312312
warning for keyword arguments that were overridden by the mappable is now
313313
removed.
314314

315-
- Omitting the *renderer* parameter to `.Axes.draw` is no longer supported; use
316-
``axes.draw_artist(axes)`` instead.
315+
- Omitting the *renderer* parameter to `matplotlib.axes.Axes.draw` is no longer
316+
supported; use ``axes.draw_artist(axes)`` instead.
317317
- Passing ``ismath="TeX!"`` to `.RendererAgg.get_text_width_height_descent` is
318318
no longer supported; pass ``ismath="TeX"`` instead,
319-
- Changes to the signature of the `.Axes.draw` method make it consistent with
320-
all other artists; thus additional parameters to `.Artist.draw` have also
321-
been removed.
319+
- Changes to the signature of the `matplotlib.axes.Axes.draw` method make it
320+
consistent with all other artists; thus additional parameters to
321+
`.Artist.draw` have also been removed.
322322

323323
rcParams
324324
~~~~~~~~

‎lib/matplotlib/artist.py

Copy file name to clipboardExpand all lines: lib/matplotlib/artist.py
+33-1Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,27 @@
2121
_log = logging.getLogger(__name__)
2222

2323

24+
def _prevent_rasterization(draw):
25+
# We assume that by default artists are not allowed to rasterize (unless
26+
# its draw method is explicitly decorated). If it is being drawn after a
27+
# rasterized artist and it has reached a raster_depth of 0, we stop
28+
# rasterization so that it does not affect the behavior of normal artist
29+
# (e.g., change in dpi).
30+
31+
@wraps(draw)
32+
def draw_wrapper(artist, renderer):
33+
if renderer._raster_depth == 0 and renderer._rasterizing:
34+
# Only stop when we are not in a rasterized parent
35+
# and something has been rasterized since last stop.
36+
renderer.stop_rasterizing()
37+
renderer._rasterizing = False
38+
39+
return draw(artist, renderer)
40+
41+
draw_wrapper._supports_rasterization = False
42+
return draw_wrapper
43+
44+
2445
def allow_rasterization(draw):
2546
"""
2647
Decorator for Artist.draw method. Provides routines
@@ -103,6 +124,15 @@ class Artist:
103124
zorder = 0
104125

105126
def __init_subclass__(cls):
127+
128+
# Decorate draw() method so that all artists are able to stop
129+
# rastrization when necessary. If the artist's draw method is already
130+
# decorated (has a `_supports_rasterization` attribute), it won't be
131+
# decorated.
132+
133+
if not hasattr(cls.draw, "_supports_rasterization"):
134+
cls.draw = _prevent_rasterization(cls.draw)
135+
106136
# Inject custom set() methods into the subclass with signature and
107137
# docstring based on the subclasses' properties.
108138

@@ -921,7 +951,9 @@ def set_rasterized(self, rasterized):
921951
----------
922952
rasterized : bool
923953
"""
924-
if rasterized and not hasattr(self.draw, "_supports_rasterization"):
954+
supports_rasterization = getattr(self.draw,
955+
"_supports_rasterization", False)
956+
if rasterized and not supports_rasterization:
925957
_api.warn_external(f"Rasterization of '{self}' will be ignored")
926958

927959
self._rasterized = rasterized

‎lib/matplotlib/tests/test_artist.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_artist.py
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,17 @@ def test_format_cursor_data_BoundaryNorm():
535535
assert img.format_cursor_data(v) == label
536536

537537
plt.close()
538+
539+
540+
def test_auto_no_rasterize():
541+
class Gen1(martist.Artist):
542+
...
543+
544+
assert 'draw' in Gen1.__dict__
545+
assert Gen1.__dict__['draw'] is Gen1.draw
546+
547+
class Gen2(Gen1):
548+
...
549+
550+
assert 'draw' not in Gen2.__dict__
551+
assert Gen2.draw is Gen1.draw

‎lib/matplotlib/tests/test_backend_svg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_svg.py
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,27 @@ def test_rasterized_ordering(fig_test, fig_ref):
122122
ax_test.plot(x+1, y, "-", c="b", lw=10, rasterized=False, zorder=1.2)
123123

124124

125+
@check_figures_equal(tol=5, extensions=['svg', 'pdf'])
126+
def test_prevent_rasterization(fig_test, fig_ref):
127+
loc = [0.05, 0.05]
128+
129+
ax_ref = fig_ref.subplots()
130+
131+
ax_ref.plot([loc[0]], [loc[1]], marker="x", c="black", zorder=2)
132+
133+
b = mpl.offsetbox.TextArea("X")
134+
abox = mpl.offsetbox.AnnotationBbox(b, loc, zorder=2.1)
135+
ax_ref.add_artist(abox)
136+
137+
ax_test = fig_test.subplots()
138+
ax_test.plot([loc[0]], [loc[1]], marker="x", c="black", zorder=2,
139+
rasterized=True)
140+
141+
b = mpl.offsetbox.TextArea("X")
142+
abox = mpl.offsetbox.AnnotationBbox(b, loc, zorder=2.1)
143+
ax_test.add_artist(abox)
144+
145+
125146
def test_count_bitmaps():
126147
def count_tag(fig, tag):
127148
with BytesIO() as fd:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.