colour.continuous.MultiSignals#

class colour.continuous.MultiSignals(data: ArrayLike | DataFrame | dict | Self | Sequence | Series | Signal | ValuesView | None = None, domain: ArrayLike | KeysView | None = None, labels: Sequence | None = None, **kwargs: Any)[source]#

Bases: AbstractContinuousFunction

Define the base class for multi-signals, a container for multiple colour.continuous.Signal sub-class instances.

Important

Specific documentation about getting, setting, indexing and slicing the multi-signals values is available in the Spectral Representation and Continuous Signal section.

Parameters:

Attributes

Methods

Examples

Instantiation with implicit domain and a single signal:

>>> range_ = np.linspace(10, 100, 10)
>>> print(MultiSignals(range_))
[[  0.  10.]
 [  1.  20.]
 [  2.  30.]
 [  3.  40.]
 [  4.  50.]
 [  5.  60.]
 [  6.  70.]
 [  7.  80.]
 [  8.  90.]
 [  9. 100.]]

Instantiation with explicit domain and a single signal:

>>> domain = np.arange(100, 1100, 100)
>>> print(MultiSignals(range_, domain))
[[ 100.   10.]
 [ 200.   20.]
 [ 300.   30.]
 [ 400.   40.]
 [ 500.   50.]
 [ 600.   60.]
 [ 700.   70.]
 [ 800.   80.]
 [ 900.   90.]
 [1000.  100.]]

Instantiation with multiple signals:

>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> print(MultiSignals(range_, domain))
[[ 100.   10.   20.   30.]
 [ 200.   20.   30.   40.]
 [ 300.   30.   40.   50.]
 [ 400.   40.   50.   60.]
 [ 500.   50.   60.   70.]
 [ 600.   60.   70.   80.]
 [ 700.   70.   80.   90.]
 [ 800.   80.   90.  100.]
 [ 900.   90.  100.  110.]
 [1000.  100.  110.  120.]]

Instantiation with a dict:

>>> print(MultiSignals(dict(zip(domain, range_))))
[[ 100.   10.   20.   30.]
 [ 200.   20.   30.   40.]
 [ 300.   30.   40.   50.]
 [ 400.   40.   50.   60.]
 [ 500.   50.   60.   70.]
 [ 600.   60.   70.   80.]
 [ 700.   70.   80.   90.]
 [ 800.   80.   90.  100.]
 [ 900.   90.  100.  110.]
 [1000.  100.  110.  120.]]

Instantiation using a Signal sub-class:

>>> class NotSignal(Signal):
...     pass
>>> multi_signals = MultiSignals(range_, domain, signal_type=NotSignal)
>>> print(multi_signals)
[[ 100.   10.   20.   30.]
 [ 200.   20.   30.   40.]
 [ 300.   30.   40.   50.]
 [ 400.   40.   50.   60.]
 [ 500.   50.   60.   70.]
 [ 600.   60.   70.   80.]
 [ 700.   70.   80.   90.]
 [ 800.   80.   90.  100.]
 [ 900.   90.  100.  110.]
 [1000.  100.  110.  120.]]
 >>> type(multi_signals.signals[0])
 <class 'multi_signals.NotSignal'>

Instantiation with a Pandas Series:

>>> if is_pandas_installed():
...     from pandas import Series
...
...     print(
...         MultiSignals(
...             Series(dict(zip(domain, np.linspace(10, 100, 10))))
...         )
...     )
[[ 100.   10.]
 [ 200.   20.]
 [ 300.   30.]
 [ 400.   40.]
 [ 500.   50.]
 [ 600.   60.]
 [ 700.   70.]
 [ 800.   80.]
 [ 900.   90.]
 [1000.  100.]]

Instantiation with a Pandas pandas.DataFrame:

>>> if is_pandas_installed():
...     from pandas import DataFrame
...
...     data = dict(zip(["a", "b", "c"], tsplit(range_)))
...     print(MultiSignals(DataFrame(data, domain)))
[[ 100.   10.   20.   30.]
 [ 200.   20.   30.   40.]
 [ 300.   30.   40.   50.]
 [ 400.   40.   50.   60.]
 [ 500.   50.   60.   70.]
 [ 600.   60.   70.   80.]
 [ 700.   70.   80.   90.]
 [ 800.   80.   90.  100.]
 [ 900.   90.  100.  110.]
 [1000.  100.  110.  120.]]

Retrieving domain y variable for arbitrary range x variable:

>>> x = 150
>>> range_ = tstack([np.sin(np.linspace(0, 1, 10))] * 3)
>>> range_ += np.array([0.0, 0.25, 0.5])
>>> MultiSignals(range_, domain)[x]
array([0.0554413..., 0.3054413..., 0.5554413...])
>>> x = np.linspace(100, 1000, 3)
>>> MultiSignals(range_, domain)[x]
array([[0.        , 0.25      , 0.5       ],
       [0.4786858..., 0.7286858..., 0.9786858...],
       [0.8414709..., 1.0914709..., 1.3414709...]])

Using an alternative interpolating function:

>>> x = 150
>>> from colour.algebra import CubicSplineInterpolator
>>> MultiSignals(range_, domain, interpolator=CubicSplineInterpolator)[
...     x
... ]
array([0.0555274..., 0.3055274..., 0.5555274...])
>>> x = np.linspace(100, 1000, 3)
>>> MultiSignals(range_, domain, interpolator=CubicSplineInterpolator)[
...     x
... ]
array([[0.       ..., 0.25     ..., 0.5      ...],
       [0.4794253..., 0.7294253..., 0.9794253...],
       [0.8414709..., 1.0914709..., 1.3414709...]])
__init__(data: ArrayLike | DataFrame | dict | Self | Sequence | Series | Signal | ValuesView | None = None, domain: ArrayLike | KeysView | None = None, labels: Sequence | None = None, **kwargs: Any) → None[source]#
Parameters:
Return type:

None

property dtype: Type[DTypeFloat]#

Getter and setter for the multi-signals dtype.

Parameters:

value – Value to set the multi-signals dtype with.

Returns:

Multi-signals dtype.

Return type:

Type[DTypeFloat]

property domain: NDArrayFloat#

Getter and setter for the multi-signals’ independent domain variable \(x\).

Parameters:

value – Value to set the multi-signals independent domain variable \(x\) with.

Returns:

Multi-signals independent domain variable \(x\).

Return type:

numpy.ndarray

property range: NDArrayFloat#

Getter and setter for the multi-signals’ range variable \(y\).

Parameters:

value – Value to set the multi-signals’ range variable \(y\) with.

Returns:

Multi-signals’ range variable \(y\).

Return type:

numpy.ndarray

property interpolator: Type[ProtocolInterpolator]#

Getter and setter for the multi-signals interpolator type.

Parameters:

value – Value to set the multi-signals interpolator type with.

Returns:

Multi-signals interpolator type.

Return type:

Type[ProtocolInterpolator]

property interpolator_kwargs: dict#

Getter and setter for the interpolator instantiation time arguments.

Parameters:

value – Value to set the multi-signals interpolator instantiation time arguments to.

Returns:

Multi-signals interpolator instantiation time arguments.

Return type:

dict

property extrapolator: Type[ProtocolExtrapolator]#

Getter and setter for the multi-signals extrapolator type.

Parameters:

value – Value to set the multi-signals extrapolator type with.

Returns:

Multi-signals extrapolator type.

Return type:

Type[ProtocolExtrapolator]

property extrapolator_kwargs: dict#

Getter and setter for the multi-signals extrapolator instantiation time arguments.

Parameters:

value – Value to set the multi-signals extrapolator instantiation time arguments to.

Returns:

Multi-signals extrapolator instantiation time arguments.

Return type:

dict

property function: Callable#

Getter for the multi-signals callable.

Returns:

Multi-signals callable.

Return type:

Callable

property signals: Mapping[str, Signal]#

Getter and setter for the dictionary of colour.continuous.Signal sub-class instances.

The canonical state lives at the parent level, in self._domain and self._range: a new colour.continuous.Signal sub-class instance is materialised per label on each access, wrapping a column of self._range.

The returned instances are therefore copies, not views: mutating one, e.g. multi_signals.signals["a"][560] = 1, does not propagate to the parent. Assign to the parent instead, e.g. multi_signals[560] = 1, or set the colour.continuous.MultiSignals.signals property.

Parameters:

value – Dictionary of colour.continuous.Signal sub-class instances to set.

Returns:

Dictionary mapping signal names to their corresponding colour.continuous.Signal sub-class instances.

Return type:

dict

property labels: List[str]#

Getter and setter for the colour.continuous.Signal sub-class instance names.

Parameters:

value – Value to set the colour.continuous.Signal sub-class instance names.

Returns:

colour.continuous.Signal sub-class instance names.

Return type:

list

property signal_type: Type[Signal]#

Getter for the type of colour.continuous.Signal sub-class instances.

Returns:

Type of colour.continuous.Signal sub-class instances used in this multi-signal collection.

Return type:

Type[Signal]

__str__() → str[source]#

Return a formatted string representation of the multi-signals.

Returns:

Formatted string representation.

Return type:

str

Examples

>>> domain = np.arange(0, 10, 1)
>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> print(MultiSignals(range_))
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  40.  50.  60.]
 [  4.  50.  60.  70.]
 [  5.  60.  70.  80.]
 [  6.  70.  80.  90.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
__repr__() → str[source]#

Return an evaluable string representation of the multi-signals.

Returns:

Evaluable string representation.

Return type:

str

Examples

>>> domain = np.arange(0, 10, 1)
>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> MultiSignals(range_)
MultiSignals([[  0.,  10.,  20.,  30.],
              [  1.,  20.,  30.,  40.],
              [  2.,  30.,  40.,  50.],
              [  3.,  40.,  50.,  60.],
              [  4.,  50.,  60.,  70.],
              [  5.,  60.,  70.,  80.],
              [  6.,  70.,  80.,  90.],
              [  7.,  80.,  90., 100.],
              [  8.,  90., 100., 110.],
              [  9., 100., 110., 120.]],
             ['0', '1', '2'],
             LinearInterpolator,
             {},
             Extrapolator,
             {'method': 'Constant', 'left': nan, 'right': nan})
__hash__() → int[source]#

Compute the hash of the multi-signals.

Returns:

Object hash.

Return type:

int

__getitem__(x: TypeAliasForwardRef('ArrayLike') | slice) → NDArrayFloat[source]#

Return the corresponding range variable \(y\) for the specified independent domain variable \(x\).

Parameters:

x (TypeAliasForwardRef('ArrayLike') | slice) – Independent domain variable \(x\).

Returns:

Variable \(y\) range value.

Return type:

numpy.ndarray

Examples

>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> multi_signals = MultiSignals(range_)
>>> print(multi_signals)
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  40.  50.  60.]
 [  4.  50.  60.  70.]
 [  5.  60.  70.  80.]
 [  6.  70.  80.  90.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
>>> multi_signals[0]
array([10., 20., 30.])
>>> multi_signals[np.array([0, 1, 2])]
array([[10., 20., 30.],
       [20., 30., 40.],
       [30., 40., 50.]])
>>> multi_signals[np.linspace(0, 5, 5)]
array([[10. , 20. , 30. ],
       [22.5, 32.5, 42.5],
       [35. , 45. , 55. ],
       [47.5, 57.5, 67.5],
       [60. , 70. , 80. ]])
>>> multi_signals[0:3]
array([[10., 20., 30.],
       [20., 30., 40.],
       [30., 40., 50.]])
>>> multi_signals[:, 0:2]
array([[ 10.,  20.],
       [ 20.,  30.],
       [ 30.,  40.],
       [ 40.,  50.],
       [ 50.,  60.],
       [ 60.,  70.],
       [ 70.,  80.],
       [ 80.,  90.],
       [ 90., 100.],
       [100., 110.]])
__setitem__(x: TypeAliasForwardRef('ArrayLike') | slice, y: ArrayLike) → None[source]#

Set the corresponding range variable \(y\) for the specified independent domain variable \(x\).

Parameters:
  • x (TypeAliasForwardRef('ArrayLike') | slice) – Independent domain variable \(x\).

  • y (ArrayLike) – Corresponding range variable \(y\).

Return type:

None

Examples

>>> domain = np.arange(0, 10, 1)
>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> multi_signals = MultiSignals(range_)
>>> print(multi_signals)
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  40.  50.  60.]
 [  4.  50.  60.  70.]
 [  5.  60.  70.  80.]
 [  6.  70.  80.  90.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
>>> multi_signals[0] = 20
>>> multi_signals[0]
array([20., 20., 20.])
>>> multi_signals[np.array([0, 1, 2])] = 30
>>> multi_signals[np.array([0, 1, 2])]
array([[30., 30., 30.],
       [30., 30., 30.],
       [30., 30., 30.]])
>>> multi_signals[np.linspace(0, 5, 5)] = 50
>>> print(multi_signals)
[[  0.    50.    50.    50.  ]
 [  1.    30.    30.    30.  ]
 [  1.25  50.    50.    50.  ]
 [  2.    30.    30.    30.  ]
 [  2.5   50.    50.    50.  ]
 [  3.    40.    50.    60.  ]
 [  3.75  50.    50.    50.  ]
 [  4.    50.    60.    70.  ]
 [  5.    50.    50.    50.  ]
 [  6.    70.    80.    90.  ]
 [  7.    80.    90.   100.  ]
 [  8.    90.   100.   110.  ]
 [  9.   100.   110.   120.  ]]
>>> multi_signals[np.array([0, 1, 2])] = np.array([10, 20, 30])
>>> print(multi_signals)
[[  0.    10.    20.    30.  ]
 [  1.    10.    20.    30.  ]
 [  1.25  50.    50.    50.  ]
 [  2.    10.    20.    30.  ]
 [  2.5   50.    50.    50.  ]
 [  3.    40.    50.    60.  ]
 [  3.75  50.    50.    50.  ]
 [  4.    50.    60.    70.  ]
 [  5.    50.    50.    50.  ]
 [  6.    70.    80.    90.  ]
 [  7.    80.    90.   100.  ]
 [  8.    90.   100.   110.  ]
 [  9.   100.   110.   120.  ]]
>>> y = np.reshape(np.arange(1, 10, 1), (3, 3))
>>> multi_signals[np.array([0, 1, 2])] = y
>>> print(multi_signals)
[[  0.     1.     2.     3.  ]
 [  1.     4.     5.     6.  ]
 [  1.25  50.    50.    50.  ]
 [  2.     7.     8.     9.  ]
 [  2.5   50.    50.    50.  ]
 [  3.    40.    50.    60.  ]
 [  3.75  50.    50.    50.  ]
 [  4.    50.    60.    70.  ]
 [  5.    50.    50.    50.  ]
 [  6.    70.    80.    90.  ]
 [  7.    80.    90.   100.  ]
 [  8.    90.   100.   110.  ]
 [  9.   100.   110.   120.  ]]
>>> multi_signals[0:3] = 40
>>> multi_signals[0:3]
array([[40., 40., 40.],
       [40., 40., 40.],
       [40., 40., 40.]])
>>> multi_signals[:, 0:2] = 50
>>> print(multi_signals)
[[  0.    50.    50.    40.  ]
 [  1.    50.    50.    40.  ]
 [  1.25  50.    50.    40.  ]
 [  2.    50.    50.     9.  ]
 [  2.5   50.    50.    50.  ]
 [  3.    50.    50.    60.  ]
 [  3.75  50.    50.    50.  ]
 [  4.    50.    50.    70.  ]
 [  5.    50.    50.    50.  ]
 [  6.    50.    50.    90.  ]
 [  7.    50.    50.   100.  ]
 [  8.    50.    50.   110.  ]
 [  9.    50.    50.   120.  ]]
__contains__(x: TypeAliasForwardRef('ArrayLike') | slice) → bool[source]#

Determine whether the multi-signals contains the specified independent domain variable \(x\).

Parameters:

x (TypeAliasForwardRef('ArrayLike') | slice) – Independent domain variable \(x\).

Returns:

Whether \(x\) domain value is contained.

Return type:

bool

Examples

>>> range_ = np.linspace(10, 100, 10)
>>> multi_signals = MultiSignals(range_)
>>> 0 in multi_signals
True
>>> 0.5 in multi_signals
True
>>> 1000 in multi_signals
False
__eq__(other: object) → bool[source]#

Determine whether the multi-signals equals the specified object.

Parameters:

other (object) – Object to determine for equality with the multi-signals.

Returns:

Whether the specified object is equal to the multi-signals.

Return type:

bool

Examples

>>> range_ = np.linspace(10, 100, 10)
>>> multi_signals_1 = MultiSignals(range_)
>>> multi_signals_2 = MultiSignals(range_)
>>> multi_signals_1 == multi_signals_2
True
>>> multi_signals_2[0] = 20
>>> multi_signals_1 == multi_signals_2
False
>>> multi_signals_2[0] = 10
>>> multi_signals_1 == multi_signals_2
True
>>> from colour.algebra import CubicSplineInterpolator
>>> multi_signals_2.interpolator = CubicSplineInterpolator
>>> multi_signals_1 == multi_signals_2
False
__ne__(other: object) → bool[source]#

Determine whether the multi-signals is not equal to the specified object.

Parameters:

other (object) – Object to test whether it is not equal to the multi-signals.

Returns:

Whether the specified object is not equal to the multi-signals.

Return type:

bool

Examples

>>> range_ = np.linspace(10, 100, 10)
>>> multi_signals_1 = MultiSignals(range_)
>>> multi_signals_2 = MultiSignals(range_)
>>> multi_signals_1 != multi_signals_2
False
>>> multi_signals_2[0] = 20
>>> multi_signals_1 != multi_signals_2
True
>>> multi_signals_2[0] = 10
>>> multi_signals_1 != multi_signals_2
False
>>> from colour.algebra import CubicSplineInterpolator
>>> multi_signals_2.interpolator = CubicSplineInterpolator
>>> multi_signals_1 != multi_signals_2
True
arithmetical_operation(a: ArrayLike | AbstractContinuousFunction, operation: Literal['+', '-', '*', '/', '**'], in_place: bool = False) → MultiSignals[source]#

Perform the specified arithmetical operation with operand \(a\), either on a copy or in-place.

Parameters:
  • a (ArrayLike | AbstractContinuousFunction) – Operand \(a\). Can be a numeric value, array-like object, or another continuous function instance.

  • operation (Literal['+', '-', '*', '/', '**']) – Operation to perform.

  • in_place (bool) – Operation happens in place.

Returns:

Multi-signals.

Return type:

colour.continuous.MultiSignals

Examples

Adding a single numeric variable:

>>> domain = np.arange(0, 10, 1)
>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> multi_signals_1 = MultiSignals(range_)
>>> print(multi_signals_1)
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  40.  50.  60.]
 [  4.  50.  60.  70.]
 [  5.  60.  70.  80.]
 [  6.  70.  80.  90.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
>>> print(multi_signals_1.arithmetical_operation(10, "+", True))
[[  0.  20.  30.  40.]
 [  1.  30.  40.  50.]
 [  2.  40.  50.  60.]
 [  3.  50.  60.  70.]
 [  4.  60.  70.  80.]
 [  5.  70.  80.  90.]
 [  6.  80.  90. 100.]
 [  7.  90. 100. 110.]
 [  8. 100. 110. 120.]
 [  9. 110. 120. 130.]]

Adding an ArrayLike variable:

>>> a = np.linspace(10, 100, 10)
>>> print(multi_signals_1.arithmetical_operation(a, "+", True))
[[  0.  30.  40.  50.]
 [  1.  50.  60.  70.]
 [  2.  70.  80.  90.]
 [  3.  90. 100. 110.]
 [  4. 110. 120. 130.]
 [  5. 130. 140. 150.]
 [  6. 150. 160. 170.]
 [  7. 170. 180. 190.]
 [  8. 190. 200. 210.]
 [  9. 210. 220. 230.]]
>>> a = np.array([[10, 20, 30]])
>>> print(multi_signals_1.arithmetical_operation(a, "+", True))
[[  0.  40.  60.  80.]
 [  1.  60.  80. 100.]
 [  2.  80. 100. 120.]
 [  3. 100. 120. 140.]
 [  4. 120. 140. 160.]
 [  5. 140. 160. 180.]
 [  6. 160. 180. 200.]
 [  7. 180. 200. 220.]
 [  8. 200. 220. 240.]
 [  9. 220. 240. 260.]]
>>> a = np.reshape(np.arange(0, 30, 1), (10, 3))
>>> print(multi_signals_1.arithmetical_operation(a, "+", True))
[[  0.  40.  61.  82.]
 [  1.  63.  84. 105.]
 [  2.  86. 107. 128.]
 [  3. 109. 130. 151.]
 [  4. 132. 153. 174.]
 [  5. 155. 176. 197.]
 [  6. 178. 199. 220.]
 [  7. 201. 222. 243.]
 [  8. 224. 245. 266.]
 [  9. 247. 268. 289.]]

Adding a colour.continuous.Signal sub-class:

>>> multi_signals_2 = MultiSignals(range_)
>>> print(multi_signals_1.arithmetical_operation(multi_signals_2, "+", True))
[[  0.  50.  81. 112.]
 [  1.  83. 114. 145.]
 [  2. 116. 147. 178.]
 [  3. 149. 180. 211.]
 [  4. 182. 213. 244.]
 [  5. 215. 246. 277.]
 [  6. 248. 279. 310.]
 [  7. 281. 312. 343.]
 [  8. 314. 345. 376.]
 [  9. 347. 378. 409.]]
static multi_signals_unpack_data(data: ArrayLike | DataFrame | dict | MultiSignals | Sequence | Series | Signal | ValuesView | None = None, domain: ArrayLike | KeysView | None = None, labels: Sequence | None = None, dtype: Type[DTypeFloat] | None = None, **kwargs: Any) → tuple[NDArrayFloat, NDArrayFloat, List[str]][source]#

Unpack specified data for multi-signals instantiation.

Parameters:
Returns:

Tuple of (domain, range, labels) where domain is the unpacked independent variable as an (N,) array, range is the unpacked dependent variable as an (N, M) array with one column per signal, and labels is the list of signal labels of length M.

Return type:

tuple

Examples

Unpacking using implicit domain and data for a single signal:

>>> range_ = np.linspace(10, 100, 10)
>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     range_
... )
>>> labels
['0']
>>> print(np.column_stack([domain, range_unpacked]))
[[  0.  10.]
 [  1.  20.]
 [  2.  30.]
 [  3.  40.]
 [  4.  50.]
 [  5.  60.]
 [  6.  70.]
 [  7.  80.]
 [  8.  90.]
 [  9. 100.]]

Unpacking using explicit domain and data for a single signal:

>>> domain_ = np.arange(100, 1100, 100)
>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     range_, domain_
... )
>>> labels
['0']
>>> print(np.column_stack([domain, range_unpacked]))
[[ 100.   10.]
 [ 200.   20.]
 [ 300.   30.]
 [ 400.   40.]
 [ 500.   50.]
 [ 600.   60.]
 [ 700.   70.]
 [ 800.   80.]
 [ 900.   90.]
 [1000.  100.]]

Unpacking using data for multiple signals:

>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     range_, domain_
... )
>>> labels
['0', '1', '2']
>>> print(np.column_stack([domain, range_unpacked[:, 2]]))
[[ 100.   30.]
 [ 200.   40.]
 [ 300.   50.]
 [ 400.   60.]
 [ 500.   70.]
 [ 600.   80.]
 [ 700.   90.]
 [ 800.  100.]
 [ 900.  110.]
 [1000.  120.]]

Unpacking using a dict:

>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     dict(zip(domain_, range_))
... )
>>> labels
['0', '1', '2']
>>> print(np.column_stack([domain, range_unpacked[:, 2]]))
[[ 100.   30.]
 [ 200.   40.]
 [ 300.   50.]
 [ 400.   60.]
 [ 500.   70.]
 [ 600.   80.]
 [ 700.   90.]
 [ 800.  100.]
 [ 900.  110.]
 [1000.  120.]]

Unpacking using a sequence of Signal instances:

>>> from colour.continuous import Signal
>>> signals_seq = [Signal(range_[:, i], domain_, name=str(i)) for i in range(3)]
>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     signals_seq
... )
>>> labels
['0', '1', '2']
>>> print(np.column_stack([domain, range_unpacked[:, 2]]))
[[ 100.   30.]
 [ 200.   40.]
 [ 300.   50.]
 [ 400.   60.]
 [ 500.   70.]
 [ 600.   80.]
 [ 700.   90.]
 [ 800.  100.]
 [ 900.  110.]
 [1000.  120.]]

Unpacking from an existing MultiSignals instance:

>>> multi_signals = MultiSignals(range_, domain_)
>>> domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...     multi_signals
... )
>>> labels
['0', '1', '2']
>>> print(np.column_stack([domain, range_unpacked[:, 2]]))
[[ 100.   30.]
 [ 200.   40.]
 [ 300.   50.]
 [ 400.   60.]
 [ 500.   70.]
 [ 600.   80.]
 [ 700.   90.]
 [ 800.  100.]
 [ 900.  110.]
 [1000.  120.]]

Unpacking using a Pandas Series:

>>> if is_pandas_installed():
...     from pandas import Series
...
...     domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...         Series(dict(zip(domain_, np.linspace(10, 100, 10))))
...     )
...     print(np.column_stack([domain, range_unpacked]))
[[ 100.   10.]
 [ 200.   20.]
 [ 300.   30.]
 [ 400.   40.]
 [ 500.   50.]
 [ 600.   60.]
 [ 700.   70.]
 [ 800.   80.]
 [ 900.   90.]
 [1000.  100.]]

Unpacking using a Pandas pandas.DataFrame:

>>> if is_pandas_installed():
...     from pandas import DataFrame
...
...     data = dict(zip(["a", "b", "c"], tsplit(range_)))
...     domain, range_unpacked, labels = MultiSignals.multi_signals_unpack_data(
...         DataFrame(data, domain_)
...     )
...     print(np.column_stack([domain, range_unpacked[:, 2]]))
[[ 100.   30.]
 [ 200.   40.]
 [ 300.   50.]
 [ 400.   60.]
 [ 500.   70.]
 [ 600.   80.]
 [ 700.   90.]
 [ 800.  100.]
 [ 900.  110.]
 [1000.  120.]]
fill_nan(method: Literal['Constant', 'Interpolation'] | str = 'Interpolation', default: Real = 0) → MultiSignals[source]#

Fill NaNs in independent domain variable \(x\) and corresponding range variable \(y\) using the specified method.

Parameters:
  • method (Literal['Constant', 'Interpolation'] | str) – Interpolation method linearly interpolates through the NaNs, Constant method replaces NaNs with default.

  • default (Real) – Value to use with the Constant method.

Returns:

Multi-signals with NaN values filled.

Return type:

colour.continuous.MultiSignals

Examples

>>> domain = np.arange(0, 10, 1)
>>> range_ = tstack([np.linspace(10, 100, 10)] * 3)
>>> range_ += np.array([0, 10, 20])
>>> multi_signals = MultiSignals(range_)
>>> multi_signals[3:7] = np.nan
>>> print(multi_signals)
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  nan  nan  nan]
 [  4.  nan  nan  nan]
 [  5.  nan  nan  nan]
 [  6.  nan  nan  nan]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
>>> print(multi_signals.fill_nan())
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.  40.  50.  60.]
 [  4.  50.  60.  70.]
 [  5.  60.  70.  80.]
 [  6.  70.  80.  90.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
>>> multi_signals[3:7] = np.nan
>>> print(multi_signals.fill_nan(method="Constant"))
[[  0.  10.  20.  30.]
 [  1.  20.  30.  40.]
 [  2.  30.  40.  50.]
 [  3.   0.   0.   0.]
 [  4.   0.   0.   0.]
 [  5.   0.   0.   0.]
 [  6.   0.   0.   0.]
 [  7.  80.  90. 100.]
 [  8.  90. 100. 110.]
 [  9. 100. 110. 120.]]
to_dataframe() → DataFrame[source]#

Convert the continuous signal to a Pandas pandas.DataFrame class instance.

Returns:

Continuous signal as a Pandas pandas.DataFrame class instance.

Return type:

pandas.DataFrame

Examples

>>> if is_pandas_installed():
...     domain = np.arange(0, 10, 1)
...     range_ = tstack([np.linspace(10, 100, 10)] * 3)
...     range_ += np.array([0, 10, 20])
...     multi_signals = MultiSignals(range_)
...     print(multi_signals.to_dataframe())
         0      1      2
0.0   10.0   20.0   30.0
1.0   20.0   30.0   40.0
2.0   30.0   40.0   50.0
3.0   40.0   50.0   60.0
4.0   50.0   60.0   70.0
5.0   60.0   70.0   80.0
6.0   70.0   80.0   90.0
7.0   80.0   90.0  100.0
8.0   90.0  100.0  110.0
9.0  100.0  110.0  120.0