41
41
42
42
import base64
43
43
from collections .abc import Sequence , Mapping
44
+ from abc import ABC , abstractmethod
44
45
import functools
45
46
import importlib
46
47
import inspect
@@ -2257,7 +2258,87 @@ def _init(self):
2257
2258
self ._isinit = True
2258
2259
2259
2260
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 ):
2261
2342
"""
2262
2343
A class which, when called, maps values within the interval
2263
2344
``[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):
2307
2388
-----
2308
2389
If ``vmin == vmax``, input data will be mapped to 0.
2309
2390
"""
2391
+ super ().__init__ ()
2310
2392
self ._vmin = _sanitize_extrema (vmin )
2311
2393
self ._vmax = _sanitize_extrema (vmax )
2312
2394
self ._clip = clip
2313
2395
self ._scale = None
2314
- self .callbacks = cbook .CallbackRegistry (signals = ["changed" ])
2315
2396
2316
2397
@property
2317
2398
def vmin (self ):
2318
- """Lower limit of the input data interval; maps to 0."""
2399
+ # docstring inherited
2319
2400
return self ._vmin
2320
2401
2321
2402
@vmin .setter
@@ -2327,7 +2408,7 @@ def vmin(self, value):
2327
2408
2328
2409
@property
2329
2410
def vmax (self ):
2330
- """Upper limit of the input data interval; maps to 1."""
2411
+ # docstring inherited
2331
2412
return self ._vmax
2332
2413
2333
2414
@vmax .setter
@@ -2339,11 +2420,7 @@ def vmax(self, value):
2339
2420
2340
2421
@property
2341
2422
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
2347
2424
return self ._clip
2348
2425
2349
2426
@clip .setter
@@ -2352,13 +2429,6 @@ def clip(self, value):
2352
2429
self ._clip = value
2353
2430
self ._changed ()
2354
2431
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
-
2362
2432
@staticmethod
2363
2433
def process_value (value ):
2364
2434
"""
@@ -2400,24 +2470,7 @@ def process_value(value):
2400
2470
return result , is_scalar
2401
2471
2402
2472
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
2421
2474
if clip is None :
2422
2475
clip = self .clip
2423
2476
@@ -2468,7 +2521,7 @@ def inverse(self, value):
2468
2521
return vmin + value * (vmax - vmin )
2469
2522
2470
2523
def autoscale (self , A ):
2471
- """Set *vmin*, *vmax* to min, max of *A*."""
2524
+ # docstring inherited
2472
2525
with self .callbacks .blocked ():
2473
2526
# Pause callbacks while we are updating so we only get
2474
2527
# a single update signal at the end
@@ -2477,7 +2530,7 @@ def autoscale(self, A):
2477
2530
self ._changed ()
2478
2531
2479
2532
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
2481
2534
A = np .asanyarray (A )
2482
2535
2483
2536
if isinstance (A , np .ma .MaskedArray ):
@@ -2491,7 +2544,7 @@ def autoscale_None(self, A):
2491
2544
self .vmax = A .max ()
2492
2545
2493
2546
def scaled (self ):
2494
- """Return whether *vmin* and *vmax* are both set."""
2547
+ # docstring inherited
2495
2548
return self .vmin is not None and self .vmax is not None
2496
2549
2497
2550
@@ -2775,7 +2828,7 @@ def _make_norm_from_scale(
2775
2828
unlike to arbitrary lambdas.
2776
2829
"""
2777
2830
2778
- class Norm (base_norm_cls ):
2831
+ class ScaleNorm (base_norm_cls ):
2779
2832
def __reduce__ (self ):
2780
2833
cls = type (self )
2781
2834
# If the class is toplevel-accessible, it is possible to directly
@@ -2855,15 +2908,15 @@ def autoscale_None(self, A):
2855
2908
return super ().autoscale_None (in_trf_domain )
2856
2909
2857
2910
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"
2860
2913
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__
2865
2918
2866
- return Norm
2919
+ return ScaleNorm
2867
2920
2868
2921
2869
2922
def _create_empty_object_of_class (cls ):
0 commit comments