Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a8de87b

Browse files
committed
Added SymNorm for normalizing symmetrical data around a center (0 by default).
1 parent 34f99a9 commit a8de87b

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

lib/matplotlib/colors.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,82 @@ def __call__(self, value, clip=None):
12551255
return result
12561256

12571257

1258+
class SymNorm(Normalize):
1259+
def __init__(self, vcenter=0.0, vmax=None, clip=False):
1260+
"""
1261+
Normalize symmetrical data around a center (0 by default).
1262+
1263+
Unlike `TwoSlopeNorm`, `SymNorm` applies an equal rate of change
1264+
around the center.
1265+
1266+
Useful when mapping symmetrical data around a conceptual center
1267+
e.g., data that range from -2 to 4, with 0 as the midpoint, and
1268+
with equal rates of change around that midpoint.
1269+
1270+
Parameters
1271+
----------
1272+
vcenter : float, optional
1273+
The data value that defines ``0.5`` in the normalization.
1274+
Defaults to ``0.0``.
1275+
vmax : float, optional
1276+
The data value that defines ``1.0`` in the normalization.
1277+
Defaults to the sum of *vcenter* plus the largest absolute
1278+
difference to *vcenter* for the values in the dataset.
1279+
If vmax is less than *vcenter*, it is automatically mirrored
1280+
over the center.
1281+
1282+
Examples
1283+
--------
1284+
This maps data values -2 to 0.25, 0 to 0.5, and 4 to 1.0
1285+
(assuming equal rates of change above and below 0.0):
1286+
1287+
>>> import matplotlib.colors as mcolors
1288+
>>> norm = mcolors.SymNorm(vmax=4.0)
1289+
>>> data = [-2., 0., 4.]
1290+
>>> norm(data)
1291+
array([[0.25, 0.5 , 1. ])
1292+
"""
1293+
1294+
self._vcenter = vcenter
1295+
if vmax is None:
1296+
self.vmin = None
1297+
self.vmax = None
1298+
else:
1299+
self.vmax = vcenter + abs(vmax-vcenter)
1300+
self.vmin = vcenter - vmax
1301+
self.clip = clip
1302+
1303+
def autoscale(self, A):
1304+
"""
1305+
Set *vmax* to *vcenter* + max(abs(*A*-*vcenter*)),
1306+
then mirror *vmax* around *vcenter* to set *vmin*.
1307+
"""
1308+
A = np.asanyarray(A)
1309+
self.vmax = self._vcenter + max(self._vcenter-A.min(),
1310+
A.max()-self._vcenter)
1311+
self.vmin = 2*self._vcenter - self.vmax
1312+
1313+
def autoscale_None(self, A):
1314+
"""Set *vmin* and *vmax*."""
1315+
A = np.asanyarray(A)
1316+
if self.vmax is None and A.size:
1317+
self.autoscale(A)
1318+
1319+
@property
1320+
def vcenter(self):
1321+
return self._vcenter
1322+
1323+
@vcenter.setter
1324+
def vcenter(self, vcenter):
1325+
self._vcenter = vcenter
1326+
if self.vmax is not None:
1327+
# recompute vmax and vmin,assuming they represent
1328+
# min and max of data
1329+
self.vmax = self._vcenter + max(self._vcenter-self.vmin,
1330+
self.vmax-self._vcenter)
1331+
self.vmin = 2*self._vcenter - self.vmax
1332+
1333+
12581334
def _make_norm_from_scale(scale_cls, base_norm_cls=None, *, init=None):
12591335
"""
12601336
Decorator for building a `.Normalize` subclass from a `.Scale` subclass.

0 commit comments

Comments
 (0)