@@ -61,7 +61,7 @@ def _canvas_preprocessor(canvas, method):
6161 # queries the bbox directly rather than using get_width_height() so requires
6262 # workaround), (2) override bbox and bbox_inches as *properties* (but these
6363 # are really complicated, dangerous, and result in unnecessary extra draws),
64- # or (3) simply override canvas draw methods. Our choice is (3) .
64+ # or (3) simply override canvas draw methods. Our choice is #3 .
6565 def _preprocess (self , * args , ** kwargs ):
6666 fig = self .figure # update even if not stale! needed after saves
6767 func = getattr (type (self ), method ) # the original method
@@ -90,7 +90,18 @@ def _preprocess(self, *args, **kwargs):
9090 return
9191
9292 # Apply formatting
93- with fig ._context_preprocessing ():
93+ # NOTE: *Critical* to not add print_figure renderer to the cache when the
94+ # print method (print_pdf, print_png, etc.) calls Figure.draw(). Otherwise
95+ # have issues where (1) figure size and/or figure bounds are incorrect after
96+ # saving figure *then* displaying it in qt or inline notebook backends, and
97+ # (2) figure fails to update correctly after successively modifying
98+ # and displaying within inline notebook backend (previously worked around
99+ # this by forcing additional draw() call in this function before proceeding
100+ # with print_figure). Solution is to use _state_context with _cachedRenderer.
101+ fallback = _not_none (fig ._fallback_to_cm , rc ['mathtext.fallback_to_cm' ])
102+ rc_context = rc .context ({'mathtext.fallback_to_cm' : fallback })
103+ fig_context = fig ._context_preprocessing (cache = (method != 'print_figure' ))
104+ with rc_context , fig_context :
94105 # Add legends and colorbars
95106 for ax in fig ._iter_axes (hidden = False , children = True ):
96107 if isinstance (ax , paxes .Axes ):
@@ -108,9 +119,7 @@ def _preprocess(self, *args, **kwargs):
108119 fig ._align_subplot_super_labels (renderer )
109120
110121 # Call main function
111- fallback = _not_none (fig ._fallback_to_cm , rc ['mathtext.fallback_to_cm' ])
112- with rc .context ({'mathtext.fallback_to_cm' : fallback }):
113- result = func (self , * args , ** kwargs )
122+ result = func (self , * args , ** kwargs )
114123 return result
115124
116125 return _preprocess .__get__ (canvas ) # ...I don't get it either
@@ -626,12 +635,16 @@ def _context_autoresizing(self):
626635 """
627636 return _state_context (self , _is_autoresizing = True )
628637
629- def _context_preprocessing (self ):
638+ def _context_preprocessing (self , cache = True ):
630639 """
631640 Prevent re-running pre-processing steps due to draws triggered
632- by figure resizes during pre-processing.
641+ by figure resizes during pre-processing. `cache` controls whether the
642+ renderer passed to draw should be cached.
633643 """
634- return _state_context (self , _is_preprocessing = True )
644+ kwargs = {}
645+ if not cache :
646+ kwargs ['_cachedRenderer' ] = None # __exit__ will restore previous value
647+ return _state_context (self , _is_preprocessing = True , ** kwargs )
635648
636649 def _fix_figure_dimensions (self , subplots_kw ):
637650 """
@@ -706,10 +719,10 @@ def _get_align_axes(self, side):
706719
707720 def _get_renderer (self ):
708721 """
709- Get a renderer at all costs, even if it means generating a brand
710- new one! Used for updating the figure bounding box when it is accessed
711- and calculating centered-row legend bounding boxes. This is copied from
712- tight_layout.py in matplotlib.
722+ Get a renderer at all costs, even if it means generating a brand new one!
723+ Used for updating the figure bounding box when it is accessed and calculating
724+ centered-row legend bounding boxes. This is copied from tight_layout.py in
725+ matplotlib.
713726 """
714727 if self ._cachedRenderer :
715728 renderer = self ._cachedRenderer
0 commit comments