bounds - Limiting data values for a palette¶
Continuous variables have values anywhere in the range minus infinite to plus infinite. However, when creating a visual representation of these values what usually matters is the relative difference between the values. This is where rescaling comes into play.
The values are mapped onto a range that a scale can deal with. For graphical representation that range tends to be \([0, 1]\) or \([0, n]\), where \(n\) is some number that makes the plotted object overflow the plotting area.
Although a scale may be able handle the \([0, n]\) range, it may be desirable to have a lower bound greater than zero. For example, if data values get mapped to zero on a scale whose graphical representation is the size/area/radius/length some data will be invisible. The solution is to restrict the lower bound e.g. \([0.1, 1]\). Similarly you can restrict the upper bound -- using these functions.
- mizani.bounds.censor(x: NDArrayFloat | Sequence[float], range: TupleFloat2 = (0, 1), only_finite: bool = True) NDArrayFloat [source]¶
- mizani.bounds.censor(x: FloatSeries, range: TupleFloat2 = (0, 1), only_finite: bool = True) FloatSeries
Convert any values outside of range to a NULL type object.
- Parameters:
- xarray_like
Values to manipulate
- range
tuple
(min, max) giving desired output range
- only_finitebool
If True (the default), will only modify finite values.
- Returns:
- xarray_like
Censored array
Notes
All values in
x
should be of the same type.only_finite
parameter is not considered for Datetime and Timedelta types.The NULL type object depends on the type of values in x.
float
-float('nan')
int
-float('nan')
datetime.datetime
:np.datetime64(NaT)
datetime.timedelta
:np.timedelta64(NaT)
Examples
>>> a = np.array([1, 2, np.inf, 3, 4, -np.inf, 5]) >>> list(censor(a, (0, 10))) [1.0, 2.0, inf, 3.0, 4.0, -inf, 5.0] >>> list(censor(a, (0, 10), False)) [1.0, 2.0, nan, 3.0, 4.0, nan, 5.0] >>> list(censor(a, (2, 4))) [nan, 2.0, inf, 3.0, 4.0, -inf, nan]
- mizani.bounds.expand_range(range: TupleFloat2, mul: float = 0, add: float = 0, zero_width: float = 1) TupleFloat2 [source]¶
Expand a range with a multiplicative or additive constant
- Parameters:
- Returns:
- out
tuple
Expanded range
- out
Notes
If expanding datetime or timedelta types, add and zero_width must be suitable timedeltas i.e. You should not mix types between Numpy, Pandas and the
datetime
module.Examples
>>> expand_range((3, 8)) (3, 8) >>> expand_range((0, 10), mul=0.1) (-1.0, 11.0) >>> expand_range((0, 10), add=2) (-2, 12) >>> expand_range((0, 10), mul=.1, add=2) (-3.0, 13.0) >>> expand_range((0, 1)) (0, 1)
When the range has zero width
>>> expand_range((5, 5)) (4.5, 5.5)
- mizani.bounds.rescale(x: FloatArrayLike, to: TupleFloat2 = (0, 1), _from: TupleFloat2 | None = None) NDArrayFloat [source]¶
Rescale numeric vector to have specified minimum and maximum.
- Parameters:
- xarray_like |
numeric
1D vector of values to manipulate.
- to
tuple
output range (numeric vector of length two)
- _from
tuple
input range (numeric vector of length two). If not given, is calculated from the range of x
- xarray_like |
- Returns:
- outarray_like
Rescaled values
Examples
>>> x = [0, 2, 4, 6, 8, 10] >>> rescale(x) array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> rescale(x, to=(0, 2)) array([0. , 0.4, 0.8, 1.2, 1.6, 2. ]) >>> rescale(x, to=(0, 2), _from=(0, 20)) array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])
- mizani.bounds.rescale_max(x: FloatArrayLike, to: TupleFloat2 = (0, 1), _from: TupleFloat2 | None = None) NDArrayFloat [source]¶
Rescale numeric vector to have specified maximum.
- Parameters:
- xarray_like
1D vector of values to manipulate.
- to
tuple
output range (numeric vector of length two)
- _from
tuple
input range (numeric vector of length two). If not given, is calculated from the range of x. Only the 2nd (max) element is essential to the output.
- Returns:
- outarray_like
Rescaled values
Examples
>>> x = np.array([0, 2, 4, 6, 8, 10]) >>> rescale_max(x, (0, 3)) array([0. , 0.6, 1.2, 1.8, 2.4, 3. ])
Only the 2nd (max) element of the parameters
to
and_from
are essential to the output.>>> rescale_max(x, (1, 3)) array([0. , 0.6, 1.2, 1.8, 2.4, 3. ]) >>> rescale_max(x, (0, 20)) array([ 0., 4., 8., 12., 16., 20.])
If
max(x) < _from[1]
then values will be scaled beyond the requested maximum (to[1]
).>>> rescale_max(x, to=(1, 3), _from=(-1, 6)) array([0., 1., 2., 3., 4., 5.])
If the values are the same, they taken on the requested maximum. This includes an array of all zeros.
>>> rescale_max(np.array([5, 5, 5])) array([1., 1., 1.]) >>> rescale_max(np.array([0, 0, 0])) array([1, 1, 1])
- mizani.bounds.rescale_mid(x: FloatArrayLike, to: TupleFloat2 = (0, 1), _from: TupleFloat2 | None = None, mid: float = 0) NDArrayFloat [source]¶
Rescale numeric vector to have specified minimum, midpoint, and maximum.
- Parameters:
- xarray_like
1D vector of values to manipulate.
- to
tuple
output range (numeric vector of length two)
- _from
tuple
input range (numeric vector of length two). If not given, is calculated from the range of x
- mid
numeric
mid-point of input range
- Returns:
- outarray_like
Rescaled values
Examples
>>> rescale_mid([1, 2, 3], mid=1) array([0.5 , 0.75, 1. ]) >>> rescale_mid([1, 2, 3], mid=2) array([0. , 0.5, 1. ])
- mizani.bounds.squish_infinite(x: FloatArrayLike, range: TupleFloat2 = (0, 1)) NDArrayFloat [source]¶
Truncate infinite values to a range.
- Parameters:
- xarray_like
Values that should have infinities squished.
- range
tuple
The range onto which to squish the infinites. Must be of size 2.
- Returns:
- outarray_like
Values with infinites squished.
Examples
>>> arr1 = np.array([0, .5, .25, np.inf, .44]) >>> arr2 = np.array([0, -np.inf, .5, .25, np.inf]) >>> list(squish_infinite(arr1)) [0.0, 0.5, 0.25, 1.0, 0.44] >>> list(squish_infinite(arr2, (-10, 9))) [0.0, -10.0, 0.5, 0.25, 9.0]
- mizani.bounds.zero_range(x: tuple[Any, Any], tol: float = 2.220446049250313e-14) bool [source]¶
Determine if range of vector is close to zero.
- Parameters:
- xarray_like
Value(s) to check. If it is an array_like, it should be of length 2.
- tol
float
Tolerance. Default tolerance is the machine epsilon times \(10^2\).
- Returns:
- outbool
Whether
x
has zero range.
Examples
>>> zero_range([1, 1]) True >>> zero_range([1, 2]) False >>> zero_range([1, 2], tol=2) True
- mizani.bounds.expand_range_distinct(range: TupleFloat2, expand: TupleFloat2 | TupleFloat4 = (0, 0, 0, 0), zero_width: float = 1) TupleFloat2 [source]¶
Expand a range with a multiplicative or additive constants
Similar to
expand_range()
but both sides of the range expanded using different constants- Parameters:
- range
tuple
Range of data. Size 2
- expand
tuple
Length 2 or 4. If length is 2, then the same constants are used for both sides. If length is 4 then the first two are are the Multiplicative (mul) and Additive (add) constants for the lower limit, and the second two are the constants for the upper limit.
- zero_width
int
|float
|timedelta
Distance to use if range has zero width
- range
- Returns:
- out
tuple
Expanded range
- out
Examples
>>> expand_range_distinct((3, 8)) (3, 8) >>> expand_range_distinct((0, 10), (0.1, 0)) (-1.0, 11.0) >>> expand_range_distinct((0, 10), (0.1, 0, 0.1, 0)) (-1.0, 11.0) >>> expand_range_distinct((0, 10), (0.1, 0, 0, 0)) (-1.0, 10) >>> expand_range_distinct((0, 10), (0, 2)) (-2, 12) >>> expand_range_distinct((0, 10), (0, 2, 0, 2)) (-2, 12) >>> expand_range_distinct((0, 10), (0, 0, 0, 2)) (0, 12) >>> expand_range_distinct((0, 10), (.1, 2)) (-3.0, 13.0) >>> expand_range_distinct((0, 10), (.1, 2, .1, 2)) (-3.0, 13.0) >>> expand_range_distinct((0, 10), (0, 0, .1, 2)) (0, 13.0)
- mizani.bounds.squish(x: FloatArrayLike, range: TupleFloat2 = (0, 1), only_finite: bool = True) NDArrayFloat [source]¶
Squish values into range.
- Parameters:
- xarray_like
Values that should have out of range values squished.
- range
tuple
The range onto which to squish the values.
- only_finite: boolean
When true, only squishes finite values.
- Returns:
- outarray_like
Values with out of range values squished.
Examples
>>> list(squish([-1.5, 0.2, 0.8, 1.0, 1.2])) [0.0, 0.2, 0.8, 1.0, 1.0]
>>> list(squish([-np.inf, -1.5, 0.2, 0.8, 1.0, np.inf], only_finite=False)) [0.0, 0.0, 0.2, 0.8, 1.0, 1.0]