예제 #1
0
파일: ohno2013.py 프로젝트: wenh06/colour
def _CCT_to_uv_Ohno2013(
        CCT_D_uv,
        cmfs=MSDS_CMFS_STANDARD_OBSERVER['CIE 1931 2 Degree Standard Observer']
):
    """
    Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}` and
    colour matching functions using *Ohno (2013)* method.

    Parameters
    ----------
    CCT_D_uv : ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.
    cmfs : XYZ_ColourMatchingFunctions, optional
        Standard observer colour matching functions.

    Returns
    -------
    ndarray
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    """

    CCT, D_uv = tsplit(CCT_D_uv)

    cmfs = cmfs.copy().trim(SPECTRAL_SHAPE_DEFAULT)

    shape = cmfs.shape

    delta = 0.01

    sd = sd_blackbody(CCT, shape)
    XYZ = sd_to_XYZ(sd, cmfs)
    XYZ *= 1 / np.max(XYZ)
    UVW = XYZ_to_UCS(XYZ)
    u0, v0 = UCS_to_uv(UVW)

    if D_uv == 0:
        return np.array([u0, v0])
    else:
        sd = sd_blackbody(CCT + delta, shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ *= 1 / np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        u1, v1 = UCS_to_uv(UVW)

        du = u0 - u1
        dv = v0 - v1

        u = u0 - D_uv * (dv / np.hypot(du, dv))
        v = v0 + D_uv * (du / np.hypot(du, dv))

        return np.array([u, v])
예제 #2
0
def _CCT_to_uv_Ohno2013(
        CCT_D_uv,
        cmfs=STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']):
    """
    Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}` and
    colour matching functions using *Ohno (2013)* method.

    Parameters
    ----------
    CCT_D_uv : ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.
    cmfs : XYZ_ColourMatchingFunctions, optional
        Standard observer colour matching functions.

    Returns
    -------
    ndarray
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    """

    CCT, D_uv = tsplit(CCT_D_uv)

    cmfs = cmfs.copy().trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape

    delta = 0.01

    sd = sd_blackbody(CCT, shape)
    XYZ = sd_to_XYZ(sd, cmfs)
    XYZ *= 1 / np.max(XYZ)
    UVW = XYZ_to_UCS(XYZ)
    u0, v0 = UCS_to_uv(UVW)

    if D_uv == 0:
        return np.array([u0, v0])
    else:
        sd = sd_blackbody(CCT + delta, shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ *= 1 / np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        u1, v1 = UCS_to_uv(UVW)

        du = u0 - u1
        dv = v0 - v1

        u = u0 - D_uv * (dv / np.hypot(du, dv))
        v = v0 + D_uv * (du / np.hypot(du, dv))

        return np.array([u, v])
예제 #3
0
def _CCT_to_uv_Ohno2013(
        CCT_D_uv: ArrayLike,
        cmfs: Optional[MultiSpectralDistributions] = None) -> NDArray:
    """
    Return the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}` and
    colour matching functions using *Ohno (2013)* method.

    Parameters
    ----------
    CCT_D_uv
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.
    cmfs
        Standard observer colour matching functions, default to the
        *CIE 1931 2 Degree Standard Observer*.

    Returns
    -------
    :class:`numpy.ndarray`
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    """

    CCT, D_uv = tsplit(CCT_D_uv)

    cmfs, _illuminant = handle_spectral_arguments(cmfs)

    delta = 0.01

    sd = sd_blackbody(CCT, cmfs.shape)
    XYZ = sd_to_XYZ(sd, cmfs)
    XYZ *= 1 / np.max(XYZ)
    UVW = XYZ_to_UCS(XYZ)
    u0, v0 = UCS_to_uv(UVW)

    if D_uv == 0:
        return np.array([u0, v0])
    else:
        sd = sd_blackbody(CCT + delta, cmfs.shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ *= 1 / np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        u1, v1 = UCS_to_uv(UVW)

        du = u0 - u1
        dv = v0 - v1

        u = u0 - D_uv * (dv / np.hypot(du, dv))
        v = v0 + D_uv * (du / np.hypot(du, dv))

        return np.array([u, v])
예제 #4
0
    def test_sd_reference_illuminant(self):
        """
        Tests :func:`colour.quality.CIE2017.sd_reference_illuminant`
        definition.
        """

        for sd, shape in [
            (SD_SAMPLE_5NM, SD_SAMPLE_5NM.shape),
            (SD_SAMPLE_1NM, SD_SAMPLE_1NM.shape),
        ]:
            CCT, _D_uv = CCT_reference_illuminant(sd)
            sd_reference = sd_reference_illuminant(CCT, shape)

            np.testing.assert_allclose(sd_reference.values,
                                       sd_blackbody(3288, shape).values,
                                       rtol=0.005)
예제 #5
0
def planckian_table(
    uv: ArrayLike,
    cmfs: MultiSpectralDistributions,
    start: Floating,
    end: Floating,
    count: Integer,
) -> List[PlanckianTableRow]:
    """
    Return a planckian table from given *CIE UCS* colourspace *uv*
    chromaticity coordinates, colour matching functions and temperature range
    using *Ohno (2013)* method.

    Parameters
    ----------
    uv
        *uv* chromaticity coordinates.
    cmfs
        Standard observer colour matching functions.
    start
        Temperature range start in kelvin degrees.
    end
        Temperature range end in kelvin degrees.
    count
        Temperatures count in the planckian table.

    Returns
    -------
    :class:`list`
        Planckian table.

    Examples
    --------
    >>> from colour import MSDS_CMFS, SPECTRAL_SHAPE_DEFAULT
    >>> cmfs = (
    ...     MSDS_CMFS['CIE 1931 2 Degree Standard Observer'].
    ...     copy().align(SPECTRAL_SHAPE_DEFAULT)
    ... )
    >>> uv = np.array([0.1978, 0.3122])
    >>> pprint(planckian_table(uv, cmfs, 1000, 1010, 10))
    ... # doctest: +SKIP
    [PlanckianTableRow(Ti=1000.0, ui=0.4479628..., \
vi=0.3546296..., di=0.2537355...),
     PlanckianTableRow(Ti=1001.1111111..., ui=0.4477030..., \
vi=0.3546521..., di=0.2534831...),
     PlanckianTableRow(Ti=1002.2222222..., ui=0.4474434..., \
vi=0.3546746..., di=0.2532310...),
     PlanckianTableRow(Ti=1003.3333333..., ui=0.4471842..., \
vi=0.3546970..., di=0.2529792...),
     PlanckianTableRow(Ti=1004.4444444..., ui=0.4469252..., \
vi=0.3547194..., di=0.2527277...),
     PlanckianTableRow(Ti=1005.5555555..., ui=0.4466666..., \
vi=0.3547417..., di=0.2524765...),
     PlanckianTableRow(Ti=1006.6666666..., ui=0.4464083..., \
vi=0.3547640..., di=0.2522256...),
     PlanckianTableRow(Ti=1007.7777777..., ui=0.4461502..., \
vi=0.3547862..., di=0.2519751...),
     PlanckianTableRow(Ti=1008.8888888..., ui=0.4458925..., \
vi=0.3548084..., di=0.2517248...),
     PlanckianTableRow(Ti=1010.0, ui=0.4456351..., \
vi=0.3548306..., di=0.2514749...)]
    """

    ux, vx = tsplit(uv)

    table = []
    for Ti in np.linspace(start, end, count):
        sd = sd_blackbody(Ti, cmfs.shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ /= np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        ui, vi = UCS_to_uv(UVW)
        di = np.hypot(ux - ui, vx - vi)
        table.append(PlanckianTableRow(Ti, ui, vi, di))

    return table
예제 #6
0
def colour_quality_scale(sd_test,
                         additional_data=False,
                         method='NIST CQS 9.0'):
    """
    Returns the *Colour Quality Scale* (CQS) of given spectral distribution
    using given method.

    Parameters
    ----------
    sd_test : SpectralDistribution
        Test spectral distribution.
    additional_data : bool, optional
        Whether to output additional data.
    method : unicode, optional
        **{'NIST CQS 9.0', 'NIST CQS 7.4'}**,
        Computation method.

    Returns
    -------
    numeric or CQS_Specification
        Color quality scale.

    References
    ----------
    :cite:`Davis2010a`, :cite:`Ohno2008a`, :cite:`Ohno2013`

    Examples
    --------
    >>> from colour import ILLUMINANTS_SDS
    >>> sd = ILLUMINANTS_SDS['FL2']
    >>> colour_quality_scale(sd)  # doctest: +ELLIPSIS
    64.0172835...
    """

    method = method.lower()
    assert method.lower() in [
        m.lower() for m in COLOUR_QUALITY_SCALE_METHODS
    ], ('"{0}" method is invalid, must be one of {1}!'.format(
        method, COLOUR_QUALITY_SCALE_METHODS))

    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy(
    ).trim(DEFAULT_SPECTRAL_SHAPE)

    shape = cmfs.shape
    sd_test = sd_test.copy().align(shape)
    vs_sds = {
        sd.name: sd.copy().align(shape)
        for sd in VS_SDS[method].values()
    }

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Ohno2013(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_vs_colorimetry_data = vs_colorimetry_data(sd_test,
                                                   sd_reference,
                                                   vs_sds,
                                                   cmfs,
                                                   chromatic_adaptation=True)

    reference_vs_colorimetry_data = vs_colorimetry_data(
        sd_reference, sd_reference, vs_sds, cmfs)

    if method == 'nist cqs 9.0':
        CCT_f = 1
        scaling_f = 3.2
    else:
        XYZ_r = sd_to_XYZ(sd_reference, cmfs)
        XYZ_r /= XYZ_r[1]
        CCT_f = CCT_factor(reference_vs_colorimetry_data, XYZ_r)
        scaling_f = 3.104

    Q_as = colour_quality_scales(test_vs_colorimetry_data,
                                 reference_vs_colorimetry_data, scaling_f,
                                 CCT_f)

    D_E_RMS = delta_E_RMS(Q_as, 'D_E_ab')
    D_Ep_RMS = delta_E_RMS(Q_as, 'D_Ep_ab')

    Q_a = scale_conversion(D_Ep_RMS, CCT_f, scaling_f)

    if method == 'nist cqs 9.0':
        scaling_f = 2.93 * 1.0343
    else:
        scaling_f = 2.928

    Q_f = scale_conversion(D_E_RMS, CCT_f, scaling_f)

    G_t = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in test_vs_colorimetry_data])
    G_r = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in reference_vs_colorimetry_data])

    Q_g = G_t / D65_GAMUT_AREA * 100

    if method == 'nist cqs 9.0':
        Q_d = Q_p = None
    else:
        p_delta_C = np.average([
            sample_data.D_C_ab if sample_data.D_C_ab > 0 else 0
            for sample_data in Q_as.values()
        ])
        Q_p = 100 - 3.6 * (D_Ep_RMS - p_delta_C)
        Q_d = G_t / G_r * CCT_f * 100

    if additional_data:
        return CQS_Specification(
            sd_test.name, Q_a, Q_f, Q_p, Q_g, Q_d, Q_as,
            (test_vs_colorimetry_data, reference_vs_colorimetry_data))
    else:
        return Q_a
예제 #7
0
def colour_quality_scale(sd_test, additional_data=False,
                         method='NIST CQS 9.0'):
    """
    Returns the *Colour Quality Scale* (CQS) of given spectral distribution
    using given method.

    Parameters
    ----------
    sd_test : SpectralDistribution
        Test spectral distribution.
    additional_data : bool, optional
        Whether to output additional data.
    method : unicode, optional
        **{'NIST CQS 9.0', 'NIST CQS 7.4'}**,
        Computation method.

    Returns
    -------
    numeric or CQS_Specification
        Color quality scale.

    References
    ----------
    :cite:`Davis2010a`, :cite:`Ohno2008a`, :cite:`Ohno2013`

    Examples
    --------
    >>> from colour import ILLUMINANTS_SDS
    >>> sd = ILLUMINANTS_SDS['FL2']
    >>> colour_quality_scale(sd)  # doctest: +ELLIPSIS
    64.0172835...
    """

    method = method.lower()
    assert method.lower() in [
        m.lower() for m in COLOUR_QUALITY_SCALE_METHODS
    ], ('"{0}" method is invalid, must be one of {1}!'.format(
        method, COLOUR_QUALITY_SCALE_METHODS))

    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy(
    ).trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape
    sd_test = sd_test.copy().align(shape)
    vs_sds = {
        sd.name: sd.copy().align(shape)
        for sd in VS_SDS[method].values()
    }

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Ohno2013(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_vs_colorimetry_data = vs_colorimetry_data(
        sd_test, sd_reference, vs_sds, cmfs, chromatic_adaptation=True)

    reference_vs_colorimetry_data = vs_colorimetry_data(
        sd_reference, sd_reference, vs_sds, cmfs)

    if method == 'nist cqs 9.0':
        CCT_f = 1
        scaling_f = 3.2
    else:
        XYZ_r = sd_to_XYZ(sd_reference, cmfs)
        XYZ_r /= XYZ_r[1]
        CCT_f = CCT_factor(reference_vs_colorimetry_data, XYZ_r)
        scaling_f = 3.104

    Q_as = colour_quality_scales(test_vs_colorimetry_data,
                                 reference_vs_colorimetry_data, scaling_f,
                                 CCT_f)

    D_E_RMS = delta_E_RMS(Q_as, 'D_E_ab')
    D_Ep_RMS = delta_E_RMS(Q_as, 'D_Ep_ab')

    Q_a = scale_conversion(D_Ep_RMS, CCT_f, scaling_f)

    if method == 'nist cqs 9.0':
        scaling_f = 2.93 * 1.0343
    else:
        scaling_f = 2.928

    Q_f = scale_conversion(D_E_RMS, CCT_f, scaling_f)

    G_t = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in test_vs_colorimetry_data])
    G_r = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in reference_vs_colorimetry_data])

    Q_g = G_t / D65_GAMUT_AREA * 100

    if method == 'nist cqs 9.0':
        Q_d = Q_p = None
    else:
        p_delta_C = np.average([
            sample_data.D_C_ab if sample_data.D_C_ab > 0 else 0
            for sample_data in Q_as.values()
        ])
        Q_p = 100 - 3.6 * (D_Ep_RMS - p_delta_C)
        Q_d = G_t / G_r * CCT_f * 100

    if additional_data:
        return CQS_Specification(
            sd_test.name, Q_a, Q_f, Q_p, Q_g, Q_d, Q_as,
            (test_vs_colorimetry_data, reference_vs_colorimetry_data))
    else:
        return Q_a
예제 #8
0
def colour_rendering_index(
    sd_test: SpectralDistribution, additional_data: Boolean = False
) -> Union[Floating, ColourRendering_Specification_CRI]:
    """
    Return the *Colour Rendering Index* (CRI) :math:`Q_a` of given spectral
    distribution.

    Parameters
    ----------
    sd_test
        Test spectral distribution.
    additional_data
        Whether to output additional data.

    Returns
    -------
    :class:`numpy.floating` or \
:class:`colour.quality.ColourRendering_Specification_CRI`
        *Colour Rendering Index* (CRI).

    References
    ----------
    :cite:`Ohno2008a`

    Examples
    --------
    >>> from colour import SDS_ILLUMINANTS
    >>> sd = SDS_ILLUMINANTS['FL2']
    >>> colour_rendering_index(sd)  # doctest: +ELLIPSIS
    64.2337241...
    """

    # pylint: disable=E1102
    cmfs = reshape_msds(
        MSDS_CMFS["CIE 1931 2 Degree Standard Observer"],
        SPECTRAL_SHAPE_DEFAULT,
    )

    shape = cmfs.shape
    sd_test = reshape_sd(sd_test, shape)
    tcs_sds = {sd.name: reshape_sd(sd, shape) for sd in SDS_TCS.values()}

    with domain_range_scale("1"):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Robertson1968(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_tcs_colorimetry_data = tcs_colorimetry_data(
        sd_test, sd_reference, tcs_sds, cmfs, chromatic_adaptation=True
    )

    reference_tcs_colorimetry_data = tcs_colorimetry_data(
        sd_reference, sd_reference, tcs_sds, cmfs
    )

    Q_as = colour_rendering_indexes(
        test_tcs_colorimetry_data, reference_tcs_colorimetry_data
    )

    Q_a = as_float_scalar(
        np.average(
            [v.Q_a for k, v in Q_as.items() if k in (1, 2, 3, 4, 5, 6, 7, 8)]
        )
    )

    if additional_data:
        return ColourRendering_Specification_CRI(
            sd_test.name,
            Q_a,
            Q_as,
            (test_tcs_colorimetry_data, reference_tcs_colorimetry_data),
        )
    else:
        return Q_a
예제 #9
0
def plot_blackbody_spectral_radiance(
    temperature: Floating = 3500,
    cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[
        MultiSpectralDistributions,
        str]], ] = "CIE 1931 2 Degree Standard Observer",
    blackbody: str = "VY Canis Major",
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot given blackbody spectral radiance.

    Parameters
    ----------
    temperature
        Blackbody temperature.
    cmfs
        Standard observer colour matching functions used for computing the
        spectrum domain and colours. ``cmfs`` can be of any type or form
        supported by the :func:`colour.plotting.filter_cmfs` definition.
    blackbody
        Blackbody name.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.plot_single_sd`,
        :func:`colour.plotting.render`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> plot_blackbody_spectral_radiance(3500, blackbody='VY Canis Major')
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 2 Axes>, <...AxesSubplot...>)

    .. image:: ../_static/Plotting_Plot_Blackbody_Spectral_Radiance.png
        :align: center
        :alt: plot_blackbody_spectral_radiance
    """

    figure = plt.figure()

    figure.subplots_adjust(hspace=CONSTANTS_COLOUR_STYLE.geometry.short / 2)

    cmfs = cast(MultiSpectralDistributions,
                first_item(filter_cmfs(cmfs).values()))

    sd = sd_blackbody(temperature, cmfs.shape)

    axes = figure.add_subplot(211)
    settings: Dict[str, Any] = {
        "axes": axes,
        "title": f"{blackbody} - Spectral Radiance",
        "y_label": "W / (sr m$^2$) / m",
    }
    settings.update(kwargs)
    settings["standalone"] = False

    plot_single_sd(sd, cmfs.name, **settings)

    axes = figure.add_subplot(212)

    with domain_range_scale("1"):
        XYZ = sd_to_XYZ(sd, cmfs)

    RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ))

    settings = {
        "axes": axes,
        "aspect": None,
        "title": f"{blackbody} - Colour",
        "x_label": f"{temperature}K",
        "y_label": "",
        "x_ticker": False,
        "y_ticker": False,
    }
    settings.update(kwargs)
    settings["standalone"] = False

    figure, axes = plot_single_colour_swatch(RGB, **settings)

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

    return render(**settings)
예제 #10
0
def sd_reference_illuminant(CCT: Floating,
                            shape: SpectralShape) -> SpectralDistribution:
    """
    Compute the reference illuminant for a given correlated colour temperature
    :math:`T_{cp}` for use in *CIE 2017 Colour Fidelity Index* (CFI)
    computation.

    Parameters
    ----------
    CCT
        Correlated colour temperature :math:`T_{cp}`.
    shape
        Desired shape of the returned spectral distribution.

    Returns
    -------
    :class:`colour.SpectralDistribution`
        Reference illuminant for *CIE 2017 Colour Fidelity Index* (CFI)
        computation.

    Examples
    --------
    >>> from colour.utilities import numpy_print_options
    >>> with numpy_print_options(suppress=True):
    ...     sd_reference_illuminant(  # doctest: +ELLIPSIS
    ...         4224.469705295263300, SpectralShape(380, 780, 20))
    SpectralDistribution([[ 380.        ,    0.0034089...],
                          [ 400.        ,    0.0044208...],
                          [ 420.        ,    0.0053260...],
                          [ 440.        ,    0.0062857...],
                          [ 460.        ,    0.0072767...],
                          [ 480.        ,    0.0080207...],
                          [ 500.        ,    0.0086590...],
                          [ 520.        ,    0.0092242...],
                          [ 540.        ,    0.0097686...],
                          [ 560.        ,    0.0101444...],
                          [ 580.        ,    0.0104475...],
                          [ 600.        ,    0.0107642...],
                          [ 620.        ,    0.0110439...],
                          [ 640.        ,    0.0112535...],
                          [ 660.        ,    0.0113922...],
                          [ 680.        ,    0.0115185...],
                          [ 700.        ,    0.0113155...],
                          [ 720.        ,    0.0108192...],
                          [ 740.        ,    0.0111582...],
                          [ 760.        ,    0.0101299...],
                          [ 780.        ,    0.0105638...]],
                         interpolator=SpragueInterpolator,
                         interpolator_kwargs={},
                         extrapolator=Extrapolator,
                         extrapolator_kwargs={...})
    """

    if CCT <= 5000:
        sd_planckian = sd_blackbody(CCT, shape)

    if CCT >= 4000:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_daylight = sd_CIE_illuminant_D_series(xy).align(shape)

    if CCT < 4000:
        sd_reference = sd_planckian
    elif 4000 <= CCT <= 5000:
        # Planckian and daylight illuminant must be normalised so that the
        # mixture isn't biased.
        sd_planckian /= sd_to_XYZ(sd_planckian)[1]  # type: ignore[misc]
        sd_daylight /= sd_to_XYZ(sd_daylight)[1]  # type: ignore[misc]

        # Mixture: 4200K should be 80% Planckian, 20% CIE Illuminant D Series.
        m = (CCT - 4000) / 1000
        values = linstep_function(m, sd_planckian.values, sd_daylight.values)
        name = (f"{as_int_scalar(CCT)}K "
                f"Blackbody & CIE Illuminant D Series Mixture - "
                f"{as_float_scalar(100 * m):.1f}%")
        sd_reference = SpectralDistribution(values, shape.range(), name=name)
    elif CCT > 5000:
        sd_reference = sd_daylight

    return sd_reference
예제 #11
0
파일: colorimetry.py 프로젝트: yixw/colour
def plot_blackbody_spectral_radiance(
        temperature=3500,
        cmfs='CIE 1931 2 Degree Standard Observer',
        blackbody='VY Canis Major',
        **kwargs):
    """
    Plots given blackbody spectral radiance.

    Parameters
    ----------
    temperature : numeric, optional
        Blackbody temperature.
    cmfs : unicode, optional
        Standard observer colour matching functions.
    blackbody : unicode, optional
        Blackbody name.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.plot_single_sd`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_blackbody_spectral_radiance(3500, blackbody='VY Canis Major')
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 2 Axes>, \
<matplotlib.axes._subplots.AxesSubplot object at 0x...>)

    .. image:: ../_static/Plotting_Plot_Blackbody_Spectral_Radiance.png
        :align: center
        :alt: plot_blackbody_spectral_radiance
    """

    figure = plt.figure()

    figure.subplots_adjust(hspace=COLOUR_STYLE_CONSTANTS.geometry.short / 2)

    cmfs = first_item(filter_cmfs(cmfs).values())

    sd = sd_blackbody(temperature, cmfs.shape)

    axes = figure.add_subplot(211)
    settings = {
        'axes': axes,
        'title': '{0} - Spectral Radiance'.format(blackbody),
        'y_label': 'W / (sr m$^2$) / m',
    }
    settings.update(kwargs)
    settings['standalone'] = False

    plot_single_sd(sd, cmfs.name, **settings)

    axes = figure.add_subplot(212)

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd, cmfs)

    RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ))

    settings = {
        'axes': axes,
        'aspect': None,
        'title': '{0} - Colour'.format(blackbody),
        'x_label': '{0}K'.format(temperature),
        'y_label': '',
        'x_ticker': False,
        'y_ticker': False,
    }
    settings.update(kwargs)
    settings['standalone'] = False

    figure, axes = plot_single_colour_swatch(ColourSwatch(name='', RGB=RGB),
                                             **settings)

    settings = {'axes': axes, 'standalone': True}
    settings.update(kwargs)

    return render(**settings)
예제 #12
0
def CCT_to_uv_Ohno2013(
        CCT,
        D_uv=0,
        cmfs=STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']):
    """
    Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}` and
    colour matching functions using *Ohno (2013)* method.

    Parameters
    ----------
    CCT : numeric
        Correlated colour temperature :math:`T_{cp}`.
    D_uv : numeric, optional
        :math:`\\Delta_{uv}`.
    cmfs : XYZ_ColourMatchingFunctions, optional
        Standard observer colour matching functions.

    Returns
    -------
    ndarray
        *CIE UCS* colourspace *uv* chromaticity coordinates.

    References
    ----------
    :cite:`Ohno2014a`

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> CCT = 6507.4342201047066
    >>> D_uv = 0.003223690901513
    >>> CCT_to_uv_Ohno2013(CCT, D_uv, cmfs)  # doctest: +ELLIPSIS
    array([ 0.1977999...,  0.3122004...])
    """

    cmfs = cmfs.copy().trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape

    delta = 0.01

    sd = sd_blackbody(CCT, shape)
    XYZ = sd_to_XYZ(sd, cmfs)
    XYZ *= 1 / np.max(XYZ)
    UVW = XYZ_to_UCS(XYZ)
    u0, v0 = UCS_to_uv(UVW)

    if D_uv == 0:
        return np.array([u0, v0])
    else:
        sd = sd_blackbody(CCT + delta, shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ *= 1 / np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        u1, v1 = UCS_to_uv(UVW)

        du = u0 - u1
        dv = v0 - v1

        u = u0 - D_uv * (dv / np.hypot(du, dv))
        v = v0 + D_uv * (du / np.hypot(du, dv))

        return np.array([u, v])
예제 #13
0
def planckian_table(uv, cmfs, start, end, count):
    """
    Returns a planckian table from given *CIE UCS* colourspace *uv*
    chromaticity coordinates, colour matching functions and temperature range
    using *Ohno (2013)* method.

    Parameters
    ----------
    uv : array_like
        *uv* chromaticity coordinates.
    cmfs : XYZ_ColourMatchingFunctions
        Standard observer colour matching functions.
    start : numeric
        Temperature range start in kelvins.
    end : numeric
        Temperature range end in kelvins.
    count : int
        Temperatures count in the planckian table.

    Returns
    -------
    list
        Planckian table.

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> from pprint import pprint
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> uv = np.array([0.1978, 0.3122])
    >>> pprint(planckian_table(uv, cmfs, 1000, 1010, 10))
    ... # doctest: +ELLIPSIS
    [PlanckianTable_Tuvdi(Ti=1000.0, \
ui=0.4479628..., vi=0.3546296..., di=0.2537355...),
     PlanckianTable_Tuvdi(Ti=1001.1111111..., \
ui=0.4477030..., vi=0.3546521..., di=0.2534831...),
     PlanckianTable_Tuvdi(Ti=1002.2222222..., \
ui=0.4474434..., vi=0.3546746..., di=0.2532310...),
     PlanckianTable_Tuvdi(Ti=1003.3333333..., \
ui=0.4471842..., vi=0.3546970..., di=0.2529792...),
     PlanckianTable_Tuvdi(Ti=1004.4444444..., \
ui=0.4469252..., vi=0.3547194..., di=0.2527277...),
     PlanckianTable_Tuvdi(Ti=1005.5555555..., \
ui=0.4466666..., vi=0.3547417..., di=0.2524765...),
     PlanckianTable_Tuvdi(Ti=1006.6666666..., \
ui=0.4464083..., vi=0.3547640..., di=0.2522256...),
     PlanckianTable_Tuvdi(Ti=1007.7777777..., \
ui=0.4461502..., vi=0.3547862..., di=0.2519751...),
     PlanckianTable_Tuvdi(Ti=1008.8888888..., \
ui=0.4458925..., vi=0.3548084..., di=0.2517248...),
     PlanckianTable_Tuvdi(Ti=1010.0, \
ui=0.4456351..., vi=0.3548306..., di=0.2514749...)]
    """

    ux, vx = uv

    cmfs = cmfs.copy().trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape

    table = []
    for Ti in np.linspace(start, end, count):
        sd = sd_blackbody(Ti, shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ /= np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        ui, vi = UCS_to_uv(UVW)
        di = np.hypot(ux - ui, vx - vi)
        table.append(PLANCKIAN_TABLE_TUVD(Ti, ui, vi, di))

    return table
예제 #14
0
def plot_blackbody_spectral_radiance(
        temperature=3500,
        cmfs='CIE 1931 2 Degree Standard Observer',
        blackbody='VY Canis Major',
        **kwargs):
    """
    Plots given blackbody spectral radiance.

    Parameters
    ----------
    temperature : numeric, optional
        Blackbody temperature.
    cmfs : unicode, optional
        Standard observer colour matching functions.
    blackbody : unicode, optional
        Blackbody name.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.plot_single_sd`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_blackbody_spectral_radiance(3500, blackbody='VY Canis Major')
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_Blackbody_Spectral_Radiance.png
        :align: center
        :alt: plot_blackbody_spectral_radiance
    """

    figure = plt.figure()

    figure.subplots_adjust(hspace=COLOUR_STYLE_CONSTANTS.geometry.short / 2)

    cmfs = first_item(filter_cmfs(cmfs).values())

    sd = sd_blackbody(temperature, cmfs.shape)

    axes = figure.add_subplot(211)
    settings = {
        'axes': axes,
        'title': '{0} - Spectral Radiance'.format(blackbody),
        'y_label': 'W / (sr m$^2$) / m',
    }
    settings.update(kwargs)
    settings['standalone'] = False

    plot_single_sd(sd, cmfs.name, **settings)

    axes = figure.add_subplot(212)

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd, cmfs)

    RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ))

    settings = {
        'axes': axes,
        'aspect': None,
        'title': '{0} - Colour'.format(blackbody),
        'x_label': '{0}K'.format(temperature),
        'y_label': '',
        'x_ticker': False,
        'y_ticker': False,
    }
    settings.update(kwargs)
    settings['standalone'] = False

    figure, axes = plot_single_colour_swatch(
        ColourSwatch(name='', RGB=RGB), **settings)

    settings = {'axes': axes, 'standalone': True}
    settings.update(kwargs)

    return render(**settings)
예제 #15
0
파일: ohno2013.py 프로젝트: wenh06/colour
def planckian_table(uv, cmfs, start, end, count):
    """
    Returns a planckian table from given *CIE UCS* colourspace *uv*
    chromaticity coordinates, colour matching functions and temperature range
    using *Ohno (2013)* method.

    Parameters
    ----------
    uv : array_like
        *uv* chromaticity coordinates.
    cmfs : XYZ_ColourMatchingFunctions
        Standard observer colour matching functions.
    start : numeric
        Temperature range start in kelvins.
    end : numeric
        Temperature range end in kelvins.
    count : int
        Temperatures count in the planckian table.

    Returns
    -------
    list
        Planckian table.

    Examples
    --------
    >>> from colour.colorimetry import (
    ...     SPECTRAL_SHAPE_DEFAULT, MSDS_CMFS_STANDARD_OBSERVER)
    >>> from pprint import pprint
    >>> cmfs = (
    ...     MSDS_CMFS_STANDARD_OBSERVER['CIE 1931 2 Degree Standard Observer'].
    ...     copy().align(SPECTRAL_SHAPE_DEFAULT)
    ... )
    >>> uv = np.array([0.1978, 0.3122])
    >>> pprint(planckian_table(uv, cmfs, 1000, 1010, 10))
    ... # doctest: +ELLIPSIS
    [PlanckianTable_Tuvdi(Ti=1000.0, \
ui=0.4479628..., vi=0.3546296..., di=0.2537355...),
     PlanckianTable_Tuvdi(Ti=1001.1111111..., \
ui=0.4477030..., vi=0.3546521..., di=0.2534831...),
     PlanckianTable_Tuvdi(Ti=1002.2222222..., \
ui=0.4474434..., vi=0.3546746..., di=0.2532310...),
     PlanckianTable_Tuvdi(Ti=1003.3333333..., \
ui=0.4471842..., vi=0.3546970..., di=0.2529792...),
     PlanckianTable_Tuvdi(Ti=1004.4444444..., \
ui=0.4469252..., vi=0.3547194..., di=0.2527277...),
     PlanckianTable_Tuvdi(Ti=1005.5555555..., \
ui=0.4466666..., vi=0.3547417..., di=0.2524765...),
     PlanckianTable_Tuvdi(Ti=1006.6666666..., \
ui=0.4464083..., vi=0.3547640..., di=0.2522256...),
     PlanckianTable_Tuvdi(Ti=1007.7777777..., \
ui=0.4461502..., vi=0.3547862..., di=0.2519751...),
     PlanckianTable_Tuvdi(Ti=1008.8888888..., \
ui=0.4458925..., vi=0.3548084..., di=0.2517248...),
     PlanckianTable_Tuvdi(Ti=1010.0, \
ui=0.4456351..., vi=0.3548306..., di=0.2514749...)]
    """

    ux, vx = uv

    cmfs = cmfs.copy().trim(SPECTRAL_SHAPE_DEFAULT)

    shape = cmfs.shape

    table = []
    for Ti in np.linspace(start, end, count):
        sd = sd_blackbody(Ti, shape)
        XYZ = sd_to_XYZ(sd, cmfs)
        XYZ /= np.max(XYZ)
        UVW = XYZ_to_UCS(XYZ)
        ui, vi = UCS_to_uv(UVW)
        di = np.hypot(ux - ui, vx - vi)
        table.append(PLANCKIAN_TABLE_TUVD(Ti, ui, vi, di))

    return table
예제 #16
0
def generate_documentation_plots(output_directory: str):
    """
    Generate documentation plots.

    Parameters
    ----------
    output_directory
        Output directory.
    """

    filter_warnings()

    colour_style()

    np.random.seed(0)

    # *************************************************************************
    # "README.rst"
    # *************************************************************************
    filename = os.path.join(
        output_directory, "Examples_Colour_Automatic_Conversion_Graph.png"
    )
    plot_automatic_colour_conversion_graph(filename)

    arguments = {
        "tight_layout": True,
        "transparent_background": True,
        "filename": os.path.join(
            output_directory, "Examples_Plotting_Visible_Spectrum.png"
        ),
    }
    plt.close(
        plot_visible_spectrum(
            "CIE 1931 2 Degree Standard Observer", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Illuminant_F1_SD.png"
    )
    plt.close(plot_single_illuminant_sd("FL1", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Blackbodies.png"
    )
    blackbody_sds = [
        sd_blackbody(i, SpectralShape(0, 10000, 10))
        for i in range(1000, 15000, 1000)
    ]
    plt.close(
        plot_multi_sds(
            blackbody_sds,
            y_label="W / (sr m$^2$) / m",
            plot_kwargs={"use_sd_colours": True, "normalise_sd_colours": True},
            legend_location="upper right",
            bounding_box=(0, 1250, 0, 2.5e6),
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Cone_Fundamentals.png"
    )
    plt.close(
        plot_single_cmfs(
            "Stockman & Sharpe 2 Degree Cone Fundamentals",
            y_label="Sensitivity",
            bounding_box=(390, 870, 0, 1.1),
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Luminous_Efficiency.png"
    )
    plt.close(
        plot_multi_sds(
            (
                sd_mesopic_luminous_efficiency_function(0.2),
                SDS_LEFS_PHOTOPIC["CIE 1924 Photopic Standard Observer"],
                SDS_LEFS_SCOTOPIC["CIE 1951 Scotopic Standard Observer"],
            ),
            y_label="Luminous Efficiency",
            legend_location="upper right",
            y_tighten=True,
            margins=(0, 0, 0, 0.1),
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_BabelColor_Average.png"
    )
    plt.close(
        plot_multi_sds(
            SDS_COLOURCHECKERS["BabelColor Average"].values(),
            plot_kwargs={"use_sd_colours": True},
            title=("BabelColor Average - " "Spectral Distributions"),
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_ColorChecker_2005.png"
    )
    plt.close(
        plot_single_colour_checker(
            "ColorChecker 2005", text_kwargs={"visible": False}, **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Chromaticities_Prediction.png"
    )
    plt.close(
        plot_corresponding_chromaticities_prediction(
            2, "Von Kries", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Examples_Plotting_Chromaticities_CIE_1931_Chromaticity_Diagram.png",
    )
    RGB = np.random.random((32, 32, 3))
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931(
            RGB,
            "ITU-R BT.709",
            colourspaces=["ACEScg", "S-Gamut"],
            show_pointer_gamut=True,
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_CRI.png"
    )
    plt.close(
        plot_single_sd_colour_rendering_index_bars(
            SDS_ILLUMINANTS["FL2"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Colour_Rendition_Report.png"
    )
    plt.close(
        plot_single_sd_colour_rendition_report(
            SDS_ILLUMINANTS["FL2"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Plot_Visible_Spectrum_Section.png"
    )
    plt.close(
        plot_visible_spectrum_section(
            section_colours="RGB", section_opacity=0.15, **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Examples_Plotting_Plot_RGB_Colourspace_Section.png"
    )
    plt.close(
        plot_RGB_colourspace_section(
            "sRGB", section_colours="RGB", section_opacity=0.15, **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Examples_Plotting_CCT_CIE_1960_UCS_Chromaticity_Diagram.png",
    )
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(
            ["A", "B", "C"], **arguments
        )[0]
    )

    # *************************************************************************
    # Documentation
    # *************************************************************************
    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_CVD_Simulation_Machado2009.png"
    )
    plt.close(plot_cvd_simulation_Machado2009(RGB, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Colour_Checker.png"
    )
    plt.close(plot_single_colour_checker("ColorChecker 2005", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Colour_Checkers.png"
    )
    plt.close(
        plot_multi_colour_checkers(
            ["ColorChecker 1976", "ColorChecker 2005"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_SD.png"
    )
    data = {
        500: 0.0651,
        520: 0.0705,
        540: 0.0772,
        560: 0.0870,
        580: 0.1128,
        600: 0.1360,
    }
    sd = SpectralDistribution(data, name="Custom")
    plt.close(plot_single_sd(sd, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_SDS.png"
    )
    data_1 = {
        500: 0.004900,
        510: 0.009300,
        520: 0.063270,
        530: 0.165500,
        540: 0.290400,
        550: 0.433450,
        560: 0.594500,
    }
    data_2 = {
        500: 0.323000,
        510: 0.503000,
        520: 0.710000,
        530: 0.862000,
        540: 0.954000,
        550: 0.994950,
        560: 0.995000,
    }
    spd1 = SpectralDistribution(data_1, name="Custom 1")
    spd2 = SpectralDistribution(data_2, name="Custom 2")
    plt.close(plot_multi_sds([spd1, spd2], **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_CMFS.png"
    )
    plt.close(
        plot_single_cmfs("CIE 1931 2 Degree Standard Observer", **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_CMFS.png"
    )
    cmfs = (
        "CIE 1931 2 Degree Standard Observer",
        "CIE 1964 10 Degree Standard Observer",
    )
    plt.close(plot_multi_cmfs(cmfs, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Illuminant_SD.png"
    )
    plt.close(plot_single_illuminant_sd("A", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Illuminant_SDS.png"
    )
    plt.close(plot_multi_illuminant_sds(["A", "B", "C"], **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Visible_Spectrum.png"
    )
    plt.close(plot_visible_spectrum(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Lightness_Function.png"
    )
    plt.close(plot_single_lightness_function("CIE 1976", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Lightness_Functions.png"
    )
    plt.close(
        plot_multi_lightness_functions(
            ["CIE 1976", "Wyszecki 1963"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Luminance_Function.png"
    )
    plt.close(plot_single_luminance_function("CIE 1976", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Luminance_Functions.png"
    )
    plt.close(
        plot_multi_luminance_functions(
            ["CIE 1976", "Newhall 1943"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Blackbody_Spectral_Radiance.png"
    )
    plt.close(
        plot_blackbody_spectral_radiance(
            3500, blackbody="VY Canis Major", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Blackbody_Colours.png"
    )
    plt.close(
        plot_blackbody_colours(SpectralShape(150, 12500, 50), **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Colour_Swatch.png"
    )
    RGB = ColourSwatch((0.45620519, 0.03081071, 0.04091952))
    plt.close(plot_single_colour_swatch(RGB, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Colour_Swatches.png"
    )
    RGB_1 = ColourSwatch((0.45293517, 0.31732158, 0.26414773))
    RGB_2 = ColourSwatch((0.77875824, 0.57726450, 0.50453169))
    plt.close(plot_multi_colour_swatches([RGB_1, RGB_2], **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Function.png"
    )
    plt.close(plot_single_function(lambda x: x ** (1 / 2.2), **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Functions.png"
    )
    functions = {
        "Gamma 2.2": lambda x: x ** (1 / 2.2),
        "Gamma 2.4": lambda x: x ** (1 / 2.4),
        "Gamma 2.6": lambda x: x ** (1 / 2.6),
    }
    plt.close(plot_multi_functions(functions, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Image.png"
    )
    path = os.path.join(
        colour.__path__[0],
        "examples",
        "plotting",
        "resources",
        "Ishihara_Colour_Blindness_Test_Plate_3.png",
    )
    plt.close(plot_image(read_image(str(path)), **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Corresponding_Chromaticities_Prediction.png",
    )
    plt.close(
        plot_corresponding_chromaticities_prediction(
            1, "Von Kries", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Spectral_Locus.png"
    )
    plt.close(
        plot_spectral_locus(spectral_locus_colours="RGB", **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Chromaticity_Diagram_Colours.png"
    )
    plt.close(
        plot_chromaticity_diagram_colours(diagram_colours="RGB", **arguments)[
            0
        ]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Chromaticity_Diagram.png"
    )
    plt.close(plot_chromaticity_diagram(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Chromaticity_Diagram_CIE1931.png"
    )
    plt.close(plot_chromaticity_diagram_CIE1931(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Chromaticity_Diagram_CIE1960UCS.png"
    )
    plt.close(plot_chromaticity_diagram_CIE1960UCS(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Chromaticity_Diagram_CIE1976UCS.png"
    )
    plt.close(plot_chromaticity_diagram_CIE1976UCS(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_SDS_In_Chromaticity_Diagram.png"
    )
    A = SDS_ILLUMINANTS["A"]
    D65 = SDS_ILLUMINANTS["D65"]
    plt.close(plot_sds_in_chromaticity_diagram([A, D65], **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1931.png",
    )
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1931([A, D65], **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1960UCS.png",
    )
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1960UCS([A, D65], **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1976UCS.png",
    )
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1976UCS([A, D65], **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Pointer_Gamut.png"
    )
    plt.close(plot_pointer_gamut(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Colourspaces_In_Chromaticity_Diagram.png",
    )
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Colourspaces_In_Chromaticity_Diagram_CIE1931.png",
    )
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Colourspaces_In_"
        "Chromaticity_Diagram_CIE1960UCS.png",
    )
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Colourspaces_In_"
        "Chromaticity_Diagram_CIE1976UCS.png",
    )
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Chromaticities_In_" "Chromaticity_Diagram.png",
    )
    RGB = np.random.random((128, 128, 3))
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram(
            RGB, "ITU-R BT.709", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Chromaticities_In_"
        "Chromaticity_Diagram_CIE1931.png",
    )
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931(
            RGB, "ITU-R BT.709", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Chromaticities_In_"
        "Chromaticity_Diagram_CIE1960UCS.png",
    )
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1960UCS(
            RGB, "ITU-R BT.709", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_RGB_Chromaticities_In_"
        "Chromaticity_Diagram_CIE1976UCS.png",
    )
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1976UCS(
            RGB, "ITU-R BT.709", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png",
    )
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram(**arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Ellipses_MacAdam1942_In_"
        "Chromaticity_Diagram_CIE1931.png",
    )
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1931(**arguments)[
            0
        ]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Ellipses_MacAdam1942_In_"
        "Chromaticity_Diagram_CIE1960UCS.png",
    )
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1960UCS(
            **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Ellipses_MacAdam1942_In_"
        "Chromaticity_Diagram_CIE1976UCS.png",
    )
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS(
            **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_CCTF.png"
    )
    plt.close(plot_single_cctf("ITU-R BT.709", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_CCTFs.png"
    )
    plt.close(plot_multi_cctfs(["ITU-R BT.709", "sRGB"], **arguments)[0])

    data = np.array(
        [
            [
                None,
                np.array([0.95010000, 1.00000000, 1.08810000]),
                np.array([0.40920000, 0.28120000, 0.30600000]),
                np.array(
                    [
                        [0.02495100, 0.01908600, 0.02032900],
                        [0.10944300, 0.06235900, 0.06788100],
                        [0.27186500, 0.18418700, 0.19565300],
                        [0.48898900, 0.40749400, 0.44854600],
                    ]
                ),
                None,
            ],
            [
                None,
                np.array([0.95010000, 1.00000000, 1.08810000]),
                np.array([0.30760000, 0.48280000, 0.42770000]),
                np.array(
                    [
                        [0.02108000, 0.02989100, 0.02790400],
                        [0.06194700, 0.11251000, 0.09334400],
                        [0.15255800, 0.28123300, 0.23234900],
                        [0.34157700, 0.56681300, 0.47035300],
                    ]
                ),
                None,
            ],
            [
                None,
                np.array([0.95010000, 1.00000000, 1.08810000]),
                np.array([0.39530000, 0.28120000, 0.18450000]),
                np.array(
                    [
                        [0.02436400, 0.01908600, 0.01468800],
                        [0.10331200, 0.06235900, 0.02854600],
                        [0.26311900, 0.18418700, 0.12109700],
                        [0.43158700, 0.40749400, 0.39008600],
                    ]
                ),
                None,
            ],
            [
                None,
                np.array([0.95010000, 1.00000000, 1.08810000]),
                np.array([0.20510000, 0.18420000, 0.57130000]),
                np.array(
                    [
                        [0.03039800, 0.02989100, 0.06123300],
                        [0.08870000, 0.08498400, 0.21843500],
                        [0.18405800, 0.18418700, 0.40111400],
                        [0.32550100, 0.34047200, 0.50296900],
                        [0.53826100, 0.56681300, 0.80010400],
                    ]
                ),
                None,
            ],
            [
                None,
                np.array([0.95010000, 1.00000000, 1.08810000]),
                np.array([0.35770000, 0.28120000, 0.11250000]),
                np.array(
                    [
                        [0.03678100, 0.02989100, 0.01481100],
                        [0.17127700, 0.11251000, 0.01229900],
                        [0.30080900, 0.28123300, 0.21229800],
                        [0.52976000, 0.40749400, 0.11720000],
                    ]
                ),
                None,
            ],
        ]
    )
    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Constant_Hue_Loci.png"
    )
    plt.close(plot_constant_hue_loci(data, "IPT", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_Munsell_Value_Function.png"
    )
    plt.close(plot_single_munsell_value_function("ASTM D1535", **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Multi_Munsell_Value_Functions.png"
    )
    plt.close(
        plot_multi_munsell_value_functions(
            ["ASTM D1535", "McCamy 1987"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Single_SD_Rayleigh_Scattering.png"
    )
    plt.close(plot_single_sd_rayleigh_scattering(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_The_Blue_Sky.png"
    )
    plt.close(plot_the_blue_sky(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Colour_Quality_Bars.png"
    )
    illuminant = SDS_ILLUMINANTS["FL2"]
    light_source = SDS_LIGHT_SOURCES["Kinoton 75P"]
    light_source = light_source.copy().align(SpectralShape(360, 830, 1))
    cqs_i = colour_quality_scale(illuminant, additional_data=True)
    cqs_l = colour_quality_scale(light_source, additional_data=True)
    plt.close(plot_colour_quality_bars([cqs_i, cqs_l], **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Single_SD_Colour_Rendering_Index_Bars.png",
    )
    illuminant = SDS_ILLUMINANTS["FL2"]
    plt.close(
        plot_single_sd_colour_rendering_index_bars(illuminant, **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Multi_SDS_Colour_Rendering_Indexes_Bars.png",
    )
    light_source = SDS_LIGHT_SOURCES["Kinoton 75P"]
    plt.close(
        plot_multi_sds_colour_rendering_indexes_bars(
            [illuminant, light_source], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Single_SD_Colour_Quality_Scale_Bars.png",
    )
    illuminant = SDS_ILLUMINANTS["FL2"]
    plt.close(
        plot_single_sd_colour_quality_scale_bars(illuminant, **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Multi_SDS_Colour_Quality_Scales_Bars.png",
    )
    light_source = SDS_LIGHT_SOURCES["Kinoton 75P"]
    plt.close(
        plot_multi_sds_colour_quality_scales_bars(
            [illuminant, light_source], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Hull_Section_Colours.png"
    )
    vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
    XYZ_vertices = RGB_to_XYZ(
        vertices["position"] + 0.5,
        RGB_COLOURSPACE_sRGB.whitepoint,
        RGB_COLOURSPACE_sRGB.whitepoint,
        RGB_COLOURSPACE_sRGB.matrix_RGB_to_XYZ,
    )
    hull = trimesh.Trimesh(XYZ_vertices, faces, process=False)
    plt.close(
        plot_hull_section_colours(hull, section_colours="RGB", **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Hull_Section_Contour.png"
    )
    plt.close(
        plot_hull_section_contour(hull, section_colours="RGB", **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Visible_Spectrum_Section.png"
    )
    plt.close(
        plot_visible_spectrum_section(
            section_colours="RGB", section_opacity=0.15, **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_RGB_Colourspace_Section.png"
    )
    plt.close(
        plot_RGB_colourspace_section(
            "sRGB", section_colours="RGB", section_opacity=0.15, **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_Planckian_Locus.png"
    )
    plt.close(
        plot_planckian_locus(planckian_locus_colours="RGB", **arguments)[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram.png",
    )
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram(
            ["A", "B", "C"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram_CIE1931.png",
    )
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1931(
            ["A", "B", "C"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram_CIE1960UCS.png",
    )
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(
            ["A", "B", "C"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Single_SD_Colour_Rendition_Report_Full.png",
    )
    plt.close(
        plot_single_sd_colour_rendition_report(
            SDS_ILLUMINANTS["FL2"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Single_SD_Colour_Rendition_Report_Intermediate.png",
    )
    plt.close(
        plot_single_sd_colour_rendition_report(
            SDS_ILLUMINANTS["FL2"], "Intermediate", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory,
        "Plotting_Plot_Single_SD_Colour_Rendition_Report_Simple.png",
    )
    plt.close(
        plot_single_sd_colour_rendition_report(
            SDS_ILLUMINANTS["FL2"], "Simple", **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_RGB_Colourspaces_Gamuts.png"
    )
    plt.close(
        plot_RGB_colourspaces_gamuts(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_RGB_Colourspaces_Gamuts.png"
    )
    plt.close(
        plot_RGB_colourspaces_gamuts(
            ["ITU-R BT.709", "ACEScg", "S-Gamut"], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Plotting_Plot_RGB_Scatter.png"
    )
    plt.close(plot_RGB_scatter(RGB, "ITU-R BT.709", **arguments)[0])

    filename = os.path.join(
        output_directory, "Plotting_Plot_Colour_Automatic_Conversion_Graph.png"
    )
    plot_automatic_colour_conversion_graph(filename)

    # *************************************************************************
    # "tutorial.rst"
    # *************************************************************************
    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_Visible_Spectrum.png"
    )
    plt.close(plot_visible_spectrum(**arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_Sample_SD.png"
    )
    sample_sd_data = {
        380: 0.048,
        385: 0.051,
        390: 0.055,
        395: 0.060,
        400: 0.065,
        405: 0.068,
        410: 0.068,
        415: 0.067,
        420: 0.064,
        425: 0.062,
        430: 0.059,
        435: 0.057,
        440: 0.055,
        445: 0.054,
        450: 0.053,
        455: 0.053,
        460: 0.052,
        465: 0.052,
        470: 0.052,
        475: 0.053,
        480: 0.054,
        485: 0.055,
        490: 0.057,
        495: 0.059,
        500: 0.061,
        505: 0.062,
        510: 0.065,
        515: 0.067,
        520: 0.070,
        525: 0.072,
        530: 0.074,
        535: 0.075,
        540: 0.076,
        545: 0.078,
        550: 0.079,
        555: 0.082,
        560: 0.087,
        565: 0.092,
        570: 0.100,
        575: 0.107,
        580: 0.115,
        585: 0.122,
        590: 0.129,
        595: 0.134,
        600: 0.138,
        605: 0.142,
        610: 0.146,
        615: 0.150,
        620: 0.154,
        625: 0.158,
        630: 0.163,
        635: 0.167,
        640: 0.173,
        645: 0.180,
        650: 0.188,
        655: 0.196,
        660: 0.204,
        665: 0.213,
        670: 0.222,
        675: 0.231,
        680: 0.242,
        685: 0.251,
        690: 0.261,
        695: 0.271,
        700: 0.282,
        705: 0.294,
        710: 0.305,
        715: 0.318,
        720: 0.334,
        725: 0.354,
        730: 0.372,
        735: 0.392,
        740: 0.409,
        745: 0.420,
        750: 0.436,
        755: 0.450,
        760: 0.462,
        765: 0.465,
        770: 0.448,
        775: 0.432,
        780: 0.421,
    }

    sd = SpectralDistribution(sample_sd_data, name="Sample")
    plt.close(plot_single_sd(sd, **arguments)[0])

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_SD_Interpolation.png"
    )
    sd_copy = sd.copy()
    sd_copy.interpolate(SpectralShape(400, 770, 1))
    plt.close(
        plot_multi_sds(
            [sd, sd_copy], bounding_box=[730, 780, 0.25, 0.5], **arguments
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_Sample_Swatch.png"
    )
    sd = SpectralDistribution(sample_sd_data)
    cmfs = MSDS_CMFS_STANDARD_OBSERVER["CIE 1931 2 Degree Standard Observer"]
    illuminant = SDS_ILLUMINANTS["D65"]
    with domain_range_scale("1"):
        XYZ = sd_to_XYZ(sd, cmfs, illuminant)
        RGB = XYZ_to_sRGB(XYZ)
    plt.close(
        plot_single_colour_swatch(
            ColourSwatch(RGB, "Sample"),
            text_kwargs={"size": "x-large"},
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_Neutral5.png"
    )
    patch_name = "neutral 5 (.70 D)"
    patch_sd = SDS_COLOURCHECKERS["ColorChecker N Ohta"][patch_name]
    with domain_range_scale("1"):
        XYZ = sd_to_XYZ(patch_sd, cmfs, illuminant)
        RGB = XYZ_to_sRGB(XYZ)
    plt.close(
        plot_single_colour_swatch(
            ColourSwatch(RGB, patch_name.title()),
            text_kwargs={"size": "x-large"},
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_Colour_Checker.png"
    )
    plt.close(
        plot_single_colour_checker(
            colour_checker="ColorChecker 2005",
            text_kwargs={"visible": False},
            **arguments,
        )[0]
    )

    arguments["filename"] = os.path.join(
        output_directory, "Tutorial_CIE_1931_Chromaticity_Diagram.png"
    )
    xy = XYZ_to_xy(XYZ)
    plot_chromaticity_diagram_CIE1931(standalone=False)
    x, y = xy
    plt.plot(x, y, "o-", color="white")
    # Annotating the plot.
    plt.annotate(
        patch_sd.name.title(),
        xy=xy,
        xytext=(-50, 30),
        textcoords="offset points",
        arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=-0.2"),
    )
    plt.close(
        render(
            standalone=True,
            limits=(-0.1, 0.9, -0.1, 0.9),
            x_tighten=True,
            y_tighten=True,
            **arguments,
        )[0]
    )

    # *************************************************************************
    # "basics.rst"
    # *************************************************************************
    arguments["filename"] = os.path.join(
        output_directory, "Basics_Logo_Small_001_CIE_XYZ.png"
    )
    RGB = read_image(os.path.join(output_directory, "Logo_Small_001.png"))[
        ..., 0:3
    ]
    XYZ = sRGB_to_XYZ(RGB)
    plt.close(
        plot_image(XYZ, text_kwargs={"text": "sRGB to XYZ"}, **arguments)[0]
    )
예제 #17
0
파일: cqs.py 프로젝트: Munins-eye/colour
def colour_quality_scale(sd_test, additional_data=False):
    """
    Returns the *Colour Quality Scale* (CQS) of given spectral
    distribution.

    Parameters
    ----------
    sd_test : SpectralDistribution
        Test spectral distribution.
    additional_data : bool, optional
        Whether to output additional data.

    Returns
    -------
    numeric or CQS_Specification
        Color quality scale.

    References
    ----------
    :cite:`Davis2010a`, :cite:`Ohno2008a`

    Examples
    --------
    >>> from colour import ILLUMINANTS_SDS
    >>> sd = ILLUMINANTS_SDS['FL2']
    >>> colour_quality_scale(sd)  # doctest: +ELLIPSIS
    64.6863391...
    """

    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy(
    ).trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape
    sd_test = sd_test.copy().align(shape)
    vs_sds = {sd.name: sd.copy().align(shape) for sd in VS_SDS.values()}

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Ohno2013(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_vs_colorimetry_data = vs_colorimetry_data(sd_test,
                                                   sd_reference,
                                                   vs_sds,
                                                   cmfs,
                                                   chromatic_adaptation=True)

    reference_vs_colorimetry_data = vs_colorimetry_data(
        sd_reference, sd_reference, vs_sds, cmfs)

    XYZ_r = sd_to_XYZ(sd_reference, cmfs)
    XYZ_r /= XYZ_r[1]
    CCT_f = CCT_factor(reference_vs_colorimetry_data, XYZ_r)

    Q_as = colour_quality_scales(test_vs_colorimetry_data,
                                 reference_vs_colorimetry_data, CCT_f)

    D_E_RMS = delta_E_RMS(Q_as, 'D_E_ab')
    D_Ep_RMS = delta_E_RMS(Q_as, 'D_Ep_ab')

    Q_a = scale_conversion(D_Ep_RMS, CCT_f)
    Q_f = scale_conversion(D_E_RMS, CCT_f, 2.928)

    p_delta_C = np.average(
        [sample_data.D_C_ab if sample_data.D_C_ab > 0 else 0
         for sample_data in Q_as.values()])  # yapf: disable
    Q_p = 100 - 3.6 * (D_Ep_RMS - p_delta_C)

    G_t = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in test_vs_colorimetry_data])
    G_r = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in reference_vs_colorimetry_data])

    Q_g = G_t / D65_GAMUT_AREA * 100
    Q_d = G_t / G_r * CCT_f * 100

    if additional_data:
        return CQS_Specification(
            sd_test.name, Q_a, Q_f, Q_p, Q_g, Q_d, Q_as,
            (test_vs_colorimetry_data, reference_vs_colorimetry_data))
    else:
        return Q_a
예제 #18
0
def generate_documentation_plots(output_directory):
    """
    Generates documentation plots.

    Parameters
    ----------
    output_directory : unicode
        Output directory.
    """

    filter_warnings()

    colour_style()

    np.random.seed(0)

    # *************************************************************************
    # "README.rst"
    # *************************************************************************
    filename = os.path.join(output_directory,
                            'Examples_Colour_Automatic_Conversion_Graph.png')
    plot_automatic_colour_conversion_graph(filename)

    arguments = {
        'tight_layout':
        True,
        'transparent_background':
        True,
        'filename':
        os.path.join(output_directory,
                     'Examples_Plotting_Visible_Spectrum.png')
    }
    plt.close(
        plot_visible_spectrum('CIE 1931 2 Degree Standard Observer',
                              **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_Illuminant_F1_SD.png')
    plt.close(plot_single_illuminant_sd('FL1', **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Examples_Plotting_Blackbodies.png')
    blackbody_sds = [
        sd_blackbody(i, SpectralShape(0, 10000, 10))
        for i in range(1000, 15000, 1000)
    ]
    plt.close(
        plot_multi_sds(blackbody_sds,
                       y_label='W / (sr m$^2$) / m',
                       use_sds_colours=True,
                       normalise_sds_colours=True,
                       legend_location='upper right',
                       bounding_box=(0, 1250, 0, 2.5e15),
                       **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_Cone_Fundamentals.png')
    plt.close(
        plot_single_cmfs('Stockman & Sharpe 2 Degree Cone Fundamentals',
                         y_label='Sensitivity',
                         bounding_box=(390, 870, 0, 1.1),
                         **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_Luminous_Efficiency.png')
    plt.close(
        plot_multi_sds((sd_mesopic_luminous_efficiency_function(0.2),
                        PHOTOPIC_LEFS['CIE 1924 Photopic Standard Observer'],
                        SCOTOPIC_LEFS['CIE 1951 Scotopic Standard Observer']),
                       y_label='Luminous Efficiency',
                       legend_location='upper right',
                       y_tighten=True,
                       margins=(0, 0, 0, .1),
                       **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_BabelColor_Average.png')
    plt.close(
        plot_multi_sds(COLOURCHECKERS_SDS['BabelColor Average'].values(),
                       use_sds_colours=True,
                       title=('BabelColor Average - '
                              'Spectral Distributions'),
                       **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_ColorChecker_2005.png')
    plt.close(
        plot_single_colour_checker('ColorChecker 2005',
                                   text_parameters={'visible': False},
                                   **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Examples_Plotting_Chromaticities_Prediction.png')
    plt.close(
        plot_corresponding_chromaticities_prediction(2, 'Von Kries', 'Bianco',
                                                     **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Examples_Plotting_CCT_CIE_1960_UCS_Chromaticity_Diagram.png')
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(
            ['A', 'B', 'C'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Examples_Plotting_Chromaticities_CIE_1931_Chromaticity_Diagram.png')
    RGB = np.random.random((32, 32, 3))
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931(
            RGB,
            'ITU-R BT.709',
            colourspaces=['ACEScg', 'S-Gamut'],
            show_pointer_gamut=True,
            **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Examples_Plotting_CRI.png')
    plt.close(
        plot_single_sd_colour_rendering_index_bars(ILLUMINANTS_SDS['FL2'],
                                                   **arguments)[0])

    # *************************************************************************
    # Documentation
    # *************************************************************************
    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_CVD_Simulation_Machado2009.png')
    plt.close(plot_cvd_simulation_Machado2009(RGB, **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Colour_Checker.png')
    plt.close(plot_single_colour_checker('ColorChecker 2005', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Colour_Checkers.png')
    plt.close(
        plot_multi_colour_checkers(['ColorChecker 1976', 'ColorChecker 2005'],
                                   **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Single_SD.png')
    data = {
        500: 0.0651,
        520: 0.0705,
        540: 0.0772,
        560: 0.0870,
        580: 0.1128,
        600: 0.1360
    }
    sd = SpectralDistribution(data, name='Custom')
    plt.close(plot_single_sd(sd, **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Multi_SDS.png')
    data_1 = {
        500: 0.004900,
        510: 0.009300,
        520: 0.063270,
        530: 0.165500,
        540: 0.290400,
        550: 0.433450,
        560: 0.594500
    }
    data_2 = {
        500: 0.323000,
        510: 0.503000,
        520: 0.710000,
        530: 0.862000,
        540: 0.954000,
        550: 0.994950,
        560: 0.995000
    }
    spd1 = SpectralDistribution(data_1, name='Custom 1')
    spd2 = SpectralDistribution(data_2, name='Custom 2')
    plt.close(plot_multi_sds([spd1, spd2], **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Single_CMFS.png')
    plt.close(
        plot_single_cmfs('CIE 1931 2 Degree Standard Observer',
                         **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Multi_CMFS.png')
    cmfs = ('CIE 1931 2 Degree Standard Observer',
            'CIE 1964 10 Degree Standard Observer')
    plt.close(plot_multi_cmfs(cmfs, **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Illuminant_SD.png')
    plt.close(plot_single_illuminant_sd('A', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Illuminant_SDS.png')
    plt.close(plot_multi_illuminant_sds(['A', 'B', 'C'], **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Visible_Spectrum.png')
    plt.close(plot_visible_spectrum(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Lightness_Function.png')
    plt.close(plot_single_lightness_function('CIE 1976', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Lightness_Functions.png')
    plt.close(
        plot_multi_lightness_functions(['CIE 1976', 'Wyszecki 1963'],
                                       **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Luminance_Function.png')
    plt.close(plot_single_luminance_function('CIE 1976', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Luminance_Functions.png')
    plt.close(
        plot_multi_luminance_functions(['CIE 1976', 'Newhall 1943'],
                                       **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Blackbody_Spectral_Radiance.png')
    plt.close(
        plot_blackbody_spectral_radiance(3500,
                                         blackbody='VY Canis Major',
                                         **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Blackbody_Colours.png')
    plt.close(
        plot_blackbody_colours(SpectralShape(150, 12500, 50), **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Colour_Swatch.png')
    RGB = ColourSwatch(RGB=(0.45620519, 0.03081071, 0.04091952))
    plt.close(plot_single_colour_swatch(RGB, **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Colour_Swatches.png')
    RGB_1 = ColourSwatch(RGB=(0.45293517, 0.31732158, 0.26414773))
    RGB_2 = ColourSwatch(RGB=(0.77875824, 0.57726450, 0.50453169))
    plt.close(plot_multi_colour_swatches([RGB_1, RGB_2], **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Single_Function.png')
    plt.close(plot_single_function(lambda x: x**(1 / 2.2), **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Multi_Functions.png')
    functions = {
        'Gamma 2.2': lambda x: x**(1 / 2.2),
        'Gamma 2.4': lambda x: x**(1 / 2.4),
        'Gamma 2.6': lambda x: x**(1 / 2.6),
    }
    plt.close(plot_multi_functions(functions, **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Image.png')
    path = os.path.join(output_directory, 'Logo_Medium_001.png')
    plt.close(plot_image(read_image(str(path)), **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Corresponding_Chromaticities_Prediction.png')
    plt.close(
        plot_corresponding_chromaticities_prediction(1, 'Von Kries', 'CAT02',
                                                     **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Spectral_Locus.png')
    plt.close(
        plot_spectral_locus(spectral_locus_colours='RGB', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Chromaticity_Diagram_Colours.png')
    plt.close(plot_chromaticity_diagram_colours(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Chromaticity_Diagram.png')
    plt.close(plot_chromaticity_diagram(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Chromaticity_Diagram_CIE1931.png')
    plt.close(plot_chromaticity_diagram_CIE1931(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(plot_chromaticity_diagram_CIE1960UCS(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Chromaticity_Diagram_CIE1976UCS.png')
    plt.close(plot_chromaticity_diagram_CIE1976UCS(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_SDS_In_Chromaticity_Diagram.png')
    A = ILLUMINANTS_SDS['A']
    D65 = ILLUMINANTS_SDS['D65']
    plt.close(plot_sds_in_chromaticity_diagram([A, D65], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1931.png')
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1931([A, D65], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1960UCS([A, D65], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_SDS_In_Chromaticity_Diagram_CIE1976UCS.png')
    plt.close(
        plot_sds_in_chromaticity_diagram_CIE1976UCS([A, D65], **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Pointer_Gamut.png')
    plt.close(plot_pointer_gamut(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_RGB_Colourspaces_In_Chromaticity_Diagram.png')
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram(
            ['ITU-R BT.709', 'ACEScg', 'S-Gamut'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_RGB_Colourspaces_In_Chromaticity_Diagram_CIE1931.png')
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931(
            ['ITU-R BT.709', 'ACEScg', 'S-Gamut'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Colourspaces_In_'
        'Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS(
            ['ITU-R BT.709', 'ACEScg', 'S-Gamut'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Colourspaces_In_'
        'Chromaticity_Diagram_CIE1976UCS.png')
    plt.close(
        plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS(
            ['ITU-R BT.709', 'ACEScg', 'S-Gamut'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Chromaticities_In_'
        'Chromaticity_Diagram.png')
    RGB = np.random.random((128, 128, 3))
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram(
            RGB, 'ITU-R BT.709', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Chromaticities_In_'
        'Chromaticity_Diagram_CIE1931.png')
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931(
            RGB, 'ITU-R BT.709', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Chromaticities_In_'
        'Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1960UCS(
            RGB, 'ITU-R BT.709', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Chromaticities_In_'
        'Chromaticity_Diagram_CIE1976UCS.png')
    plt.close(
        plot_RGB_chromaticities_in_chromaticity_diagram_CIE1976UCS(
            RGB, 'ITU-R BT.709', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png')
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Ellipses_MacAdam1942_In_'
        'Chromaticity_Diagram_CIE1931.png')
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1931(
            **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Ellipses_MacAdam1942_In_'
        'Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1960UCS(
            **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Ellipses_MacAdam1942_In_'
        'Chromaticity_Diagram_CIE1976UCS.png')
    plt.close(
        plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS(
            **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Single_CCTF.png')
    plt.close(plot_single_cctf('ITU-R BT.709', **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Multi_CCTFs.png')
    plt.close(plot_multi_cctfs(['ITU-R BT.709', 'sRGB'], **arguments)[0])

    data = np.array([
        [
            None,
            np.array([0.95010000, 1.00000000, 1.08810000]),
            np.array([0.40920000, 0.28120000, 0.30600000]),
            np.array([
                [0.02495100, 0.01908600, 0.02032900],
                [0.10944300, 0.06235900, 0.06788100],
                [0.27186500, 0.18418700, 0.19565300],
                [0.48898900, 0.40749400, 0.44854600],
            ]),
            None,
        ],
        [
            None,
            np.array([0.95010000, 1.00000000, 1.08810000]),
            np.array([0.30760000, 0.48280000, 0.42770000]),
            np.array([
                [0.02108000, 0.02989100, 0.02790400],
                [0.06194700, 0.11251000, 0.09334400],
                [0.15255800, 0.28123300, 0.23234900],
                [0.34157700, 0.56681300, 0.47035300],
            ]),
            None,
        ],
        [
            None,
            np.array([0.95010000, 1.00000000, 1.08810000]),
            np.array([0.39530000, 0.28120000, 0.18450000]),
            np.array([
                [0.02436400, 0.01908600, 0.01468800],
                [0.10331200, 0.06235900, 0.02854600],
                [0.26311900, 0.18418700, 0.12109700],
                [0.43158700, 0.40749400, 0.39008600],
            ]),
            None,
        ],
        [
            None,
            np.array([0.95010000, 1.00000000, 1.08810000]),
            np.array([0.20510000, 0.18420000, 0.57130000]),
            np.array([
                [0.03039800, 0.02989100, 0.06123300],
                [0.08870000, 0.08498400, 0.21843500],
                [0.18405800, 0.18418700, 0.40111400],
                [0.32550100, 0.34047200, 0.50296900],
                [0.53826100, 0.56681300, 0.80010400],
            ]),
            None,
        ],
        [
            None,
            np.array([0.95010000, 1.00000000, 1.08810000]),
            np.array([0.35770000, 0.28120000, 0.11250000]),
            np.array([
                [0.03678100, 0.02989100, 0.01481100],
                [0.17127700, 0.11251000, 0.01229900],
                [0.30080900, 0.28123300, 0.21229800],
                [0.52976000, 0.40749400, 0.11720000],
            ]),
            None,
        ],
    ])
    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Constant_Hue_Loci.png')
    plt.close(plot_constant_hue_loci(data, 'IPT', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_Munsell_Value_Function.png')
    plt.close(plot_single_munsell_value_function('ASTM D1535', **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Multi_Munsell_Value_Functions.png')
    plt.close(
        plot_multi_munsell_value_functions(['ASTM D1535', 'McCamy 1987'],
                                           **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Single_SD_Rayleigh_Scattering.png')
    plt.close(plot_single_sd_rayleigh_scattering(**arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_The_Blue_Sky.png')
    plt.close(plot_the_blue_sky(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Colour_Quality_Bars.png')
    illuminant = ILLUMINANTS_SDS['FL2']
    light_source = LIGHT_SOURCES_SDS['Kinoton 75P']
    light_source = light_source.copy().align(SpectralShape(360, 830, 1))
    cqs_i = colour_quality_scale(illuminant, additional_data=True)
    cqs_l = colour_quality_scale(light_source, additional_data=True)
    plt.close(plot_colour_quality_bars([cqs_i, cqs_l], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Single_SD_Colour_Rendering_Index_Bars.png')
    illuminant = ILLUMINANTS_SDS['FL2']
    plt.close(
        plot_single_sd_colour_rendering_index_bars(illuminant, **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Multi_SDS_Colour_Rendering_Indexes_Bars.png')
    light_source = LIGHT_SOURCES_SDS['Kinoton 75P']
    plt.close(
        plot_multi_sds_colour_rendering_indexes_bars(
            [illuminant, light_source], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Single_SD_Colour_Quality_Scale_Bars.png')
    illuminant = ILLUMINANTS_SDS['FL2']
    plt.close(
        plot_single_sd_colour_quality_scale_bars(illuminant, **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Multi_SDS_Colour_Quality_Scales_Bars.png')
    light_source = LIGHT_SOURCES_SDS['Kinoton 75P']
    plt.close(
        plot_multi_sds_colour_quality_scales_bars([illuminant, light_source],
                                                  **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_Planckian_Locus.png')
    plt.close(plot_planckian_locus(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Planckian_Locus_CIE1931.png')
    plt.close(plot_planckian_locus_CIE1931(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_Planckian_Locus_CIE1960UCS.png')
    plt.close(plot_planckian_locus_CIE1960UCS(**arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram.png')
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram(['A', 'B', 'C'],
                                                     **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram_CIE1931.png')
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1931(['A', 'B', 'C'],
                                                             **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory,
        'Plotting_Plot_Planckian_Locus_In_Chromaticity_Diagram_CIE1960UCS.png')
    plt.close(
        plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(
            ['A', 'B', 'C'], **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Colourspaces_Gamuts.png')
    plt.close(
        plot_RGB_colourspaces_gamuts(['ITU-R BT.709', 'ACEScg', 'S-Gamut'],
                                     **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Plotting_Plot_RGB_Colourspaces_Gamuts.png')
    plt.close(
        plot_RGB_colourspaces_gamuts(['ITU-R BT.709', 'ACEScg', 'S-Gamut'],
                                     **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Plotting_Plot_RGB_Scatter.png')
    plt.close(plot_RGB_scatter(RGB, 'ITU-R BT.709', **arguments)[0])

    filename = os.path.join(
        output_directory,
        'Plotting_Plot_Colour_Automatic_Conversion_Graph.png')
    plot_automatic_colour_conversion_graph(filename)

    # *************************************************************************
    # "tutorial.rst"
    # *************************************************************************
    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_Visible_Spectrum.png')
    plt.close(plot_visible_spectrum(**arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_Sample_SD.png')
    sample_sd_data = {
        380: 0.048,
        385: 0.051,
        390: 0.055,
        395: 0.060,
        400: 0.065,
        405: 0.068,
        410: 0.068,
        415: 0.067,
        420: 0.064,
        425: 0.062,
        430: 0.059,
        435: 0.057,
        440: 0.055,
        445: 0.054,
        450: 0.053,
        455: 0.053,
        460: 0.052,
        465: 0.052,
        470: 0.052,
        475: 0.053,
        480: 0.054,
        485: 0.055,
        490: 0.057,
        495: 0.059,
        500: 0.061,
        505: 0.062,
        510: 0.065,
        515: 0.067,
        520: 0.070,
        525: 0.072,
        530: 0.074,
        535: 0.075,
        540: 0.076,
        545: 0.078,
        550: 0.079,
        555: 0.082,
        560: 0.087,
        565: 0.092,
        570: 0.100,
        575: 0.107,
        580: 0.115,
        585: 0.122,
        590: 0.129,
        595: 0.134,
        600: 0.138,
        605: 0.142,
        610: 0.146,
        615: 0.150,
        620: 0.154,
        625: 0.158,
        630: 0.163,
        635: 0.167,
        640: 0.173,
        645: 0.180,
        650: 0.188,
        655: 0.196,
        660: 0.204,
        665: 0.213,
        670: 0.222,
        675: 0.231,
        680: 0.242,
        685: 0.251,
        690: 0.261,
        695: 0.271,
        700: 0.282,
        705: 0.294,
        710: 0.305,
        715: 0.318,
        720: 0.334,
        725: 0.354,
        730: 0.372,
        735: 0.392,
        740: 0.409,
        745: 0.420,
        750: 0.436,
        755: 0.450,
        760: 0.462,
        765: 0.465,
        770: 0.448,
        775: 0.432,
        780: 0.421
    }

    sd = SpectralDistribution(sample_sd_data, name='Sample')
    plt.close(plot_single_sd(sd, **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_SD_Interpolation.png')
    sd_copy = sd.copy()
    sd_copy.interpolate(SpectralShape(400, 770, 1))
    plt.close(
        plot_multi_sds([sd, sd_copy],
                       bounding_box=[730, 780, 0.25, 0.5],
                       **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_Sample_Swatch.png')
    sd = SpectralDistribution(sample_sd_data)
    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    illuminant = ILLUMINANTS_SDS['D65']
    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd, cmfs, illuminant)
        RGB = XYZ_to_sRGB(XYZ)
    plt.close(
        plot_single_colour_swatch(ColourSwatch('Sample', RGB),
                                  text_parameters={'size': 'x-large'},
                                  **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_Neutral5.png')
    patch_name = 'neutral 5 (.70 D)'
    patch_sd = COLOURCHECKERS_SDS['ColorChecker N Ohta'][patch_name]
    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(patch_sd, cmfs, illuminant)
        RGB = XYZ_to_sRGB(XYZ)
    plt.close(
        plot_single_colour_swatch(ColourSwatch(patch_name.title(), RGB),
                                  text_parameters={'size': 'x-large'},
                                  **arguments)[0])

    arguments['filename'] = os.path.join(output_directory,
                                         'Tutorial_Colour_Checker.png')
    plt.close(
        plot_single_colour_checker(colour_checker='ColorChecker 2005',
                                   text_parameters={'visible': False},
                                   **arguments)[0])

    arguments['filename'] = os.path.join(
        output_directory, 'Tutorial_CIE_1931_Chromaticity_Diagram.png')
    xy = XYZ_to_xy(XYZ)
    plot_chromaticity_diagram_CIE1931(standalone=False)
    x, y = xy
    plt.plot(x, y, 'o-', color='white')
    # Annotating the plot.
    plt.annotate(patch_sd.name.title(),
                 xy=xy,
                 xytext=(-50, 30),
                 textcoords='offset points',
                 arrowprops=dict(arrowstyle='->',
                                 connectionstyle='arc3, rad=-0.2'))
    plt.close(
        render(standalone=True,
               limits=(-0.1, 0.9, -0.1, 0.9),
               x_tighten=True,
               y_tighten=True,
               **arguments)[0])

    # *************************************************************************
    # "basics.rst"
    # *************************************************************************
    arguments['filename'] = os.path.join(output_directory,
                                         'Basics_Logo_Small_001_CIE_XYZ.png')
    RGB = read_image(os.path.join(output_directory, 'Logo_Small_001.png'))[...,
                                                                           0:3]
    XYZ = sRGB_to_XYZ(RGB)
    plt.close(
        plot_image(XYZ, text_parameters={'text': 'sRGB to XYZ'},
                   **arguments)[0])
예제 #19
0
def colour_quality_scale(
    sd_test: SpectralDistribution,
    additional_data: Boolean = False,
    method: Union[Literal["NIST CQS 7.4", "NIST CQS 9.0"],
                  str] = "NIST CQS 9.0",
) -> Union[Floating, ColourRendering_Specification_CQS]:
    """
    Return the *Colour Quality Scale* (CQS) of given spectral distribution
    using given method.

    Parameters
    ----------
    sd_test
        Test spectral distribution.
    additional_data
        Whether to output additional data.
    method
        Computation method.

    Returns
    -------
    :class:`numpy.floating` or \
:class:`colour.quality.ColourRendering_Specification_CQS`
        *Colour Quality Scale* (CQS).

    References
    ----------
    :cite:`Davis2010a`, :cite:`Ohno2008a`, :cite:`Ohno2013`

    Examples
    --------
    >>> from colour import SDS_ILLUMINANTS
    >>> sd = SDS_ILLUMINANTS['FL2']
    >>> colour_quality_scale(sd)  # doctest: +ELLIPSIS
    64.1117031...
    """

    method = validate_method(method, COLOUR_QUALITY_SCALE_METHODS)

    # pylint: disable=E1102
    cmfs = reshape_msds(
        MSDS_CMFS["CIE 1931 2 Degree Standard Observer"],
        SPECTRAL_SHAPE_DEFAULT,
    )

    shape = cmfs.shape
    sd_test = reshape_sd(sd_test, shape)
    vs_sds = {sd.name: reshape_sd(sd, shape) for sd in SDS_VS[method].values()}

    with domain_range_scale("1"):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Ohno2013(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_vs_colorimetry_data = vs_colorimetry_data(sd_test,
                                                   sd_reference,
                                                   vs_sds,
                                                   cmfs,
                                                   chromatic_adaptation=True)

    reference_vs_colorimetry_data = vs_colorimetry_data(
        sd_reference, sd_reference, vs_sds, cmfs)

    CCT_f: Floating
    if method == "nist cqs 9.0":
        CCT_f = 1
        scaling_f = 3.2
    else:
        XYZ_r = sd_to_XYZ(sd_reference, cmfs)
        XYZ_r /= XYZ_r[1]
        CCT_f = CCT_factor(reference_vs_colorimetry_data, XYZ_r)
        scaling_f = 3.104

    Q_as = colour_quality_scales(
        test_vs_colorimetry_data,
        reference_vs_colorimetry_data,
        scaling_f,
        CCT_f,
    )

    D_E_RMS = delta_E_RMS(Q_as, "D_E_ab")
    D_Ep_RMS = delta_E_RMS(Q_as, "D_Ep_ab")

    Q_a = scale_conversion(D_Ep_RMS, CCT_f, scaling_f)

    if method == "nist cqs 9.0":
        scaling_f = 2.93 * 1.0343
    else:
        scaling_f = 2.928

    Q_f = scale_conversion(D_E_RMS, CCT_f, scaling_f)

    G_t = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in test_vs_colorimetry_data])
    G_r = gamut_area(
        [vs_CQS_data.Lab for vs_CQS_data in reference_vs_colorimetry_data])

    Q_g = G_t / GAMUT_AREA_D65 * 100

    if method == "nist cqs 9.0":
        Q_p = Q_d = None
    else:
        p_delta_C = np.average([
            sample_data.D_C_ab if sample_data.D_C_ab > 0 else 0
            for sample_data in Q_as.values()
        ])
        Q_p = as_float_scalar(100 - 3.6 * (D_Ep_RMS - p_delta_C))
        Q_d = as_float_scalar(G_t / G_r * CCT_f * 100)

    if additional_data:
        return ColourRendering_Specification_CQS(
            sd_test.name,
            Q_a,
            Q_f,
            Q_p,
            Q_g,
            Q_d,
            Q_as,
            (test_vs_colorimetry_data, reference_vs_colorimetry_data),
        )
    else:
        return Q_a
예제 #20
0
파일: cri.py 프로젝트: zachlewis/colour
def colour_rendering_index(sd_test, additional_data=False):
    """
    Returns the *Colour Rendering Index* (CRI) :math:`Q_a` of given spectral
    distribution.

    Parameters
    ----------
    sd_test : SpectralDistribution
        Test spectral distribution.
    additional_data : bool, optional
        Whether to output additional data.

    Returns
    -------
    numeric or CRI_Specification
        *Colour Rendering Index* (CRI).

    References
    ----------
    :cite:`Ohno2008a`

    Examples
    --------
    >>> from colour import ILLUMINANTS_SDS
    >>> sd = ILLUMINANTS_SDS['FL2']
    >>> colour_rendering_index(sd)  # doctest: +ELLIPSIS
    64.1515202...
    """

    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy(
    ).trim(DEFAULT_SPECTRAL_SHAPE)

    shape = cmfs.shape
    sd_test = sd_test.copy().align(shape)
    tcs_sds = {sd.name: sd.copy().align(shape) for sd in TCS_SDS.values()}

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Robertson1968(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_tcs_colorimetry_data = tcs_colorimetry_data(sd_test,
                                                     sd_reference,
                                                     tcs_sds,
                                                     cmfs,
                                                     chromatic_adaptation=True)

    reference_tcs_colorimetry_data = tcs_colorimetry_data(
        sd_reference, sd_reference, tcs_sds, cmfs)

    Q_as = colour_rendering_indexes(test_tcs_colorimetry_data,
                                    reference_tcs_colorimetry_data)

    Q_a = np.average(
        [v.Q_a for k, v in Q_as.items() if k in (1, 2, 3, 4, 5, 6, 7, 8)])

    if additional_data:
        return CRI_Specification(
            sd_test.name, Q_a, Q_as,
            (test_tcs_colorimetry_data, reference_tcs_colorimetry_data))
    else:
        return Q_a
예제 #21
0
def generate_illuminants_rawtoaces_v1() -> CaseInsensitiveMapping:
    """
    Generate a series of illuminants according to *RAW to ACES* v1:

    -   *CIE Illuminant D Series* in range [4000, 25000] kelvin degrees.
    -   *Blackbodies* in range [1000, 3500] kelvin degrees.
    -   A.M.P.A.S. variant of *ISO 7589 Studio Tungsten*.

    Returns
    -------
    :class:`colour.utilities.CaseInsensitiveMapping`
        Series of illuminants.

    Notes
    -----
    -   This definition introduces a few differences compared to
        *RAW to ACES* v1: *CIE Illuminant D Series* are computed in range
        [4002.15, 7003.77] kelvin degrees and the :math:`C_2` change is not
        used in *RAW to ACES* v1.

    References
    ----------
    :cite:`Dyer2017`

    Examples
    --------
    >>> list(sorted(generate_illuminants_rawtoaces_v1().keys()))
    ['1000K Blackbody', '1500K Blackbody', '2000K Blackbody', \
'2500K Blackbody', '3000K Blackbody', '3500K Blackbody', 'D100', 'D105', \
'D110', 'D115', 'D120', 'D125', 'D130', 'D135', 'D140', 'D145', 'D150', \
'D155', 'D160', 'D165', 'D170', 'D175', 'D180', 'D185', 'D190', 'D195', \
'D200', 'D205', 'D210', 'D215', 'D220', 'D225', 'D230', 'D235', 'D240', \
'D245', 'D250', 'D40', 'D45', 'D50', 'D55', 'D60', 'D65', 'D70', 'D75', \
'D80', 'D85', 'D90', 'D95', 'iso7589']
    """

    global _ILLUMINANTS_RAWTOACES_V1

    if _ILLUMINANTS_RAWTOACES_V1 is not None:
        illuminants = _ILLUMINANTS_RAWTOACES_V1
    else:
        illuminants = CaseInsensitiveMapping()

        # CIE Illuminants D Series from 4000K to 25000K.
        for i in np.arange(4000, 25000 + 500, 500):
            CCT = i * 1.4388 / 1.4380
            xy = CCT_to_xy_CIE_D(CCT)
            sd = sd_CIE_illuminant_D_series(xy)
            sd.name = f"D{int(CCT / 100):d}"
            illuminants[sd.name] = sd.align(SPECTRAL_SHAPE_RAWTOACES)

        # TODO: Remove when removing the "colour.sd_blackbody" definition
        # warning.
        with suppress_warnings(colour_usage_warnings=True):
            # Blackbody from 1000K to 4000K.
            for i in np.arange(1000, 4000, 500):
                sd = sd_blackbody(i, SPECTRAL_SHAPE_RAWTOACES)
                illuminants[sd.name] = sd

        # A.M.P.A.S. variant of ISO 7589 Studio Tungsten.
        sd = read_sds_from_csv_file(
            os.path.join(RESOURCES_DIRECTORY_RAWTOACES,
                         "AMPAS_ISO_7589_Tungsten.csv"))["iso7589"]
        illuminants.update({sd.name: sd})

        _ILLUMINANTS_RAWTOACES_V1 = illuminants

    return illuminants
예제 #22
0
def plot_blackbody_colours(
        shape=SpectralShape(150, 12500, 50),
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots blackbody colours.

    Parameters
    ----------
    shape : SpectralShape, optional
        Spectral shape to use as plot boundaries.
    cmfs : unicode, optional
        Standard observer colour matching functions.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_blackbody_colours(SpectralShape(150, 12500, 50))  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_Blackbody_Colours.png
        :align: center
        :alt: plot_blackbody_colours
    """

    _figure, axes = artist(**kwargs)

    cmfs = first_item(filter_cmfs(cmfs).values())

    colours = []
    temperatures = []

    for temperature in shape:
        sd = sd_blackbody(temperature, cmfs.shape)

        with domain_range_scale('1'):
            XYZ = sd_to_XYZ(sd, cmfs)

        RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ))

        colours.append(RGB)
        temperatures.append(temperature)

    x_min, x_max = min(temperatures), max(temperatures)
    y_min, y_max = 0, 1

    padding = 0.1
    axes.bar(
        x=np.array(temperatures) - padding,
        height=1,
        width=shape.interval + (padding * shape.interval),
        color=colours,
        align='edge')

    settings = {
        'axes': axes,
        'bounding_box': (x_min, x_max, y_min, y_max),
        'title': 'Blackbody Colours',
        'x_label': 'Temperature K',
        'y_label': None,
    }
    settings.update(kwargs)

    return render(**settings)
예제 #23
0
def colour_rendering_index(sd_test, additional_data=False):
    """
    Returns the *Colour Rendering Index* (CRI) :math:`Q_a` of given spectral
    distribution.

    Parameters
    ----------
    sd_test : SpectralDistribution
        Test spectral distribution.
    additional_data : bool, optional
        Whether to output additional data.

    Returns
    -------
    numeric or CRI_Specification
        *Colour Rendering Index* (CRI).

    References
    ----------
    :cite:`Ohno2008a`

    Examples
    --------
    >>> from colour import ILLUMINANTS_SDS
    >>> sd = ILLUMINANTS_SDS['FL2']
    >>> colour_rendering_index(sd)  # doctest: +ELLIPSIS
    64.1515202...
    """

    cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy(
    ).trim(ASTME30815_PRACTISE_SHAPE)

    shape = cmfs.shape
    sd_test = sd_test.copy().align(shape)
    tcs_sds = {sd.name: sd.copy().align(shape) for sd in TCS_SDS.values()}

    with domain_range_scale('1'):
        XYZ = sd_to_XYZ(sd_test, cmfs)

    uv = UCS_to_uv(XYZ_to_UCS(XYZ))
    CCT, _D_uv = uv_to_CCT_Robertson1968(uv)

    if CCT < 5000:
        sd_reference = sd_blackbody(CCT, shape)
    else:
        xy = CCT_to_xy_CIE_D(CCT)
        sd_reference = sd_CIE_illuminant_D_series(xy)
        sd_reference.align(shape)

    test_tcs_colorimetry_data = tcs_colorimetry_data(
        sd_test, sd_reference, tcs_sds, cmfs, chromatic_adaptation=True)

    reference_tcs_colorimetry_data = tcs_colorimetry_data(
        sd_reference, sd_reference, tcs_sds, cmfs)

    Q_as = colour_rendering_indexes(test_tcs_colorimetry_data,
                                    reference_tcs_colorimetry_data)

    Q_a = np.average(
        [v.Q_a for k, v in Q_as.items() if k in (1, 2, 3, 4, 5, 6, 7, 8)])

    if additional_data:
        return CRI_Specification(
            sd_test.name, Q_a, Q_as,
            (test_tcs_colorimetry_data, reference_tcs_colorimetry_data))
    else:
        return Q_a
예제 #24
0
파일: colorimetry.py 프로젝트: yixw/colour
def plot_blackbody_colours(shape=SpectralShape(150, 12500, 50),
                           cmfs='CIE 1931 2 Degree Standard Observer',
                           **kwargs):
    """
    Plots blackbody colours.

    Parameters
    ----------
    shape : SpectralShape, optional
        Spectral shape to use as plot boundaries.
    cmfs : unicode, optional
        Standard observer colour matching functions.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_blackbody_colours(SpectralShape(150, 12500, 50))
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, \
<matplotlib.axes._subplots.AxesSubplot object at 0x...>)

    .. image:: ../_static/Plotting_Plot_Blackbody_Colours.png
        :align: center
        :alt: plot_blackbody_colours
    """

    _figure, axes = artist(**kwargs)

    cmfs = first_item(filter_cmfs(cmfs).values())

    colours = []
    temperatures = []

    for temperature in shape:
        sd = sd_blackbody(temperature, cmfs.shape)

        with domain_range_scale('1'):
            XYZ = sd_to_XYZ(sd, cmfs)

        RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ))

        colours.append(RGB)
        temperatures.append(temperature)

    x_min, x_max = min(temperatures), max(temperatures)
    y_min, y_max = 0, 1

    padding = 0.1
    axes.bar(x=np.array(temperatures) - padding,
             height=1,
             width=shape.interval + (padding * shape.interval),
             color=colours,
             align='edge')

    settings = {
        'axes': axes,
        'bounding_box': (x_min, x_max, y_min, y_max),
        'title': 'Blackbody Colours',
        'x_label': 'Temperature K',
        'y_label': None,
    }
    settings.update(kwargs)

    return render(**settings)
예제 #25
0
def plot_blackbody_colours(
    shape: SpectralShape = SpectralShape(150, 12500, 50),
    cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[
        MultiSpectralDistributions,
        str]], ] = "CIE 1931 2 Degree Standard Observer",
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot blackbody colours.

    Parameters
    ----------
    shape
        Spectral shape to use as plot boundaries.
    cmfs
        Standard observer colour matching functions used for computing the
        blackbody colours. ``cmfs`` can be of any type or form supported by the
        :func:`colour.plotting.filter_cmfs` definition.

    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_blackbody_colours(SpectralShape(150, 12500, 50))
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...AxesSubplot...>)

    .. image:: ../_static/Plotting_Plot_Blackbody_Colours.png
        :align: center
        :alt: plot_blackbody_colours
    """

    _figure, axes = artist(**kwargs)

    cmfs = cast(MultiSpectralDistributions,
                first_item(filter_cmfs(cmfs).values()))

    RGB = []
    temperatures = []

    for temperature in shape:
        sd = sd_blackbody(temperature, cmfs.shape)

        with domain_range_scale("1"):
            XYZ = sd_to_XYZ(sd, cmfs)

        RGB.append(normalise_maximum(XYZ_to_plotting_colourspace(XYZ)))
        temperatures.append(temperature)

    x_min, x_max = min(temperatures), max(temperatures)
    y_min, y_max = 0, 1

    padding = 0.1
    axes.bar(
        x=np.array(temperatures) - padding,
        height=1,
        width=shape.interval + (padding * shape.interval),
        color=RGB,
        align="edge",
        zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon,
    )

    settings: Dict[str, Any] = {
        "axes": axes,
        "bounding_box": (x_min, x_max, y_min, y_max),
        "title": "Blackbody Colours",
        "x_label": "Temperature K",
        "y_label": None,
    }
    settings.update(kwargs)

    return render(**settings)