@@ -600,6 +600,10 @@ class Axis(martist.Artist):
600600 # The class used in _get_tick() to create tick instances. Must either be
601601 # overwritten in subclasses, or subclasses must reimplement _get_tick().
602602 _tick_class = None
603+ converter = _api .deprecate_privatize_attribute (
604+ "3.10" ,
605+ alternative = "get_converter and set_converter methods"
606+ )
603607
604608 def __str__ (self ):
605609 return "{}({},{})" .format (
@@ -656,7 +660,8 @@ def __init__(self, axes, *, pickradius=15, clear=True):
656660 if clear :
657661 self .clear ()
658662 else :
659- self .converter = None
663+ self ._converter = None
664+ self ._converter_is_explicit = False
660665 self .units = None
661666
662667 self ._autoscale_on = True
@@ -886,7 +891,8 @@ def clear(self):
886891 mpl .rcParams ['axes.grid.which' ] in ('both' , 'minor' ))
887892 self .reset_ticks ()
888893
889- self .converter = None
894+ self ._converter = None
895+ self ._converter_is_explicit = False
890896 self .units = None
891897 self .stale = True
892898
@@ -1738,16 +1744,20 @@ def grid(self, visible=None, which='major', **kwargs):
17381744 def update_units (self , data ):
17391745 """
17401746 Introspect *data* for units converter and update the
1741- ``axis.converter `` instance if necessary. Return *True*
1747+ ``axis.get_converter `` instance if necessary. Return *True*
17421748 if *data* is registered for unit conversion.
17431749 """
1744- converter = munits .registry .get_converter (data )
1750+ if not self ._converter_is_explicit :
1751+ converter = munits .registry .get_converter (data )
1752+ else :
1753+ converter = self ._converter
1754+
17451755 if converter is None :
17461756 return False
17471757
1748- neednew = self .converter != converter
1749- self .converter = converter
1750- default = self .converter .default_units (data , self )
1758+ neednew = self ._converter != converter
1759+ self ._set_converter ( converter )
1760+ default = self ._converter .default_units (data , self )
17511761 if default is not None and self .units is None :
17521762 self .set_units (default )
17531763
@@ -1761,10 +1771,10 @@ def _update_axisinfo(self):
17611771 Check the axis converter for the stored units to see if the
17621772 axis info needs to be updated.
17631773 """
1764- if self .converter is None :
1774+ if self ._converter is None :
17651775 return
17661776
1767- info = self .converter .axisinfo (self .units , self )
1777+ info = self ._converter .axisinfo (self .units , self )
17681778
17691779 if info is None :
17701780 return
@@ -1791,25 +1801,58 @@ def _update_axisinfo(self):
17911801 self .set_default_intervals ()
17921802
17931803 def have_units (self ):
1794- return self .converter is not None or self .units is not None
1804+ return self ._converter is not None or self .units is not None
17951805
17961806 def convert_units (self , x ):
17971807 # If x is natively supported by Matplotlib, doesn't need converting
17981808 if munits ._is_natively_supported (x ):
17991809 return x
18001810
1801- if self .converter is None :
1802- self .converter = munits .registry .get_converter (x )
1811+ if self ._converter is None :
1812+ self ._set_converter ( munits .registry .get_converter (x ) )
18031813
1804- if self .converter is None :
1814+ if self ._converter is None :
18051815 return x
18061816 try :
1807- ret = self .converter .convert (x , self .units , self )
1817+ ret = self ._converter .convert (x , self .units , self )
18081818 except Exception as e :
18091819 raise munits .ConversionError ('Failed to convert value(s) to axis '
18101820 f'units: { x !r} ' ) from e
18111821 return ret
18121822
1823+ def get_converter (self ):
1824+ """
1825+ Get the unit converter for axis.
1826+
1827+ Returns
1828+ -------
1829+ `~matplotlib.units.ConversionInterface` or None
1830+ """
1831+ return self ._converter
1832+
1833+ def set_converter (self , converter ):
1834+ """
1835+ Set the unit converter for axis.
1836+
1837+ Parameters
1838+ ----------
1839+ converter : `~matplotlib.units.ConversionInterface`
1840+ """
1841+ self ._set_converter (converter )
1842+ self ._converter_is_explicit = True
1843+
1844+ def _set_converter (self , converter ):
1845+ if self ._converter == converter :
1846+ return
1847+ if self ._converter_is_explicit :
1848+ raise RuntimeError ("Axis already has an explicit converter set" )
1849+ elif self ._converter is not None :
1850+ _api .warn_external (
1851+ "This axis already has a converter set and "
1852+ "is updating to a potentially incompatible converter"
1853+ )
1854+ self ._converter = converter
1855+
18131856 def set_units (self , u ):
18141857 """
18151858 Set the units for axis.
@@ -2529,8 +2572,8 @@ def set_default_intervals(self):
25292572 # not changed the view:
25302573 if (not self .axes .dataLim .mutatedx () and
25312574 not self .axes .viewLim .mutatedx ()):
2532- if self .converter is not None :
2533- info = self .converter .axisinfo (self .units , self )
2575+ if self ._converter is not None :
2576+ info = self ._converter .axisinfo (self .units , self )
25342577 if info .default_limits is not None :
25352578 xmin , xmax = self .convert_units (info .default_limits )
25362579 self .axes .viewLim .intervalx = xmin , xmax
@@ -2759,8 +2802,8 @@ def set_default_intervals(self):
27592802 # not changed the view:
27602803 if (not self .axes .dataLim .mutatedy () and
27612804 not self .axes .viewLim .mutatedy ()):
2762- if self .converter is not None :
2763- info = self .converter .axisinfo (self .units , self )
2805+ if self ._converter is not None :
2806+ info = self ._converter .axisinfo (self .units , self )
27642807 if info .default_limits is not None :
27652808 ymin , ymax = self .convert_units (info .default_limits )
27662809 self .axes .viewLim .intervaly = ymin , ymax
0 commit comments