Skip to content

Commit

Permalink
Merge branch 'feature/v0.4.3' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar committed Mar 6, 2023
2 parents 7e0a665 + 8d8f693 commit 2e38631
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 9 deletions.
2 changes: 1 addition & 1 deletion colour/appearance/hellwig2022.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ def colourfulness_correlate(
a = as_float_array(a)
b = as_float_array(b)

M = 43.0 * N_c * e_t * np.sqrt(a**2 + b**2)
M = 43.0 * N_c * e_t * np.hypot(a, b)

return M

Expand Down
2 changes: 1 addition & 1 deletion colour/appearance/kim2009.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def XYZ_to_Kim2009(

# Computing the correlate of *chroma* :math:`C`.
a_k, n_k = 456.5, 0.62
C = a_k * spow(np.sqrt(a**2 + b**2), n_k)
C = a_k * spow(np.hypot(a, b), n_k)

# Computing the correlate of *colourfulness* :math:`M`.
a_m, b_m = 0.11, 0.61
Expand Down
2 changes: 1 addition & 1 deletion colour/contrast/barten1999.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def sigma_Barten1999(
C_ab = as_float_array(C_ab)
d = as_float_array(d)

return as_float(np.sqrt(sigma_0**2 + (C_ab * d) ** 2))
return as_float(np.hypot(sigma_0, C_ab * d))


def retinal_illuminance_Barten1999(
Expand Down
2 changes: 1 addition & 1 deletion colour/models/din99.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def DIN99_to_Lab(

h_99 = np.arctan2(b_99, a_99) - np.radians(c_7)

C_99 = np.sqrt(a_99**2 + b_99**2)
C_99 = np.hypot(a_99, b_99)
G = np.expm1((c_8 / c_5) * C_99 * k_CH * k_E) / c_6

e = G * np.cos(h_99)
Expand Down
2 changes: 1 addition & 1 deletion colour/models/rgb/hanbury2003.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def RGB_to_IHLS(RGB: ArrayLike) -> NDArrayFloat:

Y, C_1, C_2 = tsplit(vector_dot(MATRIX_RGB_TO_YC_1_C_2, RGB))

C = np.sqrt(C_1**2 + C_2**2)
C = np.hypot(C_1, C_2)

with sdiv_mode():
C_1_C = sdiv(C_1, C)
Expand Down
143 changes: 139 additions & 4 deletions colour/plotting/temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
UCS_uv_to_xy,
XYZ_to_UCS,
xy_to_Luv_uv,
xy_to_UCS_uv,
xy_to_XYZ,
)
from colour.temperature import mired_to_CCT, CCT_to_uv
from colour.temperature import mired_to_CCT, CCT_to_uv, CCT_to_xy_CIE_D
from colour.plotting import (
CONSTANTS_COLOUR_STYLE,
CONSTANTS_ARROW_STYLE,
Expand Down Expand Up @@ -70,13 +71,148 @@
__status__ = "Production"

__all__ = [
"plot_daylight_locus",
"plot_planckian_locus",
"plot_planckian_locus_in_chromaticity_diagram",
"plot_planckian_locus_in_chromaticity_diagram_CIE1931",
"plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS",
]


@override_style()
def plot_daylight_locus(
daylight_locus_colours: ArrayLike | str | None = None,
daylight_locus_opacity: float = 1,
daylight_locus_use_mireds: bool = False,
method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"]
| str = "CIE 1931",
**kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
"""
Plot the *Daylight Locus* according to given method.
Parameters
----------
daylight_locus_colours
Colours of the *Daylight Locus*, if ``daylight_locus_colours`` is set
to *RGB*, the colours will be computed according to the corresponding
chromaticity coordinates.
daylight_locus_opacity
Opacity of the *Daylight Locus*.
daylight_locus_use_mireds
Whether to use micro reciprocal degrees for the iso-temperature lines.
method
*Chromaticity Diagram* method.
Other Parameters
----------------
kwargs
{:func:`colour.plotting.artist`, :func:`colour.plotting.render`},
See the documentation of the previously listed definitions.
Returns
-------
:class:`tuple`
Current figure and axes.
Examples
--------
>>> plot_daylight_locus(
... daylight_locus_colours="RGB",
... method="CIE 1960 UCS",
... )
... # doctest: +ELLIPSIS
(<Figure size ... with 1 Axes>, <...Axes...>)
.. image:: ../_static/Plotting_Plot_Daylight_Locus.png
:align: center
:alt: plot_daylight_locus
"""

method = validate_method(
method, ["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"]
)

daylight_locus_colours = optional(
daylight_locus_colours, CONSTANTS_COLOUR_STYLE.colour.dark
)

settings: Dict[str, Any] = {"uniform": True}
settings.update(kwargs)

_figure, axes = artist(**settings)

if method == "cie 1931":

def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat:
"""
Convert given *CIE xy* chromaticity coordinates to *ij*
chromaticity coordinates.
"""

return xy

elif method == "cie 1960 ucs":

def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat:
"""
Convert given *CIE xy* chromaticity coordinates to *ij*
chromaticity coordinates.
"""

return xy_to_UCS_uv(xy)

elif method == "cie 1976 ucs":

def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat:
"""
Convert given *CIE xy* chromaticity coordinates to *ij*
chromaticity coordinates.
"""

return xy_to_Luv_uv(xy)

def CCT_to_plotting_colourspace(CCT):
"""
Convert given correlated colour temperature :math:`T_{cp}` to the
default plotting colourspace.
"""

return normalise_maximum(
XYZ_to_plotting_colourspace(xy_to_XYZ(CCT_to_xy_CIE_D(CCT))),
axis=-1,
)

start, end = (
(0, 1000) if daylight_locus_use_mireds else (1e6 / 600, 1e6 / 10)
)

CCT = np.arange(start, end + 100, 10) * 1.4388 / 1.4380
CCT = mired_to_CCT(CCT) if daylight_locus_use_mireds else CCT
ij = xy_to_ij(CCT_to_xy_CIE_D(CCT)).reshape(-1, 1, 2)

use_RGB_daylight_locus_colours = (
str(daylight_locus_colours).upper() == "RGB"
)
if use_RGB_daylight_locus_colours:
pl_colours = CCT_to_plotting_colourspace(CCT)
else:
pl_colours = daylight_locus_colours

line_collection = LineCollection(
np.concatenate([ij[:-1], ij[1:]], axis=1),
colors=pl_colours,
alpha=daylight_locus_opacity,
zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line,
)
axes.add_collection(line_collection)

settings = {"axes": axes}
settings.update(kwargs)

return render(**settings)


@override_style()
def plot_planckian_locus(
planckian_locus_colours: ArrayLike | str | None = None,
Expand Down Expand Up @@ -128,7 +264,6 @@ def plot_planckian_locus(
>>> plot_planckian_locus(
... planckian_locus_colours="RGB",
... method="CIE 1960 UCS",
... use_mireds=True,
... )
... # doctest: +ELLIPSIS
(<Figure size ... with 1 Axes>, <...Axes...>)
Expand Down Expand Up @@ -194,8 +329,8 @@ def uv_to_ij(uv: NDArrayFloat) -> NDArrayFloat:

def CCT_D_uv_to_plotting_colourspace(CCT_D_uv):
"""
Convert given *uv* chromaticity coordinates to the default plotting
colourspace.
Convert given correlated colour temperature :math:`T_{cp}` and
:math:`\\Delta_{uv}` to the default plotting colourspace.
"""

return normalise_maximum(
Expand Down
34 changes: 34 additions & 0 deletions colour/plotting/tests/test_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS,
)
from colour.plotting.temperature import (
plot_daylight_locus,
plot_planckian_locus,
plot_planckian_locus_in_chromaticity_diagram,
)
Expand All @@ -21,13 +22,46 @@
__status__ = "Production"

__all__ = [
"TestPlotDaylightLocus",
"TestPlotPlanckianLocus",
"TestPlotPlanckianLocusInChromaticityDiagram",
"TestPlotPlanckianLocusInChromaticityDiagramCIE1931",
"TestPlotPlanckianLocusInChromaticityDiagramCIE1960UCS",
]


class TestPlotDaylightLocus(unittest.TestCase):
"""
Define :func:`colour.plotting.temperature.plot_daylight_locus` definition
unit tests methods.
"""

def test_plot_daylight_locus(self):
"""
Test :func:`colour.plotting.temperature.plot_daylight_locus`
definition.
"""

figure, axes = plot_daylight_locus()

self.assertIsInstance(figure, Figure)
self.assertIsInstance(axes, Axes)

self.assertRaises(
ValueError, lambda: plot_daylight_locus(method="Undefined")
)

figure, axes = plot_daylight_locus(method="CIE 1976 UCS")

self.assertIsInstance(figure, Figure)
self.assertIsInstance(axes, Axes)

figure, axes = plot_daylight_locus(planckian_locus_colours="RGB")

self.assertIsInstance(figure, Figure)
self.assertIsInstance(axes, Axes)


class TestPlotPlanckianLocus(unittest.TestCase):
"""
Define :func:`colour.plotting.temperature.plot_planckian_locus` definition
Expand Down
1 change: 1 addition & 0 deletions docs/colour.plotting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ Colour Temperature & Correlated Colour Temperature
.. autosummary::
:toctree: generated/

plot_daylight_locus
plot_planckian_locus
plot_planckian_locus_in_chromaticity_diagram

Expand Down
8 changes: 8 additions & 0 deletions utilities/generate_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
plot_hull_section_contour,
)
from colour.plotting.temperature import ( # noqa: E402
plot_daylight_locus,
plot_planckian_locus,
plot_planckian_locus_in_chromaticity_diagram,
)
Expand Down Expand Up @@ -909,6 +910,13 @@ def generate_documentation_plots(output_directory: str):
)[0]
)

arguments["filename"] = os.path.join(
output_directory, "Plotting_Plot_Daylight_Locus.png"
)
plt.close(
plot_daylight_locus(daylight_locus_colours="RGB", **arguments)[0]
)

arguments["filename"] = os.path.join(
output_directory, "Plotting_Plot_Planckian_Locus.png"
)
Expand Down

0 comments on commit 2e38631

Please sign in to comment.