Colour 0.4.5 - Alpha Milestone
Features
Dependencies
- Support for Python 3.13 was implemented. (#1302, @ KelSolaar)
- Support for Numpy 2 was implemented. (#1279, @KelSolaar)
- pygraphviz was replaced with pydot so that installation is easier:
pygraphviz
needs to be built , which is not trivial, whereaspydot
is a pure Python package.
The following scientific packages minimum versions are required:
- numpy >= 1.24
- scipy >= 1.10
- matplotlib >= 3.7
- networkx >= 3
- pandas >= 2
Development Environment
Astral's uv
-
We switched from Poetry to uv and hatch for managing the development environment and build our wheels. (#1300)
- uv is faster at resolving the environment and the team at astral.sh has been doing wonders for the Python ecosystem, we have been using ruff for a while now.
- It is so good that it literally only requires
uv run --with colour-science my_script.py
to run a script using Colour. - Thanks a ton to @charliermarsh et al.!
-
Improve static typing checks using multi-threading thanks to @erictraut suggestion.
Environment
It is now possible to create a ~/.colour-science/colour-science.jenv
JSON file from which Colour will load environment variables from: (#1239, @KelSolaar)
{
"COLOUR_SCIENCE__COLOUR__SHOW_WARNINGS_WITH_TRACEBACK": 1
}
The following new environment variables are now supported:
COLOUR_SCIENCE__FILTER_RUNTIME_WARNINGS
: Filter Colour runtime warnings.COLOUR_SCIENCE__FILTER_USAGE_WARNINGS
: Filter Colour usage warnings.COLOUR_SCIENCE__FILTER_COLOUR_WARNINGS
: Filter Colour warnings, this also filters Colour usage and runtime warnings.COLOUR_SCIENCE__FILTER_PYTHON_WARNINGS
: Filter Python warnings.
Input and Output
- Definitions reading from and writing to files now support the
pathlib.Path
type. (ff4fe99, @KelSolaar)
colour.adaptation
- Implement support for vK20 chromatic adaptation transform with
colour.adaptation.matrix_chromatic_adaptation_vk20
andcolour.adaptation.chromatic_adaptation_vK20
definitions. (#1131, @KelSolaar)
colour.characterisation
- Add the ColorChecker SG chromaticity coordinates with the
colour.CCS_COLOURCHECKERS["ColorCheckerSG - Before November 2014"]
andcolour.CCS_COLOURCHECKERS["ColorCheckerSG - After November 2014"]
attribute keys.
colour.colorimetry
- Use
shape
if passed, to also reshape thecolour.continuous.AbstractContinuousSignal
sub-classes incolour.colorimetry.sd_to_XYZ_integration
definition. (#1250, @KelSolaar)
colour.models
-
Programmatically add polar conversions to the following definitions: (#1183, #1272, @KelSolaar)
-
colour.Lab_to_LCHab
* -
colour.LCHab_to_Lab
* -
colour.Luv_to_LCHuv
* -
colour.LCHuv_to_Luv
* -
colour.hdr_CIELab_to_hdr_CIELCHab
-
colour.hdr_CIELCHab_to_hdr_CIELab
-
colour.Hunter_Lab_to_Hunter_LCHab
-
colour.Hunter_LCHab_to_Hunter_Lab
-
colour.Hunter_Rdab_to_Hunter_RdCHab
-
colour.Hunter_RdCHab_to_Hunter_Rdab
-
colour.ICaCb_to_ICHab
-
colour.ICHab_to_ICaCb
-
colour.ICtCp_to_ICHtp
-
colour.ICHtp_to_ICtCp
-
colour.IgPgTg_to_IgCHpt
-
colour.IgCHpt_to_IgPgTg
-
colour.IPT_to_ICH
-
colour.ICH_to_IPT
-
colour.Izazbz_to_IzCHab
-
colour.IzCHab_to_Izazbz
-
colour.Jzazbz_to_JzCHab
-
colour.JzCHab_to_Jzazbz
-
colour.hdr_IPT_to_hdr_ICH
-
colour.hdr_ICH_to_hdr_IPT
-
colour.Oklab_to_Oklch
-
colour.Oklch_to_Oklab
-
colour.ProLab_to_ProLCHab
-
colour.ProLCHab_to_ProLab
-
colour.IPT_Ragoo2021_to_ICH_Ragoo2021
-
colour.ICH_Ragoo2021_to_IPT_Ragoo2021
* Now programmatically defined
colour.utilities
Port-Based Nodes and Graphs (#1277, @KelSolaar)
6 new classes were introduced to support for a port-based node-graph:
colour.utilities.Port
colour.utilities.PortNode
colour.utilities.PortGraph
colour.utilities.For
colour.utilities.ParallelForThread
colour.utilities.ParallelForMultiProcess
They enable the construction of processing graphs:
class NodeAdd(PortNode):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.description = "Perform the addition of the two input port values."
self.add_input_port("a")
self.add_input_port("b")
self.add_output_port("output")
def process(self):
a = self.get_input("a")
b = self.get_input("b")
if a is None or b is None:
return
self._output_ports["output"].value = a + b
self.dirty = False
class NodeMultiply(PortNode):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.description = (
"Perform the multiplication of the two input port values."
)
self.add_input_port("a")
self.add_input_port("b")
self.add_output_port("output")
def process(self):
a = self.get_input("a")
b = self.get_input("b")
if a is None or b is None:
return
self._output_ports["output"].value = a * b
self.dirty = False
node_add = NodeAdd()
node_add.set_input("a", 1)
node_add.set_input("b", 1)
node_multiply = NodeMultiply()
node_multiply.set_input("b", 2)
graph = PortGraph()
graph.add_node(node_add)
graph.add_node(node_multiply)
graph.connect(node_add, "output", node_multiply, "a")
graph.process()
print(node_multiply.get_output("output"))
graph.to_graphviz().draw("Graph.png", prog="dot")
colour-hdri uses the new classes to implement a multi-processed HDRI merging graph: https://github.com/colour-science/colour-hdri/blob/develop/colour_hdri/examples/examples_advanced_processing_with_an_input_device_transform.ipynb
Fixes
colour.colorimetry
- Fix issue where
colour.colorimetry.sds_and_msds_to_msds
definition did not always copy the converted spectral distributions and was causing seemingly random unit tests failure. (891d364, @KelSolaar) - Fix issue when passing a
colour.MultiSpectralDistributions
tocolour.sd_to_XYZ
definition using the ASTM E308 method. (20fb963, @KelSolaar, @gul916)
colour.io
- Ensure that
colour.io.process_image_OpenColorIO
definition handles non-contiguous arrays. (387c9e5, @nick-shaw, @KelSolaar)
colour.models
- Change Canon Cinema Gamut whitepoint to D55. (c25934e, @MrLixm, @KelSolaar)
colour.notation
- Reduce various thresholds in Munsell Renotation computations to allow sRGB colours to be converted. (#1173, 4b0c38d, @KelSolaar)
colour.utilities
- Ensure that caches are systematically cleared when changing dtype: It was causing seemingly random unit tests failure. (8faeb09, @KelSolaar)
Changes
colour.algebra
Object | Name | Author |
---|---|---|
colour.algebra.vector_dot
| vecmul
| @KelSolaar |
colour.plotting
Object | Signature | Author |
---|---|---|
colour.plotting.plot_RGB_colourspace_section
| plot_RGB_colourspace_section(colourspace: (RGB_Colourspace | LiteralRGBColourspace | str | Sequence[RGB_Colourspace | LiteralRGBColourspace | str]) ,model: LiteralColourspaceModel | str = "CIE xyY", axis: Literal["+z", "+x", "+y"] | str = "+z", origin: float = 0.5, normalise: bool = True,size: float = 1.0, show_section_colours: bool = True, show_section_contour: bool = True, segments: int = 64, **kwargs: Any) -> Tuple[Figure, Axes]
| @KelSolaar |
colour.utilities
- ~
colour.utilities.is_string
: (@KelSolaar)- Remove