Skip to content

Commit 744d7d3

Browse files
committed
Fix wrong figsize/spacing after print_figure for all backends
1 parent 0202a4d commit 744d7d3

1 file changed

Lines changed: 25 additions & 12 deletions

File tree

proplot/figure.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)