Skip to content

Clean up and clarify Normalize docs #16271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 49 additions & 30 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,27 +922,32 @@ def reversed(self, name=None):

class Normalize:
"""
A class which, when called, can normalize data into
the ``[0.0, 1.0]`` interval.

A class which, when called, linearly normalizes data into the
``[0.0, 1.0]`` interval.
"""
def __init__(self, vmin=None, vmax=None, clip=False):
"""
If *vmin* or *vmax* is not given, they are initialized from the
Parameters
----------
vmin : scalar
vmax : scalar
clip : bool
If ``True`` values falling outside the range ``[vmin, vmax]``,
are mapped to 0 or 1, whichever is closer, and masked values are
set to 1. If ``False`` masked values remain masked.

Notes
-----
If neither *vmin* or *vmax* are given, they are initialized from the
minimum and maximum value respectively of the first input
processed. That is, *__call__(A)* calls *autoscale_None(A)*.
If *clip* is *True* and the given value falls outside the range,
the returned value will be 0 or 1, whichever is closer.
Returns 0 if ::
processed. That is, ``__call__(A)`` calls ``autoscale_None(A)``.
Returns 0 if::

vmin==vmax

Works with scalars or arrays, including masked arrays. If
*clip* is *True*, masked values are set to 1; otherwise they
remain masked. Clipping silently defeats the purpose of setting
the over, under, and masked colors in the colormap, so it is
likely to lead to surprises; therefore the default is
*clip* = *False*.
Clipping silently defeats the purpose of setting the over, under, and
masked colors in a colormap, so it is likely to lead to surprises;
therefore the default is ``clip=False``.
"""
self.vmin = _sanitize_extrema(vmin)
self.vmax = _sanitize_extrema(vmax)
Expand All @@ -955,15 +960,19 @@ def process_value(value):

*value* can be a scalar or sequence.

Returns *result*, *is_scalar*, where *result* is a
masked array matching *value*. Float dtypes are preserved;
integer types with two bytes or smaller are converted to
np.float32, and larger types are converted to np.float64.
Preserving float32 when possible, and using in-place operations,
can greatly improve speed for large arrays.
Returns
-------
result : masked array
Masked array with the same shape as *value*.
is_scalar : bool
``True`` if *value* is a scalar.

Experimental; we may want to add an option to force the
use of float32.
Notes
-----
Float dtypes are preserved; integer types with two bytes or smaller are
converted to np.float32, and larger types are converted to np.float64.
Preserving float32 when possible, and using in-place operations,
greatly improves speed for large arrays.
"""
is_scalar = not np.iterable(value)
if is_scalar:
Expand All @@ -981,11 +990,21 @@ def process_value(value):

def __call__(self, value, clip=None):
"""
Normalize *value* data in the ``[vmin, vmax]`` interval into
the ``[0.0, 1.0]`` interval and return it. *clip* defaults
to ``self.clip`` (which defaults to *False*). If not already
initialized, *vmin* and *vmax* are initialized using
``autoscale_None(value)``.
Normalize *value* data in the ``[vmin, vmax]`` interval into the
``[0.0, 1.0]`` interval and return it.

Parameters
----------
value
Data to normalize.
clip : bool
If ``None``, defaults to ``self.clip`` (which defaults to
``False``).

Notes
-----
If not already initialized, ``self.vmin`` and ``self.vmax`` are
initialized using ``self.autoscale_None(value)``.
"""
if clip is None:
clip = self.clip
Expand Down Expand Up @@ -1016,7 +1035,7 @@ def __call__(self, value, clip=None):

def inverse(self, value):
if not self.scaled():
raise ValueError("Not invertible until scaled")
raise ValueError("Not invertible until both vmin and vmax are set")
(vmin,), _ = self.process_value(self.vmin)
(vmax,), _ = self.process_value(self.vmax)

Expand All @@ -1033,7 +1052,7 @@ def autoscale(self, A):
self.vmax = A.max()

def autoscale_None(self, A):
"""Autoscale only None-valued vmin or vmax."""
"""If vmin or vmax are not set, use the min/max of *A* to set them."""
A = np.asanyarray(A)
if self.vmin is None and A.size:
self.vmin = A.min()
Expand Down Expand Up @@ -1194,7 +1213,7 @@ class SymLogNorm(Normalize):
*linthresh* allows the user to specify the size of this range
(-*linthresh*, *linthresh*).
"""
def __init__(self, linthresh, linscale=1.0,
def __init__(self, linthresh, linscale=1.0,
vmin=None, vmax=None, clip=False):
"""
Parameters
Expand Down