8000 Restore axes sharedness when unpickling. · matplotlib/matplotlib@859a412 · GitHub
[go: up one dir, main page]

Skip to content

Commit 859a412

Browse files
committed
Restore axes sharedness when unpickling.
Previously, pickling and unpickling shared axes would result in axes sharing a ticker instance (because that's how shared axes are set up), but without changes of one's xlims propagated to the other. The reason is that that sharedness information is stored in AxesBase._shared_x_axes, which does *not* get pickled together with the Axes instance: the latter only has a textual reference "I am an instance of AxesBase", so the Grouper information is lost. To keep the Grouper information valid, additionally pickle the current group of shared axes together with the Axes, and restore that information upon unpickling.
1 parent ead2ff8 commit 859a412

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -542,17 +542,25 @@ def __getstate__(self):
542542
# The renderer should be re-created by the figure, and then cached at
543543
# that point.
544544
state = super().__getstate__()
545-
state['_cachedRenderer'] = None
546-
state.pop('_layoutbox')
547-
state.pop('_poslayoutbox')
548-
545+
for key in ['_cachedRenderer', '_layoutbox', '_poslayoutbox']:
546+
state[key] = None
547+
# Prune the sharing & twinning info to only contain the current group.
548+
for grouper_name in [
549+
'_shared_x_axes', '_shared_y_axes', '_twinned_axes']:
550+
grouper = getattr(self, grouper_name)
551+
state[grouper_name] = (grouper.get_siblings(self)
552+
if self in grouper else None)
549553
return state
550554

551555
def __setstate__(self, state):
556+
# Merge the grouping info back into the global groupers.
557+
for grouper_name in [
558+
'_shared_x_axes', '_shared_y_axes', '_twinned_axes']:
559+
siblings = state.pop(grouper_name)
560+
if siblings:
561+
getattr(self, grouper_name).join(*siblings)
552562
self.__dict__ = state
553563
self._stale = True
554-
self._layoutbox = None
555-
self._poslayoutbox = None
556564

557565
def get_window_extent(self, *args, **kwargs):
558566
"""

lib/matplotlib/tests/test_pickle.py

Lines changed: 781C 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,10 @@ def test_rrulewrapper():
185185
except RecursionError:
186186
print('rrulewrapper pickling test failed')
187187
raise
188+
189+
190+
def test_shared():
191+
fig, axs = plt.subplots(2, sharex=True)
192+
fig = pickle.loads(pickle.dumps(fig))
193+
fig.axes[0].set_xlim(10, 20)
194+
assert fig.axes[1].get_xlim() == (10, 20)

0 commit comments

Comments
 (0)
0