Skip to content

Commit 5c9ac9e

Browse files
committed
Don't lose unit change handlers when pickling/unpickling.
Make the `units finalize` event handlers picklable, and request that they be restored upon unpickling. I have yet to see a case where the unit change handlers actually have an observable effect, but at least this seems theoretically more correct...
1 parent cf4f8e1 commit 5c9ac9e

File tree

3 files changed

+24
-32
lines changed

3 files changed

+24
-32
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from collections import OrderedDict
22
from contextlib import ExitStack
3+
import functools
34
import inspect
45
import itertools
56
import logging
@@ -562,13 +563,10 @@ def __init__(self, fig, rect,
562563

563564
self.update(kwargs)
564565

565-
if self.xaxis is not None:
566-
self._xcid = self.xaxis.callbacks.connect(
567-
'units finalize', lambda: self._on_units_changed(scalex=True))
568-
569-
if self.yaxis is not None:
570-
self._ycid = self.yaxis.callbacks.connect(
571-
'units finalize', lambda: self._on_units_changed(scaley=True))
566+
for name, axis in self._get_axis_map().items():
567+
axis.callbacks._pickled_cids.add(
568+
axis.callbacks.connect(
569+
'units finalize', self._unit_change_handler(name)))
572570

573571
rcParams = mpl.rcParams
574572
self.tick_params(
@@ -2150,14 +2148,16 @@ def add_container(self, container):
21502148
container._remove_method = self.containers.remove
21512149
return container
21522150

2153-
def _on_units_changed(self, scalex=False, scaley=False):
2151+
def _unit_change_handler(self, axis_name, event=None):
21542152
"""
2155-
Callback for processing changes to axis units.
2156-
2157-
Currently requests updates of data limits and view limits.
2153+
Process axis units changes: requests updates to data and view limits.
21582154
"""
2155+
if event is None: # Allow connecting `self._unit_change_handler(name)`
2156+
return functools.partial(self._unit_change_handler, axis_name)
2157+
_api.check_in_list(self._get_axis_map(), axis_name=axis_name)
21592158
self.relim()
2160-
self._request_autoscale_view(scalex=scalex, scaley=scaley)
2159+
self._request_autoscale_view(scalex=(axis_name == "x"),
2160+
scaley=(axis_name == "y"))
21612161

21622162
def relim(self, visible_only=False):
21632163
"""

lib/matplotlib/lines.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -627,13 +627,9 @@ def axes(self, ax):
627627
# call the set method from the base-class property
628628
Artist.axes.fset(self, ax)
629629
if ax is not None:
630-
# connect unit-related callbacks
631-
if ax.xaxis is not None:
632-
self._xcid = ax.xaxis.callbacks.connect('units',
633-
self.recache_always)
634-
if ax.yaxis is not None:
635-
self._ycid = ax.yaxis.callbacks.connect('units',
636-
self.recache_always)
630+
for axis in ax._get_axis_map().values():
631+
axis.callbacks._pickled_cids.add(
632+
axis.callbacks.connect('units', self.recache_always))
637633

638634
def set_data(self, *args):
639635
"""

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"""
1212

1313
from collections import defaultdict
14+
import functools
1415
from functools import reduce
1516
from itertools import compress
1617
import math
@@ -111,12 +112,6 @@ def __init__(
111112
# func used to format z -- fall back on major formatters
112113
self.fmt_zdata = None
113114

114-
if self.zaxis is not None:
115-
self._zcid = self.zaxis.callbacks.connect(
116-
'units finalize', lambda: self._on_units_changed(scalez=True))
117-
else:
118-
self._zcid = None
119-
120115
self.mouse_init()
121116
self.figure.canvas.callbacks._pickled_cids.update({
122117
self.figure.canvas.mpl_connect(
@@ -475,14 +470,15 @@ def get_axis_position(self):
475470
zhigh = tc[0][2] > tc[2][2]
476471
return xhigh, yhigh, zhigh
477472

478-
def _on_units_changed(self, scalex=False, scaley=False, scalez=False):
479-
"""
480-
Callback for processing changes to axis units.
481-
482-
Currently forces updates of data limits and view limits.
483-
"""
473+
def _unit_change_handler(self, axis_name, event=None):
474+
# docstring inherited
475+
if event is None: # Allow connecting `self._unit_change_handler(name)`
476+
return functools.partial(self._unit_change_handler, axis_name)
477+
_api.check_in_list(self._get_axis_map(), axis_name=axis_name)
484478
self.relim()
485-
self.autoscale_view(scalex=scalex, scaley=scaley, scalez=scalez)
479+
self.autoscale_view(scalex=(axis_name == "x"),
480+
scaley=(axis_name == "y"),
481+
scalez=(axis_name == "z"))
486482

487483
def update_datalim(self, xys, **kwargs):
488484
pass

0 commit comments

Comments
 (0)