4141
4242import base64
4343from collections .abc import Sequence , Mapping
44+ from abc import ABC , abstractmethod
4445import functools
4546import importlib
4647import inspect
@@ -2257,7 +2258,87 @@ def _init(self):
22572258 self ._isinit = True
22582259
22592260
2260- class Normalize :
2261+ class Norm (ABC ):
2262+ """
2263+ Abstract base class for normalizations.
2264+
2265+ Subclasses include `Normalize` which maps from a scalar to
2266+ a scalar. However, this class makes no such requirement, and subclasses may
2267+ support the normalization of multiple variates simultaneously, with
2268+ separate normalization for each variate.
2269+ """
2270+
2271+ def __init__ (self ):
2272+ self .callbacks = cbook .CallbackRegistry (signals = ["changed" ])
2273+
2274+ @property
2275+ @abstractmethod
2276+ def vmin (self ):
2277+ """Lower limit of the input data interval; maps to 0."""
2278+ pass
2279+
2280+ @property
2281+ @abstractmethod
2282+ def vmax (self ):
2283+ """Upper limit of the input data interval; maps to 1."""
2284+ pass
2285+
2286+ @property
2287+ @abstractmethod
2288+ def clip (self ):
2289+ """
2290+ Determines the behavior for mapping values outside the range ``[vmin, vmax]``.
2291+
2292+ See the *clip* parameter in `.Normalize`.
2293+ """
2294+ pass
2295+
2296+ @abstractmethod
2297+ def __call__ (self , value , clip = None ):
2298+ """
2299+ Normalize the data and return the normalized data.
2300+
2301+ Parameters
2302+ ----------
2303+ value
2304+ Data to normalize.
2305+ clip : bool, optional
2306+ See the description of the parameter *clip* in `.Normalize`.
2307+
2308+ If ``None``, defaults to ``self.clip`` (which defaults to
2309+ ``False``).
2310+
2311+ Notes
2312+ -----
2313+ If not already initialized, ``self.vmin`` and ``self.vmax`` are
2314+ initialized using ``self.autoscale_None(value)``.
2315+ """
2316+ pass
2317+
2318+ @abstractmethod
2319+ def autoscale (self , A ):
2320+ """Set *vmin*, *vmax* to min, max of *A*."""
2321+ pass
2322+
2323+ @abstractmethod
2324+ def autoscale_None (self , A ):
2325+ """If *vmin* or *vmax* are not set, use the min/max of *A* to set them."""
2326+ pass
2327+
2328+ @abstractmethod
2329+ def scaled (self ):
2330+ """Return whether *vmin* and *vmax* are both set."""
2331+ pass
2332+
2333+ def _changed (self ):
2334+ """
2335+ Call this whenever the norm is changed to notify all the
2336+ callback listeners to the 'changed' signal.
2337+ """
2338+ self .callbacks .process ('changed' )
2339+
2340+
2341+ class Normalize (Norm ):
22612342 """
22622343 A class which, when called, maps values within the interval
22632344 ``[vmin, vmax]`` linearly to the interval ``[0.0, 1.0]``. The mapping of
@@ -2307,15 +2388,15 @@ def __init__(self, vmin=None, vmax=None, clip=False):
23072388 -----
23082389 If ``vmin == vmax``, input data will be mapped to 0.
23092390 """
2391+ super ().__init__ ()
23102392 self ._vmin = _sanitize_extrema (vmin )
23112393 self ._vmax = _sanitize_extrema (vmax )
23122394 self ._clip = clip
23132395 self ._scale = None
2314- self .callbacks = cbook .CallbackRegistry (signals = ["changed" ])
23152396
23162397 @property
23172398 def vmin (self ):
2318- """Lower limit of the input data interval; maps to 0."""
2399+ # docstring inherited
23192400 return self ._vmin
23202401
23212402 @vmin .setter
@@ -2327,7 +2408,7 @@ def vmin(self, value):
23272408
23282409 @property
23292410 def vmax (self ):
2330- """Upper limit of the input data interval; maps to 1."""
2411+ # docstring inherited
23312412 return self ._vmax
23322413
23332414 @vmax .setter
@@ -2339,11 +2420,7 @@ def vmax(self, value):
23392420
23402421 @property
23412422 def clip (self ):
2342- """
2343- Determines the behavior for mapping values outside the range ``[vmin, vmax]``.
2344-
2345- See the *clip* parameter in `.Normalize`.
2346- """
2423+ # docstring inherited
23472424 return self ._clip
23482425
23492426 @clip .setter
@@ -2352,13 +2429,6 @@ def clip(self, value):
23522429 self ._clip = value
23532430 self ._changed ()
23542431
2355- def _changed (self ):
2356- """
2357- Call this whenever the norm is changed to notify all the
2358- callback listeners to the 'changed' signal.
2359- """
2360- self .callbacks .process ('changed' )
2361-
23622432 @staticmethod
23632433 def process_value (value ):
23642434 """
@@ -2400,24 +2470,7 @@ def process_value(value):
24002470 return result , is_scalar
24012471
24022472 def __call__ (self , value , clip = None ):
2403- """
2404- Normalize the data and return the normalized data.
2405-
2406- Parameters
2407- ----------
2408- value
2409- Data to normalize.
2410- clip : bool, optional
2411- See the description of the parameter *clip* in `.Normalize`.
2412-
2413- If ``None``, defaults to ``self.clip`` (which defaults to
2414- ``False``).
2415-
2416- Notes
2417- -----
2418- If not already initialized, ``self.vmin`` and ``self.vmax`` are
2419- initialized using ``self.autoscale_None(value)``.
2420- """
2473+ # docstring inherited
24212474 if clip is None :
24222475 clip = self .clip
24232476
@@ -2468,7 +2521,7 @@ def inverse(self, value):
24682521 return vmin + value * (vmax - vmin )
24692522
24702523 def autoscale (self , A ):
2471- """Set *vmin*, *vmax* to min, max of *A*."""
2524+ # docstring inherited
24722525 with self .callbacks .blocked ():
24732526 # Pause callbacks while we are updating so we only get
24742527 # a single update signal at the end
@@ -2477,7 +2530,7 @@ def autoscale(self, A):
24772530 self ._changed ()
24782531
24792532 def autoscale_None (self , A ):
2480- """If *vmin* or *vmax* are not set, use the min/max of *A* to set them."""
2533+ # docstring inherited
24812534 A = np .asanyarray (A )
24822535
24832536 if isinstance (A , np .ma .MaskedArray ):
@@ -2491,7 +2544,7 @@ def autoscale_None(self, A):
24912544 self .vmax = A .max ()
24922545
24932546 def scaled (self ):
2494- """Return whether *vmin* and *vmax* are both set."""
2547+ # docstring inherited
24952548 return self .vmin is not None and self .vmax is not None
24962549
24972550
@@ -2775,7 +2828,7 @@ def _make_norm_from_scale(
27752828 unlike to arbitrary lambdas.
27762829 """
27772830
2778- class Norm (base_norm_cls ):
2831+ class ScaleNorm (base_norm_cls ):
27792832 def __reduce__ (self ):
27802833 cls = type (self )
27812834 # If the class is toplevel-accessible, it is possible to directly
@@ -2855,15 +2908,15 @@ def autoscale_None(self, A):
28552908 return super ().autoscale_None (in_trf_domain )
28562909
28572910 if base_norm_cls is Normalize :
2858- Norm .__name__ = f"{ scale_cls .__name__ } Norm"
2859- Norm .__qualname__ = f"{ scale_cls .__qualname__ } Norm"
2911+ ScaleNorm .__name__ = f"{ scale_cls .__name__ } Norm"
2912+ ScaleNorm .__qualname__ = f"{ scale_cls .__qualname__ } Norm"
28602913 else :
2861- Norm .__name__ = base_norm_cls .__name__
2862- Norm .__qualname__ = base_norm_cls .__qualname__
2863- Norm .__module__ = base_norm_cls .__module__
2864- Norm .__doc__ = base_norm_cls .__doc__
2914+ ScaleNorm .__name__ = base_norm_cls .__name__
2915+ ScaleNorm .__qualname__ = base_norm_cls .__qualname__
2916+ ScaleNorm .__module__ = base_norm_cls .__module__
2917+ ScaleNorm .__doc__ = base_norm_cls .__doc__
28652918
2866- return Norm
2919+ return ScaleNorm
28672920
28682921
28692922def _create_empty_object_of_class (cls ):
0 commit comments