25
25
The base class for the Toolbar class of each interactive backend.
26
26
"""
27
27
28
- from contextlib import contextmanager
28
+ from contextlib import contextmanager , suppress
29
29
from enum import Enum , IntEnum
30
30
import functools
31
31
import importlib
46
46
from matplotlib .backend_managers import ToolManager
47
47
from matplotlib .transforms import Affine2D
48
48
from matplotlib .path import Path
49
+ from matplotlib .cbook import _setattr_cm
49
50
50
51
51
52
_log = logging .getLogger (__name__ )
@@ -708,6 +709,23 @@ def stop_filter(self, filter_func):
708
709
Currently only supported by the agg renderer.
709
710
"""
710
711
712
+ def _draw_disabled (self ):
713
+ """
714
+ Context manager to temporary disable drawing.
715
+
716
+ This is used for getting the drawn size of Artists. This lets us
717
+ run the draw process to update any Python state but does not pay the
718
+ cost of the draw_XYZ calls on the canvas.
<
10000
/td>
719
+ """
720
+ no_ops = {
721
+ meth_name : lambda * args , ** kwargs : None
722
+ for meth_name in dir (RendererBase )
723
+ if (meth_name .startswith ("draw_" )
724
+ or meth_name in ["open_group" , "close_group" ])
725
+ }
726
+
727
+ return _setattr_cm (self , ** no_ops )
728
+
711
729
712
730
class GraphicsContextBase :
713
731
"""An abstract base class that provides color, line styles, etc."""
@@ -1506,15 +1524,14 @@ def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
1506
1524
LocationEvent .__init__ (self , name , canvas , x , y , guiEvent = guiEvent )
1507
1525
1508
1526
1509
- def _get_renderer (figure , print_method = None , * , draw_disabled = False ):
1527
+ def _get_renderer (figure , print_method = None ):
1510
1528
"""
1511
1529
Get the renderer that would be used to save a `~.Figure`, and cache it on
1512
1530
the figure.
1513
1531
1514
- If *draw_disabled* is True, additionally replace drawing methods on
1515
- *renderer* by no-ops. This is used by the tight-bbox-saving renderer,
1516
- which needs to walk through the artist tree to compute the tight-bbox, but
1517
- for which the output file may be closed early.
1532
+ If you need a renderer without any active draw methods use
1533
+ renderer._draw_disabled to temporary patch them out at your call site.
1534
+
1518
1535
"""
1519
1536
# This is implemented by triggering a draw, then immediately jumping out of
1520
1537
# Figure.draw() by raising an exception.
@@ -1533,12 +1550,6 @@ def _draw(renderer): raise Done(renderer)
1533
1550
except Done as exc :
1534
1551
renderer , = figure ._cachedRenderer , = exc .args
1535
1552
1536
- if draw_disabled :
1537
- for meth_name in dir (RendererBase ):
1538
- if (meth_name .startswith ("draw_" )
1539
- or meth_name in ["open_group" , "close_group" ]):
1540
- setattr (renderer , meth_name , lambda * args , ** kwargs : None )
1541
-
1542
1553
return renderer
1543
1554
1544
1555
@@ -2097,9 +2108,14 @@ def print_figure(
2097
2108
renderer = _get_renderer (
2098
2109
self .figure ,
2099
2110
functools .partial (
2100
- print_method , orientation = orientation ),
2101
- draw_disabled = True )
2102
- self .figure .draw (renderer )
2111
+ print_method , orientation = orientation )
2112
+ )
2113
+ ctx = (renderer ._draw_disabled ()
2114
+ if hasattr (renderer , '_draw_disabled' )
2115
+ else suppress ())
2116
+ with ctx :
2117
+ self .figure .draw (renderer )
2118
+
2103
2119
bbox_inches = self .figure .get_tightbbox (
2104
2120
renderer , bbox_extra_artists = bbox_extra_artists )
2105
2121
if pad_inches is None :
0 commit comments