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

Skip to content

Commit 0a0a241

Browse files
committed
Support diverging SegmentedNorm colors
This supports diverging colormaps with SegmentedNorm normalizers generated from lists that are not necessarily centered about the central colormap value (e.g. [-2, -1, 0, 1, 2, 4, 8, 16]). Auto application of ``diverging=True`` now behaves exactly the same as when passing evenly-spaced lists containing zero.
1 parent b59fbcc commit 0a0a241

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

‎proplot/axes/plot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,8 @@ def _parse_cmap(
22452245
isdiverging = modes['diverging']
22462246
default = 'div' if isdiverging else 'linear'
22472247
norm = _not_none(norm, default)
2248+
if isdiverging and isinstance(norm, str) and norm in ('segments', 'segmented'):
2249+
norm_kw.setdefault('vcenter', 0)
22482250
if isinstance(norm, mcolors.Normalize):
22492251
norm.vmin, norm.vmax = vmin, vmax
22502252
else:

‎proplot/colors.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,22 +2538,22 @@ class SegmentedNorm(mcolors.Normalize):
25382538
Normalizer that scales data linearly with respect to the
25392539
interpolated index in an arbitrary monotonic level sequence.
25402540
"""
2541-
def __init__(self, levels, vmin=None, vmax=None, clip=False):
2541+
def __init__(self, levels, vcenter=None, vmin=None, vmax=None, clip=None, fair=True): # noqa: E501
25422542
"""
25432543
Parameters
25442544
----------
25452545
levels : sequence of float
2546-
The level boundaries. Must be monotonically increasing
2547-
or decreasing.
2546+
The level boundaries. Must be monotonically increasing or decreasing.
2547+
vcenter : float, default: None
2548+
The central colormap value. Default is to omit this.
25482549
vmin : float, optional
2549-
Ignored but included for consistency with other normalizers.
2550-
Set to the minimum of `levels`.
2550+
Ignored but included for consistency. Set to ``min(levels)``.
25512551
vmax : float, optional
2552-
Ignored but included for consistency with other normalizers.
2553-
Set to the minimum of `levels`.
2552+
Ignored but included for consistency. Set to ``max(levels)``.
25542553
clip : bool, optional
2555-
Whether to clip values falling outside of the minimum
2556-
and maximum of `levels`.
2554+
Whether to clip values falling outside of `vmin` and `vmax`.
2555+
fair : bool, optional
2556+
Whether to use fair scaling. See `DivergingNorm`.
25572557
25582558
See also
25592559
--------
@@ -2587,7 +2587,21 @@ def __init__(self, levels, vmin=None, vmax=None, clip=False):
25872587
dest = np.linspace(0, 1, len(levels))
25882588
vmin = np.min(levels)
25892589
vmax = np.max(levels)
2590+
if vcenter is not None:
2591+
center = _interpolate_extrapolate_vector(vcenter, levels, dest)
2592+
idxs, = np.where(np.isclose(vcenter, levels))
2593+
if fair:
2594+
delta = center - 0.5
2595+
delta = max(-(dest[0] - delta), dest[-1] - delta - 1)
2596+
dest = (dest - center) / (1 + 2 * delta) + 0.5
2597+
elif idxs.size and idxs[0] > 0 and idxs[0] < len(levels) - 1:
2598+
dest1 = np.linspace(0, 0.5, idxs[0] + 1)
2599+
dest2 = np.linspace(0.5, 1, len(levels) - idxs[0])
2600+
dest = np.append(dest1, dest2[1:])
2601+
else:
2602+
raise ValueError(f'Center {vcenter} not in level list {levels}.')
25902603
super().__init__(vmin=vmin, vmax=vmax, clip=clip)
2604+
self.vcenter = vcenter # used for DiscreteNorm
25912605
self._x = self.boundaries = levels # 'boundaries' are used in PlotAxes
25922606
self._y = dest
25932607

@@ -2636,26 +2650,24 @@ class DivergingNorm(mcolors.Normalize):
26362650
def __str__(self):
26372651
return type(self).__name__ + f'(center={self.vcenter!r})'
26382652

2639-
def __init__(
2640-
self, vcenter=0, vmin=None, vmax=None, fair=True, clip=None
2641-
):
2653+
def __init__(self, vcenter=0, vmin=None, vmax=None, clip=None, fair=True):
26422654
"""
26432655
Parameters
26442656
----------
26452657
vcenter : float, default: 0
2646-
The data value corresponding to the central colormap position.
2658+
The central data value.
26472659
vmin : float, optional
26482660
The minimum data value.
26492661
vmax : float, optional
26502662
The maximum data value.
2663+
clip : bool, optional
2664+
Whether to clip values falling outside of `vmin` and `vmax`.
26512665
fair : bool, optional
26522666
If ``True`` (default), the speeds of the color gradations on either side
26532667
of the center point are equal, but colormap colors may be omitted. If
26542668
``False``, all colormap colors are included, but the color gradations on
26552669
one side may be faster than the other side. ``False`` should be used with
26562670
great care, as it may result in a misleading interpretation of your data.
2657-
clip : bool, optional
2658-
Whether to clip values falling outside of `vmin` and `vmax`.
26592671
26602672
See also
26612673
--------

0 commit comments

Comments
 (0)