示例#1
0
def spds_CIE_1976_UCS_chromaticity_diagram_plot(
        spds,
        cmfs='CIE 1931 2 Degree Standard Observer',
        annotate=True,
        **kwargs):
    """
    Plots given spectral power distribution chromaticity coordinates into the
    *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    spds : list, optional
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    annotate : bool
        Should resulting chromaticity coordinates annotated with their
        respective spectral power distribution names.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> A = ILLUMINANTS_RELATIVE_SPDS['A']
    >>> D65 = ILLUMINANTS_RELATIVE_SPDS['D65']
    >>> spds_CIE_1976_UCS_chromaticity_diagram_plot([A, D65])  # doctest: +SKIP
    True
    """

    CIE_1976_UCS_chromaticity_diagram_plot(standalone=False,
                                           **kwargs)

    cmfs = get_cmfs(cmfs)
    cmfs_shape = cmfs.shape

    for spd in spds:
        spd = spd.clone().align(cmfs_shape)
        XYZ = spectral_to_XYZ(spd) / 100
        uv = Luv_to_uv(XYZ_to_Luv(XYZ))

        pylab.plot(uv[0], uv[1], 'o', color='white')

        if spd.name is not None and annotate:
            pylab.annotate(spd.name,
                           xy=uv,
                           xytext=(50, 30),
                           textcoords='offset points',
                           arrowprops=dict(arrowstyle='->',
                                           connectionstyle='arc3, rad=0.2'))

    display(standalone=True)
示例#2
0
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs):
    """
    Plots the *colour rendering index* of given illuminants or light sources
    spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *colour rendering index*.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P')
    >>> multi_spd_colour_rendering_index_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [
        colour_rendering_index(spd, additional_data=True) for spd in spds
    ]

    # *colour rendering index* colorimetry data tristimulus values are
    # computed in [0, 100] domain however `colour_quality_bars_plot` expects
    # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition
    # agnostic from the colour quality data, we update the test spd
    # colorimetry data tristimulus values domain.
    for specification in specifications:
        colorimetry_data = specification.colorimetry_data
        for i, c_d in enumerate(colorimetry_data[0]):
            colorimetry_data[0][i] = TCS_ColorimetryData(
                c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW)

    colour_quality_bars_plot(specifications, **settings)

    settings = {
        'title':
        'Colour Rendering Index - {0}'.format(', '.join(
            [spd.title for spd in spds]))
    }
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
示例#3
0
def RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(
        RGB,
        colourspace,
        **kwargs):
    """
    Plots given *RGB* colourspace array in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : unicode
        *RGB* colourspace of the *RGB* array.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> c = 'Rec. 709'
    >>> RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(
    ...     RGB, c)  # doctest: +SKIP
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    colourspace, name = get_RGB_colourspace(colourspace), colourspace
    settings['colourspaces'] = (
        [name] + settings.get('colourspaces', []))

    RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(**settings)

    alpha_p, colour_p = 0.85, 'black'

    xy = XYZ_to_xy(RGB_to_XYZ(RGB,
                              colourspace.whitepoint,
                              colourspace.whitepoint,
                              colourspace.RGB_to_XYZ_matrix),
                   colourspace.whitepoint)

    pylab.scatter(xy[..., 0],
                  xy[..., 1],
                  alpha=alpha_p / 2,
                  color=colour_p,
                  marker='+')

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

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#4
0
def colour_quality_scale_bars_plot(spd, **kwargs):
    """
    Plots the *colour quality scale* of given illuminant or light source.

    Parameters
    ----------
    spd : SpectralPowerDistribution
        Illuminant or light source to plot the *colour quality scale*.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> colour_quality_scale_bars_plot(illuminant)  # doctest: +SKIP
    True
    """

    if colour_quality_bars_plot(
            colour_quality_scale(
                    spd,
                    additional_data=True),
            standalone=False):
        settings = {
            'title': 'Colour Quality Scale - {0}'.format(spd.title)}

        decorate(**settings)
        return display(**settings)
示例#5
0
def RGB_chromaticity_coordinates_CIE_1976_UCS_chromaticity_diagram_plot(
        RGB,
        colourspace,
        **kwargs):
    """
    Plots given *RGB* colourspace array in *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> c = 'Rec. 709'
    >>> RGB_chromaticity_coordinates_CIE_1976_UCS_chromaticity_diagram_plot(
    ...     RGB, c)  # doctest: +SKIP
    True
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    settings['colourspaces'] = (
        [colourspace.name] + settings.get('colourspaces', []))

    RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    alpha_p, colour_p = 0.85, 'black'

    uv = Luv_to_uv(XYZ_to_Luv(RGB_to_XYZ(RGB,
                                         colourspace.whitepoint,
                                         colourspace.whitepoint,
                                         colourspace.RGB_to_XYZ_matrix),
                              colourspace.whitepoint),
                   colourspace.whitepoint)

    pylab.scatter(uv[..., 0],
                  uv[..., 1],
                  alpha=alpha_p / 2,
                  color=colour_p,
                  marker='+')

    settings.update({'standalone': True})

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#6
0
文件: quality.py 项目: brehm/colour
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs):
    """
    Plots the *colour rendering index* of given illuminants or light sources
    spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *colour rendering index*.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P')
    >>> multi_spd_colour_rendering_index_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    True
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [colour_rendering_index(spd, additional_data=True)
                      for spd in spds]

    # *colour rendering index* colorimetry data tristimulus values are
    # computed in [0, 100] domain however `colour_quality_bars_plot` expects
    # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition
    # agnostic from the colour quality data, we update the test spd
    # colorimetry data tristimulus values domain.
    for specification in specifications:
        colorimetry_data = specification.colorimetry_data
        for i, c_d in enumerate(colorimetry_data[0]):
            colorimetry_data[0][i] = TCS_ColorimetryData(c_d.name,
                                                         c_d.XYZ / 100,
                                                         c_d.uv,
                                                         c_d.UVW)

    colour_quality_bars_plot(specifications, **settings)

    settings = {'title': 'Colour Rendering Index - {0}'.format(', '.join(
        [spd.title for spd in spds]))}
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
示例#7
0
def multi_transfer_function_plot(colourspaces=None,
                                 inverse=False, **kwargs):
    """
    Plots given colourspaces transfer functions.

    Parameters
    ----------
    colourspaces : list, optional
        Colourspaces transfer functions to plot.
    inverse : bool
        Plot inverse transfer functions.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> multi_transfer_function_plot(['sRGB', 'Rec. 709'])  # doctest: +SKIP
    True
    """

    if colourspaces is None:
        colourspaces = ['sRGB', 'Rec. 709']

    samples = np.linspace(0, 1, 1000)
    for i, colourspace in enumerate(colourspaces):
        colourspace, name = get_RGB_colourspace(colourspace), colourspace

        RGBs = np.array([colourspace.inverse_transfer_function(x)
                         if inverse else
                         colourspace.transfer_function(x)
                         for x in samples])
        pylab.plot(samples,
                   RGBs,
                   label=u'{0}'.format(colourspace.name),
                   linewidth=2)

    settings = {
        'title': '{0} - Transfer Functions'.format(
            ', '.join(colourspaces)),
        'x_tighten': True,
        'legend': True,
        'legend_location': 'upper left',
        'x_ticker': True,
        'y_ticker': True,
        'grid': True,
        'limits': [0, 1, 0, 1]}

    settings.update(kwargs)

    bounding_box(**settings)
    aspect(**settings)

    return display(**settings)
示例#8
0
def RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(
        RGB, colourspace, **kwargs):
    """
    Plots given *RGB* colourspace array in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : unicode
        *RGB* colourspace of the *RGB* array.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> c = 'Rec. 709'
    >>> RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(
    ...     RGB, c)  # doctest: +SKIP
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    colourspace, name = get_RGB_colourspace(colourspace), colourspace
    settings['colourspaces'] = ([name] + settings.get('colourspaces', []))

    RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(**settings)

    alpha_p, colour_p = 0.85, 'black'

    xy = XYZ_to_xy(
        RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                   colourspace.RGB_to_XYZ_matrix), colourspace.whitepoint)

    pylab.scatter(xy[..., 0],
                  xy[..., 1],
                  alpha=alpha_p / 2,
                  color=colour_p,
                  marker='+')

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

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#9
0
文件: models.py 项目: fangjy88/colour
def RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(
        RGB,
        colourspace,
        **kwargs):
    """
    Plots given *RGB* colourspace array in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> RGB_chromaticity_coordinates_CIE_1931_chromaticity_diagram_plot(RGB)  # noqa  # doctest: +SKIP
    True
    """

    settings = {}
    settings.update(kwargs)

    settings['colourspaces'] = (
        [colourspace.name] + settings.get('colourspaces', []))
    RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
        standalone=False, **settings)

    alpha_p, colour_p = 0.85, 'black'

    xy = XYZ_to_xy(RGB_to_XYZ(RGB,
                              colourspace.whitepoint,
                              colourspace.whitepoint,
                              colourspace.RGB_to_XYZ_matrix),
                   colourspace.whitepoint)

    pylab.scatter(xy[..., 0],
                  xy[..., 1],
                  alpha=alpha_p / 2,
                  color=colour_p,
                  marker='+')

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#10
0
def radiance_image_strip_plot(image,
                              count=5,
                              ev_steps=-2,
                              encoding_cctf=DEFAULT_PLOTTING_ENCODING_CCTF,
                              **kwargs):
    """
    Plots given HDRI / radiance image as strip of images of varying exposure.

    Parameters
    ----------
    image : array_like
         HDRI / radiance image to plot.
    count : int, optional
        Strip images count.
    ev_steps : numeric, optional
        Exposure variation for each image of the strip.
    encoding_cctf : callable, optional
        Encoding colour component transfer function / opto-electronic
        transfer function used for plotting.

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

    Returns
    -------
    Figure
        Current figure or None.
    """

    image = np.asarray(image)

    grid = matplotlib.gridspec.GridSpec(1, count)
    grid.update(wspace=0, hspace=0)

    height, width, _channel = image.shape
    for i in range(count):
        ev = i * ev_steps
        axis = matplotlib.pyplot.subplot(grid[i])
        axis.imshow(np.clip(encoding_cctf(adjust_exposure(image, ev)), 0, 1))
        axis.text(width * 0.05,
                  height - height * 0.05,
                  'EV {0}'.format(ev),
                  color=(1, 1, 1))
        axis.set_xticks([])
        axis.set_yticks([])
        axis.set_aspect('equal')

    return display(**kwargs)
示例#11
0
def multi_spd_colour_quality_scale_bars_plot(spds, **kwargs):
    """
    Plots the *colour quality scale* of given illuminants or light sources
    spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *colour quality scale*.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P')
    >>> multi_spd_colour_quality_scale_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    True
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [
        colour_quality_scale(spd, additional_data=True) for spd in spds
    ]
    colour_quality_bars_plot(specifications, **settings)

    settings = {
        'title':
        'Colour Quality Scale - {0}'.format(', '.join(
            [spd.title for spd in spds]))
    }
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
示例#12
0
def radiance_image_strip_plot(image,
                              count=5,
                              ev_steps=-2,
                              encoding_cctf=DEFAULT_PLOTTING_ENCODING_CCTF,
                              **kwargs):
    """
    Plots given HDRI / radiance image as strip of images of varying exposure.

    Parameters
    ----------
    image : array_like
         HDRI / radiance image to plot.
    count : int, optional
        Strip images count.
    ev_steps : numeric, optional
        Exposure variation for each image of the strip.
    encoding_cctf : callable, optional
        Encoding colour component transfer function / opto-electronic
        transfer function used for plotting.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.
    """

    image = np.asarray(image)

    grid = matplotlib.gridspec.GridSpec(1, count)
    grid.update(wspace=0, hspace=0)

    height, width, _channel = image.shape
    for i in range(count):
        ev = i * ev_steps
        axis = matplotlib.pyplot.subplot(grid[i])
        axis.imshow(
            np.clip(encoding_cctf(adjust_exposure(image, ev)), 0, 1))
        axis.text(width * 0.05,
                  height - height * 0.05,
                  'EV {0}'.format(ev),
                  color=(1, 1, 1))
        axis.set_xticks([])
        axis.set_yticks([])
        axis.set_aspect('equal')

    return display(**kwargs)
示例#13
0
文件: quality.py 项目: brehm/colour
def multi_spd_colour_quality_scale_bars_plot(spds, **kwargs):
    """
    Plots the *colour quality scale* of given illuminants or light sources
    spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *colour quality scale*.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P')
    >>> multi_spd_colour_quality_scale_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    True
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [colour_quality_scale(spd, additional_data=True)
                      for spd in spds]
    colour_quality_bars_plot(specifications, **settings)

    settings = {'title': 'Colour Quality Scale - {0}'.format(', '.join(
        [spd.title for spd in spds]))}
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
def fraunhofer_lines_plot(image=SUN_SPECTRUM_IMAGE):
    """
    Plots the Fraunhofer lines of given image.

    Parameters
    ----------
    image : unicode
        Path to read the image from.

    Returns
    -------
    bool
        Definition success.
    """

    spectrum = RGB_spectrum(read_image(image),
                            FRAUNHOFER_LINES_PUBLISHED,
                            FRAUNHOFER_LINES_MEASURED)

    height = len(spectrum.R.values) / 8
    spd = luminance_spd(spectrum).normalise(height)

    pylab.title('The Solar Spectrum - Fraunhofer Lines')

    wavelengths = spectrum.wavelengths
    input, output = min(wavelengths), max(wavelengths)
    pylab.imshow(sRGB_COLOURSPACE.OECF(
        np.dstack([spectrum.R.values,
                   spectrum.G.values,
                   spectrum.B.values])),
        extent=[input, output, 0, height])

    pylab.plot(spd.wavelengths,
               spd.values, color='black',
               linewidth=1)

    fraunhofer_wavelengths = np.array(
        sorted(FRAUNHOFER_LINES_PUBLISHED.values()))
    fraunhofer_wavelengths = fraunhofer_wavelengths[
        np.where(np.logical_and(fraunhofer_wavelengths >= input,
                                fraunhofer_wavelengths <= output))]
    fraunhofer_lines_labels = [
        tuple(FRAUNHOFER_LINES_PUBLISHED.keys())[
            tuple(FRAUNHOFER_LINES_PUBLISHED.values()).index(i)]
        for i in fraunhofer_wavelengths]

    y0, y1 = 0, height * .5
    for i, label in enumerate(fraunhofer_lines_labels):

        # Trick to cluster siblings fraunhofer lines.
        from_siblings = False
        for pattern, (first, siblings,
                      specific_label) in FRAUNHOFER_LINES_CLUSTERED.items():
            if re.match(pattern, label):
                if label in siblings:
                    from_siblings = True

                label = specific_label
                break

        power = bisect.bisect_left(wavelengths, fraunhofer_wavelengths[i])
        scale = (spd.get(wavelengths[power]) / height)

        is_large_line = label in FRAUNHOFER_LINES_NOTABLE

        pylab.vlines(fraunhofer_wavelengths[i], y0, y1 * scale,
                     linewidth=2 if is_large_line else 1)

        pylab.vlines(fraunhofer_wavelengths[i], y0, height,
                     linewidth=2 if is_large_line else 1, alpha=0.075)

        if not from_siblings:
            pylab.text(fraunhofer_wavelengths[i],
                       y1 * scale + (y1 * 0.025),
                       label,
                       clip_on=True,
                       ha='center',
                       va='bottom',
                       fontdict={'size': 'large' if is_large_line else'small'})

    r = lambda x: int(x / 100) * 100
    matplotlib.pyplot.xticks(np.arange(r(input), r(output * 1.5), 20))

    settings = {'x_tighten': True,
                'y_tighten': True,
                'x_label': u'Wavelength λ (nm)',
                'y_label': False,
                'legend': False,
                'limits': [input, output, 0, height],
                'y_ticker': True,
                'grid': True}

    boundaries(**settings)

    decorate(**settings)

    return display(**settings)
示例#15
0
def planckian_locus_CIE_1931_chromaticity_diagram_plot(
        illuminants=None,
        **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'B', 'C']
    >>> planckian_locus_CIE_1931_chromaticity_diagram_plot(
    ...     ils)  # doctest: +SKIP
    """

    if illuminants is None:
        illuminants = ('A', 'B', 'C')

    cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1931 Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer').format(
            ', '.join(illuminants))
        if illuminants else
        ('Planckian Locus\nCIE 1931 Chromaticity Diagram - '
         'CIE 1931 2 Degree Standard Observer'),
        'standalone': False}
    settings.update(kwargs)

    CIE_1931_chromaticity_diagram_plot(**settings)

    start, end = 1667, 100000
    xy = np.array([UCS_uv_to_xy(CCT_to_uv(x, 0, method='Robertson 1968'))
                   for x in np.arange(start, end + 250, 250)])

    pylab.plot(xy[..., 0], xy[..., 1], color='black', linewidth=2)

    for i in (1667, 2000, 2500, 3000, 4000, 6000, 10000):
        x0, y0 = UCS_uv_to_xy(CCT_to_uv(i, -0.025, method='Robertson 1968'))
        x1, y1 = UCS_uv_to_xy(CCT_to_uv(i, 0.025, method='Robertson 1968'))
        pylab.plot((x0, x1), (y0, y1), color='black', linewidth=2)
        pylab.annotate('{0}K'.format(i),
                       xy=(x0, y0),
                       xytext=(0, -10),
                       color='black',
                       textcoords='offset points',
                       size='x-small')

    for illuminant in illuminants:
        xy = ILLUMINANTS.get(cmfs.name).get(illuminant)
        if xy is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS.get(cmfs.name).keys())))

        pylab.plot(xy[0], xy[1], 'o', color='white', linewidth=2)

        pylab.annotate(illuminant,
                       xy=(xy[0], xy[1]),
                       xytext=(-50, 30),
                       color='black',
                       textcoords='offset points',
                       arrowprops=dict(arrowstyle='->',
                                       connectionstyle='arc3, rad=-0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.9, -0.1, 0.9),
        'standalone': True})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#16
0
def colour_quality_bars_plot(specifications,
                             labels=True,
                             hatching=None,
                             hatching_repeat=1,
                             **kwargs):
    """
    Plots the colour quality data of given illuminants or light sources colour
    quality specifications.

    Parameters
    ----------
    specifications : array_like
        Array of illuminants or light sources colour quality specifications.
    labels : bool, optional
        Add labels above bars.
    hatching : bool or None, optional
        Use hatching for the bars.
    hatching_repeat : int, optional
        Hatching pattern repeat.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS,
    ...     SpectralShape)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS['F2']
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS['Kinoton 75P']
    >>> light_source = light_source.clone().align(SpectralShape(360, 830, 1))
    >>> cqs_i = colour_quality_scale(illuminant, additional_data=True)
    >>> cqs_l = colour_quality_scale(light_source, additional_data=True)
    >>> colour_quality_bars_plot([cqs_i, cqs_l])  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    bar_width = 0.5
    y_ticks_interval = 10
    count_s, count_Q_as = len(specifications), 0
    patterns = cycle(DEFAULT_HATCH_PATTERNS)
    if hatching is None:
        hatching = False if count_s == 1 else True
    for i, specification in enumerate(specifications):
        Q_a, Q_as, colorimetry_data = (specification.Q_a, specification.Q_as,
                                       specification.colorimetry_data)

        count_Q_as = len(Q_as)
        colours = (
            [[1] * 3] +
            [np.clip(XYZ_to_sRGB(x.XYZ), 0, 1) for x in colorimetry_data[0]])

        x = (i + np.arange(0, (count_Q_as + 1) * (count_s + 1), (count_s + 1),
                           dtype=np.float_)) * bar_width
        y = [s[1].Q_a for s in sorted(Q_as.items(), key=lambda s: s[0])]
        y = np.array([Q_a] + list(y))

        if np.sign(np.min(y)) < 0:
            warning(
                ('"{0}" spectral distribution has negative "Q_a" value(s), '
                 'using absolute value(s) '
                 'for plotting purpose!'.format(specification.name)))

            y = np.abs(y)

        bars = pylab.bar(x,
                         y,
                         color=colours,
                         width=bar_width,
                         hatch=(next(patterns) *
                                hatching_repeat if hatching else None),
                         label=specification.name)

        if labels:
            label_rectangles(
                bars,
                rotation='horizontal' if count_s == 1 else 'vertical',
                offset=(0 if count_s == 1 else 3 / 100 * count_s + 65 / 1000,
                        0.025),
                text_size=-5 / 7 * count_s + 12.5)

    pylab.axhline(y=100, color='black', linestyle='--')

    pylab.xticks(
        (np.arange(0, (count_Q_as + 1) * (count_s + 1), (count_s + 1),
                   dtype=np.float_) * bar_width + (count_s * bar_width / 2)),
        ['Qa'] +
        ['Q{0}'.format(index + 1) for index in range(0, count_Q_as + 1, 1)])
    pylab.yticks(range(0, 100 + y_ticks_interval, y_ticks_interval))

    settings.update({
        'title':
        'Colour Quality',
        'legend':
        hatching,
        'x_tighten':
        True,
        'y_tighten':
        True,
        'limits': (-bar_width, ((count_Q_as + 1) * (count_s + 1)) / 2, 0, 120),
        'aspect':
        1 / (120 / (bar_width + len(Q_as) + bar_width * 2))
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#17
0
文件: quality.py 项目: brehm/colour
def colour_quality_bars_plot(specifications,
                             labels=True,
                             hatching=None,
                             hatching_repeat=1,
                             **kwargs):
    """
    Plots the colour quality data of given illuminants or light sources colour
    quality specifications.

    Parameters
    ----------
    specifications : array_like
        Array of illuminants or light sources colour quality specifications.
    labels : bool, optional
        Add labels above bars.
    hatching : bool or None, optional
        Use hatching for the bars.
    hatching_repeat : int, optional
        Hatching pattern repeat.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P')
    >>> cqs_i = colour_quality_scale(illuminant, additional_data=True)
    >>> cqs_l = colour_quality_scale(light_source, additional_data=True)
    >>> colour_quality_bars_plot([cqs_i, cqs_l])  # doctest: +SKIP
    True
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    bar_width = 0.5
    y_ticks_steps = 10
    count_s, count_Q_as = len(specifications), 0
    patterns = cycle(DEFAULT_HATCH_PATTERNS)
    if hatching is None:
        hatching = False if count_s == 1 else True
    for i, specification in enumerate(specifications):
        Q_a, Q_as, colorimetry_data = (specification.Q_a,
                                       specification.Q_as,
                                       specification.colorimetry_data)

        count_Q_as = len(Q_as)
        colours = ([[1] * 3] + [np.clip(XYZ_to_sRGB(x.XYZ), 0, 1)
                                for x in colorimetry_data[0]])

        x = (i + np.arange(0, (count_Q_as + 1) * (count_s + 1), (count_s + 1),
                           dtype=np.float)) * bar_width
        y = [s[1].Q_a for s in sorted(Q_as.items(), key=lambda s: s[0])]
        y = np.array([Q_a] + list(y))

        if np.sign(np.min(y)) < 0:
            warning(
                ('"{0}" spectral distribution has negative "Q_a" value(s), '
                 'using absolute value(s) '
                 'for plotting purpose!'.format(specification.name)))

            y = np.abs(y)

        bars = pylab.bar(x,
                         y,
                         color=colours,
                         width=bar_width,
                         hatch=(next(patterns) * hatching_repeat
                                if hatching else None),
                         label=specification.name)

        if labels:
            label_rectangles(
                bars,
                rotation='horizontal' if count_s == 1 else 'vertical',
                offset=(0 if count_s == 1 else 3 / 100 * count_s + 65 / 1000,
                        0.025),
                text_size=-5 / 7 * count_s + 12.5)

    pylab.axhline(y=100, color='black', linestyle='--')

    pylab.xticks((np.arange(0, (count_Q_as + 1) * (count_s + 1), (count_s + 1),
                            dtype=np.float) *
                  bar_width + (count_s * bar_width / 2)),
                 ['Qa'] + ['Q{0}'.format(index + 1)
                           for index in range(0, count_Q_as + 1, 1)])
    pylab.yticks(range(0, 100 + y_ticks_steps, y_ticks_steps))

    settings.update({
        'title': 'Colour Quality',
        'legend': hatching,
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-bar_width,
                   ((count_Q_as + 1) * (count_s + 1)) / 2,
                   0,
                   120),
        'aspect': 1 / (120 / (bar_width + len(Q_as) + bar_width * 2))})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#18
0
def RGB_colourspaces_gamuts_plot(colourspaces=None,
                                 reference_colourspace='CIE xyY',
                                 segments=8,
                                 display_grid=True,
                                 grid_segments=10,
                                 spectral_locus=False,
                                 spectral_locus_colour=None,
                                 cmfs='CIE 1931 2 Degree Standard Observer',
                                 **kwargs):
    """
    Plots given *RGB* colourspaces gamuts in given reference colourspace.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to plot the gamuts into.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    display_grid : bool, optional
        Display a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    spectral_locus : bool, optional
        Is spectral locus line plotted.
    spectral_locus_colour : array_like, optional
        Spectral locus line colour.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`nadir_grid`},
        Please refer to the documentation of the previously listed definitions.
    face_colours : array_like, optional
        Face colours array such as `face_colours = (None, (0.5, 0.5, 1.0))`.
    edge_colours : array_like, optional
        Edge colours array such as `edge_colours = (None, (0.5, 0.5, 1.0))`.
    face_alpha : numeric, optional
        Face opacity value such as `face_alpha = (0.5, 1.0)`.
    edge_alpha : numeric, optional
        Edge opacity value such as `edge_alpha = (0.0, 1.0)`.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_gamuts_plot(c)  # doctest: +SKIP
    """

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg')

    count_c = len(colourspaces)
    settings = Structure(
        **{
            'face_colours': [None] * count_c,
            'edge_colours': [None] * count_c,
            'face_alpha': [1] * count_c,
            'edge_alpha': [1] * count_c,
            'title':
            '{0} - {1} Reference Colourspace'.format(', '.join(colourspaces),
                                                     reference_colourspace)
        })
    settings.update(kwargs)

    figure = matplotlib.pyplot.figure()
    axes = figure.add_subplot(111, projection='3d')

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    points = np.zeros((4, 3))
    if spectral_locus:
        cmfs = get_cmfs(cmfs)
        XYZ = cmfs.values

        points = common_colourspace_model_axis_reorder(
            XYZ_to_colourspace_model(XYZ, illuminant, reference_colourspace),
            reference_colourspace)

        points[np.isnan(points)] = 0

        c = ((0.0, 0.0, 0.0,
              0.5) if spectral_locus_colour is None else spectral_locus_colour)

        pylab.plot(points[..., 0],
                   points[..., 1],
                   points[..., 2],
                   color=c,
                   linewidth=2,
                   zorder=1)
        pylab.plot((points[-1][0], points[0][0]),
                   (points[-1][1], points[0][1]),
                   (points[-1][2], points[0][2]),
                   color=c,
                   linewidth=2,
                   zorder=1)

    quads, RGB_f, RGB_e = [], [], []
    for i, colourspace in enumerate(colourspaces):
        colourspace = get_RGB_colourspace(colourspace)
        quads_c, RGB = RGB_identity_cube(width_segments=segments,
                                         height_segments=segments,
                                         depth_segments=segments)

        XYZ = RGB_to_XYZ(quads_c, colourspace.whitepoint,
                         colourspace.whitepoint, colourspace.RGB_to_XYZ_matrix)

        quads.extend(
            common_colourspace_model_axis_reorder(
                XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                         reference_colourspace),
                reference_colourspace))

        if settings.face_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.face_colours[i]

        RGB_f.extend(
            np.hstack((RGB,
                       np.full((RGB.shape[0], 1), settings.face_alpha[i],
                               np.float_))))

        if settings.edge_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.edge_colours[i]

        RGB_e.extend(
            np.hstack((RGB,
                       np.full((RGB.shape[0], 1), settings.edge_alpha[i],
                               np.float_))))

    quads = np.asarray(quads)
    quads[np.isnan(quads)] = 0

    if quads.size != 0:
        for i, axis in enumerate('xyz'):
            min_a = np.min(np.vstack((quads[..., i], points[..., i])))
            max_a = np.max(np.vstack((quads[..., i], points[..., i])))
            getattr(axes, 'set_{}lim'.format(axis))((min_a, max_a))

    labels = COLOURSPACE_MODELS_LABELS[reference_colourspace]
    for i, axis in enumerate('xyz'):
        getattr(axes, 'set_{}label'.format(axis))(labels[i])

    if display_grid:
        if reference_colourspace == 'CIE Lab':
            limits = np.array([[-450, 450], [-450, 450]])
        elif reference_colourspace == 'CIE Luv':
            limits = np.array([[-650, 650], [-650, 650]])
        elif reference_colourspace == 'CIE UVW':
            limits = np.array([[-850, 850], [-850, 850]])
        elif reference_colourspace in ('Hunter Lab', 'Hunter Rdab'):
            limits = np.array([[-250, 250], [-250, 250]])
        else:
            limits = np.array([[-1.5, 1.5], [-1.5, 1.5]])

        quads_g, RGB_gf, RGB_ge = nadir_grid(limits, grid_segments, labels,
                                             axes, **settings)
        quads = np.vstack((quads_g, quads))
        RGB_f = np.vstack((RGB_gf, RGB_f))
        RGB_e = np.vstack((RGB_ge, RGB_e))

    collection = Poly3DCollection(quads)
    collection.set_facecolors(RGB_f)
    collection.set_edgecolors(RGB_e)

    axes.add_collection3d(collection)

    settings.update({'camera_aspect': 'equal', 'no_axes': True})
    settings.update(kwargs)

    camera(**settings)
    decorate(**settings)

    return display(**settings)
示例#19
0
def blackbody_spectral_radiance_plot(
        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.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> blackbody_spectral_radiance_plot()  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    cmfs = get_cmfs(cmfs)

    matplotlib.pyplot.subplots_adjust(hspace=0.4)

    spd = blackbody_spd(temperature, cmfs.shape)

    matplotlib.pyplot.figure(1)
    matplotlib.pyplot.subplot(211)

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

    single_spd_plot(spd, cmfs.name, **settings)

    XYZ = spectral_to_XYZ(spd, cmfs)
    RGB = normalise(XYZ_to_sRGB(XYZ / 100))

    matplotlib.pyplot.subplot(212)

    settings = {'title': '{0} - Colour'.format(blackbody),
                'x_label': '{0}K'.format(temperature),
                'y_label': '',
                'aspect': None,
                'standalone': False}

    single_colour_plot(ColourParameter(name='', RGB=RGB), **settings)

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

    boundaries(**settings)
    decorate(**settings)
    return display(**settings)
示例#20
0
def multi_cmfs_plot(cmfs=None, **kwargs):
    """
    Plots given colour matching functions.

    Parameters
    ----------
    cmfs : array_like, optional
        Colour matching functions to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> cmfs = [
    ... 'CIE 1931 2 Degree Standard Observer',
    ... 'CIE 1964 10 Degree Standard Observer']
    >>> multi_cmfs_plot(cmfs)  # doctest: +SKIP
    """

    canvas(**kwargs)

    if cmfs is None:
        cmfs = ('CIE 1931 2 Degree Standard Observer',
                'CIE 1964 10 Degree Standard Observer')

    x_limit_min, x_limit_max, y_limit_min, y_limit_max = [], [], [], []
    for axis, rgb in (('x', (1, 0, 0)), ('y', (0, 1, 0)), ('z', (0, 0, 1))):
        for i, cmfs_i in enumerate(cmfs):
            cmfs_i = get_cmfs(cmfs_i)

            rgb = [
                reduce(lambda y, _: y * 0.5, range(i), x)  # noqa
                for x in rgb
            ]
            wavelengths, values = tuple(
                zip(*[(key, value) for key, value in getattr(cmfs_i, axis)]))

            shape = cmfs_i.shape
            x_limit_min.append(shape.start)
            x_limit_max.append(shape.end)
            y_limit_min.append(min(values))
            y_limit_max.append(max(values))

            pylab.plot(wavelengths,
                       values,
                       color=rgb,
                       label=u'{0} - {1}'.format(cmfs_i.labels.get(axis),
                                                 cmfs_i.title),
                       linewidth=2)

    settings = {
        'title':
        '{0} - Colour Matching Functions'.format(', '.join(
            [get_cmfs(c).title for c in cmfs])),
        'x_label':
        'Wavelength $\\lambda$ (nm)',
        'y_label':
        'Tristimulus Values',
        'x_tighten':
        True,
        'legend':
        True,
        'legend_location':
        'upper right',
        'grid':
        True,
        'y_axis_line':
        True,
        'limits': (min(x_limit_min), max(x_limit_max), min(y_limit_min),
                   max(y_limit_max))
    }
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#21
0
def corresponding_chromaticities_prediction_plot(experiment=1,
                                                 model='Von Kries',
                                                 transform='CAT02',
                                                 **kwargs):
    """
    Plots given chromatic adaptation model corresponding chromaticities
    prediction.

    Parameters
    ----------
    experiment : int, optional
        Corresponding chromaticities prediction experiment number.
    model : unicode, optional
        Corresponding chromaticities prediction model name.
    transform : unicode, optional
        Transformation to use with *Von Kries* chromatic adaptation model.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1976_UCS_chromaticity_diagram_plot`}
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> corresponding_chromaticities_prediction_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    settings.update({
        'title': (('Corresponding Chromaticities Prediction\n{0} ({1}) - '
                   'Experiment {2}\nCIE 1976 UCS Chromaticity Diagram').format(
                       model, transform, experiment)
                  if model.lower() in ('von kries', 'vonkries') else
                  ('Corresponding Chromaticities Prediction\n{0} - '
                   'Experiment {1}\nCIE 1976 UCS Chromaticity Diagram').format(
                       model, experiment)),
        'standalone':
        False
    })
    settings.update(kwargs)

    CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    results = corresponding_chromaticities_prediction(experiment,
                                                      transform=transform)

    for result in results:
        name, uvp_t, uvp_m, uvp_p = result
        pylab.arrow(uvp_t[0],
                    uvp_t[1],
                    uvp_p[0] - uvp_t[0] - 0.1 * (uvp_p[0] - uvp_t[0]),
                    uvp_p[1] - uvp_t[1] - 0.1 * (uvp_p[1] - uvp_t[1]),
                    head_width=0.005,
                    head_length=0.005,
                    linewidth=0.5,
                    color='black')
        pylab.plot(uvp_t[0], uvp_t[1], 'o', color='white')
        pylab.plot(uvp_m[0], uvp_m[1], '^', color='white')
        pylab.plot(uvp_p[0], uvp_p[1], '^', color='black')
    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.1, 0.7),
        'standalone': True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#22
0
def tonemapping_operator_image_plot(image,
                                    luminance_function,
                                    log_scale=False,
                                    OECF=DEFAULT_PLOTTING_OECF,
                                    **kwargs):
    """
    Plots given tonemapped image with superimposed luminance mapping function.

    Parameters
    ----------
    image : array_like
         Tonemapped image to plot.
    luminance_function : callable
        Luminance mapping function.
    log_scale : bool, optional
        Use a log scale for plotting the luminance mapping function.
    OECF : callable, optional
        OECF / opto-electronic conversion function used for plotting.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.
    """
    shape = image.shape
    limits = [0, 1, 0, 1]

    image = np.clip(OECF(image), 0, 1)
    pylab.imshow(image,
                 aspect=shape[0] / shape[1],
                 extent=limits,
                 interpolation='nearest')

    pylab.plot(np.linspace(0, 1, len(luminance_function)),
               luminance_function,
               color='red')

    settings = {
        'figure_size': (8, 8),
        'x_label': 'Input Luminance',
        'y_label': 'Output Luminance',
        'x_ticker': True,
        'y_ticker': True,
        'grid': True,
        'x_tighten': True,
        'y_tighten': True,
        'limits': limits}
    settings.update(kwargs)

    if log_scale:
        settings.update({
            'x_label': '$log_2$ Input Luminance',
            'x_ticker_locator': matplotlib.ticker.AutoMinorLocator(0.5)})
        matplotlib.pyplot.gca().set_xscale('log', basex=2)
        matplotlib.pyplot.gca().xaxis.set_major_formatter(
            matplotlib.ticker.ScalarFormatter())

    canvas(**settings)
    decorate(**settings)
    boundaries(**settings)
    return display(**settings)
示例#23
0
def CIE_1931_chromaticity_diagram_colours_plot(
        surface=1.25,
        spacing=0.00075,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots the *CIE 1931 Chromaticity Diagram* colours.

    Parameters
    ----------
    surface : numeric, optional
        Generated markers surface.
    spacing : numeric, optional
        Spacing between markers.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> CIE_1931_chromaticity_diagram_colours_plot()  # doctest: +SKIP
    True
    """

    cmfs, name = get_cmfs(cmfs), cmfs

    illuminant = ILLUMINANTS.get(
        'CIE 1931 2 Degree Standard Observer').get('E')

    XYZs = [value for key, value in cmfs]

    x, y = tuple(zip(*([XYZ_to_xy(x) for x in XYZs])))

    path = matplotlib.path.Path(tuple(zip(x, y)))
    x_dot, y_dot, colours = [], [], []
    for i in np.arange(0, 1, spacing):
        for j in np.arange(0, 1, spacing):
            if path.contains_path(matplotlib.path.Path([[i, j], [i, j]])):
                x_dot.append(i)
                y_dot.append(j)

                XYZ = xy_to_XYZ((i, j))
                RGB = normalise(XYZ_to_sRGB(XYZ, illuminant))

                colours.append(RGB)

    pylab.scatter(x_dot, y_dot, color=colours, s=surface)

    settings = {'no_ticks': True,
                'bounding_box': [0, 1, 0, 1],
                'bbox_inches': 'tight',
                'pad_inches': 0}
    settings.update(kwargs)

    bounding_box(**settings)
    aspect(**settings)

    return display(**settings)
示例#24
0
def CIE_1976_UCS_chromaticity_diagram_plot(
        cmfs='CIE 1931 2 Degree Standard Observer', **kwargs):
    """
    Plots the *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> CIE_1976_UCS_chromaticity_diagram_plot()  # doctest: +SKIP
    True
    """

    cmfs, name = get_cmfs(cmfs), cmfs

    image = matplotlib.image.imread(
        os.path.join(PLOTTING_RESOURCES_DIRECTORY,
                     'CIE_1976_UCS_Chromaticity_Diagram_{0}_Small.png'.format(
                         cmfs.name.replace(' ', '_'))))
    pylab.imshow(image, interpolation='nearest', extent=(0, 1, 0, 1))

    labels = [420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530,
              540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 680]

    wavelengths = cmfs.wavelengths
    equal_energy = np.array([1 / 3] * 2)

    illuminant = ILLUMINANTS.get(
        'CIE 1931 2 Degree Standard Observer').get('D50')

    Luvs = [XYZ_to_Luv(value, illuminant) for key, value in cmfs]

    u, v = tuple(zip(*([Luv_to_uv(x) for x in Luvs])))

    wavelengths_chromaticity_coordinates = dict(zip(wavelengths,
                                                    tuple(zip(u, v))))

    pylab.plot(u, v, color='black', linewidth=2)
    pylab.plot((u[-1], u[0]), (v[-1], v[0]), color='black', linewidth=2)

    for label in labels:
        u, v = wavelengths_chromaticity_coordinates.get(label)
        pylab.plot(u, v, 'o', color='black', linewidth=2)

        index = bisect.bisect(wavelengths, label)
        left = wavelengths[index - 1] if index >= 0 else wavelengths[index]
        right = (wavelengths[index]
                 if index < len(wavelengths) else
                 wavelengths[-1])

        dx = (wavelengths_chromaticity_coordinates.get(right)[0] -
              wavelengths_chromaticity_coordinates.get(left)[0])
        dy = (wavelengths_chromaticity_coordinates.get(right)[1] -
              wavelengths_chromaticity_coordinates.get(left)[1])

        norme = lambda x: x / np.linalg.norm(x)

        uv = np.array([u, v])
        direction = np.array((-dy, dx))

        normal = (np.array((-dy, dx))
                  if np.dot(norme(uv - equal_energy),
                            norme(direction)) > 0 else
                  np.array((dy, -dx)))
        normal = norme(normal)
        normal /= 25

        pylab.plot([u, u + normal[0] * 0.75],
                   [v, v + normal[1] * 0.75],
                   color='black',
                   linewidth=1.5)
        pylab.text(u + normal[0],
                   v + normal[1],
                   label,
                   clip_on=True,
                   ha='left' if normal[0] >= 0 else 'right',
                   va='center',
                   fontdict={'size': 'small'})

    settings = {
        'title': 'CIE 1976 UCS Chromaticity Diagram - {0}'.format(name),
        'x_label': 'CIE u"',
        'y_label': 'CIE v"',
        'x_ticker': True,
        'y_ticker': True,
        'grid': True,
        'bounding_box': [-0.1, .7, -.1, .7],
        'bbox_inches': 'tight',
        'pad_inches': 0}
    settings.update(kwargs)

    bounding_box(**settings)
    aspect(**settings)

    return display(**settings)
示例#25
0
def CIE_1931_chromaticity_diagram_plot(
        cmfs='CIE 1931 2 Degree Standard Observer', **kwargs):
    """
    Plots the *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> CIE_1931_chromaticity_diagram_plot()  # doctest: +SKIP
    True

    """

    cmfs, name = get_cmfs(cmfs), cmfs

    image = matplotlib.image.imread(
        os.path.join(PLOTTING_RESOURCES_DIRECTORY,
                     'CIE_1931_Chromaticity_Diagram_{0}_Small.png'.format(
                         cmfs.name.replace(' ', '_'))))
    pylab.imshow(image, interpolation='nearest', extent=(0, 1, 0, 1))

    labels = (
        [390, 460, 470, 480, 490, 500, 510, 520, 540, 560, 580, 600, 620,
         700])

    wavelengths = cmfs.wavelengths
    equal_energy = np.array([1 / 3] * 2)

    XYZs = [value for key, value in cmfs]

    x, y = tuple(zip(*([XYZ_to_xy(x) for x in XYZs])))

    wavelengths_chromaticity_coordinates = dict(
        tuple(zip(wavelengths, tuple(zip(x, y)))))

    pylab.plot(x, y, color='black', linewidth=2)
    pylab.plot((x[-1], x[0]), (y[-1], y[0]), color='black', linewidth=2)

    for label in labels:
        x, y = wavelengths_chromaticity_coordinates.get(label)
        pylab.plot(x, y, 'o', color='black', linewidth=2)

        index = bisect.bisect(wavelengths, label)
        left = wavelengths[index - 1] if index >= 0 else wavelengths[index]
        right = (wavelengths[index]
                 if index < len(wavelengths) else
                 wavelengths[-1])

        dx = (wavelengths_chromaticity_coordinates.get(right)[0] -
              wavelengths_chromaticity_coordinates.get(left)[0])
        dy = (wavelengths_chromaticity_coordinates.get(right)[1] -
              wavelengths_chromaticity_coordinates.get(left)[1])

        norme = lambda x: x / np.linalg.norm(x)

        xy = np.array([x, y])
        direction = np.array((-dy, dx))

        normal = (np.array((-dy, dx))
                  if np.dot(norme(xy - equal_energy),
                            norme(direction)) > 0 else
                  np.array((dy, -dx)))
        normal = norme(normal)
        normal /= 25

        pylab.plot([x, x + normal[0] * 0.75],
                   [y, y + normal[1] * 0.75],
                   color='black',
                   linewidth=1.5)
        pylab.text(x + normal[0],
                   y + normal[1],
                   label,
                   clip_on=True,
                   ha='left' if normal[0] >= 0 else 'right',
                   va='center',
                   fontdict={'size': 'small'})

    settings = {
        'title': 'CIE 1931 Chromaticity Diagram - {0}'.format(name),
        'x_label': 'CIE x',
        'y_label': 'CIE y',
        'x_ticker': True,
        'y_ticker': True,
        'grid': True,
        'bounding_box': [-0.1, 0.9, -0.1, 0.9],
        'bbox_inches': 'tight',
        'pad_inches': 0}
    settings.update(kwargs)

    bounding_box(**settings)
    aspect(**settings)

    return display(**settings)
示例#26
0
def the_blue_sky_plot(cmfs='CIE 1931 2 Degree Standard Observer', **kwargs):
    """
    Plots the blue sky.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> the_blue_sky_plot()  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    cmfs, name = get_cmfs(cmfs), cmfs

    ASTM_G_173_spd = ASTM_G_173_ETR.clone()
    rayleigh_spd = rayleigh_scattering_spd()
    ASTM_G_173_spd.align(rayleigh_spd.shape)

    spd = rayleigh_spd * ASTM_G_173_spd

    matplotlib.pyplot.subplots_adjust(hspace=0.4)

    matplotlib.pyplot.figure(1)
    matplotlib.pyplot.subplot(211)

    settings = {
        'title': 'The Blue Sky - Synthetic Spectral Power Distribution',
        'y_label': u'W / m-2 / nm-1',
        'standalone': False
    }
    settings.update(kwargs)

    single_spd_plot(spd, name, **settings)

    matplotlib.pyplot.subplot(212)

    settings = {
        'title':
        'The Blue Sky - Colour',
        'x_label': ('The sky is blue because molecules in the atmosphere '
                    'scatter shorter wavelengths more than longer ones.\n'
                    'The synthetic spectral power distribution is computed as '
                    'follows: '
                    '(ASTM G-173 ETR * Standard Air Rayleigh Scattering).'),
        'y_label':
        '',
        'aspect':
        None,
        'standalone':
        False
    }

    blue_sky_color = XYZ_to_sRGB(spectral_to_XYZ(spd))
    single_colour_plot(ColourParameter('', normalise(blue_sky_color)),
                       **settings)

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

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#27
0
def CIE_1931_chromaticity_diagram_colours_plot(
        surface=1,
        samples=4096,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots the *CIE 1931 Chromaticity Diagram* colours.

    Parameters
    ----------
    surface : numeric, optional
        Generated markers surface.
    samples : numeric, optional
        Samples count on one axis.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> CIE_1931_chromaticity_diagram_colours_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (64, 64)}
    settings.update(kwargs)

    canvas(**settings)

    cmfs = get_cmfs(cmfs)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    triangulation = Delaunay(XYZ_to_xy(cmfs.values, illuminant),
                             qhull_options='QJ')
    xx, yy = np.meshgrid(np.linspace(0, 1, samples),
                         np.linspace(0, 1, samples))
    xy = tstack((xx, yy))
    xy = xy[triangulation.find_simplex(xy) > 0]

    XYZ = xy_to_XYZ(xy)

    RGB = normalise_maximum(XYZ_to_sRGB(XYZ, illuminant), axis=-1)

    x_dot, y_dot = tsplit(xy)

    pylab.scatter(x_dot, y_dot, color=RGB, s=surface)

    settings.update({
        'x_ticker': False,
        'y_ticker': False,
        'bounding_box': (0, 1, 0, 1)
    })
    settings.update(kwargs)

    ax = matplotlib.pyplot.gca()
    matplotlib.pyplot.setp(ax, frame_on=False)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#28
0
def blackbody_spectral_radiance_plot(
        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.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> blackbody_spectral_radiance_plot()  # doctest: +SKIP
    """

    canvas(**kwargs)

    cmfs = get_cmfs(cmfs)

    matplotlib.pyplot.subplots_adjust(hspace=0.4)

    spd = blackbody_spd(temperature, cmfs.shape)

    matplotlib.pyplot.figure(1)
    matplotlib.pyplot.subplot(211)

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

    single_spd_plot(spd, cmfs.name, **settings)

    XYZ = spectral_to_XYZ(spd, cmfs)
    RGB = normalise_maximum(XYZ_to_sRGB(XYZ / 100))

    matplotlib.pyplot.subplot(212)

    settings = {
        'title': '{0} - Colour'.format(blackbody),
        'x_label': '{0}K'.format(temperature),
        'y_label': '',
        'aspect': None,
        'standalone': False
    }

    single_colour_plot(ColourParameter(name='', RGB=RGB), **settings)

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

    boundaries(**settings)
    decorate(**settings)
    return display(**settings)
示例#29
0
def multi_lightness_function_plot(functions=None, **kwargs):
    """
    Plots given *Lightness* functions.

    Parameters
    ----------
    functions : array_like, optional
        *Lightness* functions to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Raises
    ------
    KeyError
        If one of the given *Lightness* function is not found in the factory
        *Lightness* functions.

    Examples
    --------
    >>> fs = ('CIE 1976', 'Wyszecki 1963')
    >>> multi_lightness_function_plot(fs)  # doctest: +SKIP
    True
    """

    settings = {
        'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if functions is None:
        functions = ('CIE 1976', 'Wyszecki 1963')

    samples = np.linspace(0, 100, 1000)
    for function in functions:
        function, name = LIGHTNESS_METHODS.get(function), function
        if function is None:
            raise KeyError(
                ('"{0}" "Lightness" function not found in factory '
                 '"Lightness" functions: "{1}".').format(
                    name, sorted(LIGHTNESS_METHODS.keys())))

        pylab.plot(samples,
                   [function(x) for x in samples],
                   label='{0}'.format(name),
                   linewidth=2)

    settings.update({
        'title': '{0} - Lightness Functions'.format(', '.join(functions)),
        'x_label': 'Luminance Y',
        'y_label': 'Lightness L*',
        'x_tighten': True,
        'legend': True,
        'legend_location': 'upper left',
        'grid': True,
        'limits': (0, 100, 0, 100),
        'aspect': 'equal'})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#30
0
def the_blue_sky_plot(
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots the blue sky.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> the_blue_sky_plot()  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    cmfs, name = get_cmfs(cmfs), cmfs

    ASTM_G_173_spd = ASTM_G_173_ETR.clone()
    rayleigh_spd = rayleigh_scattering_spd()
    ASTM_G_173_spd.align(rayleigh_spd.shape)

    spd = rayleigh_spd * ASTM_G_173_spd

    matplotlib.pyplot.subplots_adjust(hspace=0.4)

    matplotlib.pyplot.figure(1)
    matplotlib.pyplot.subplot(211)

    settings = {
        'title': 'The Blue Sky - Synthetic Spectral Power Distribution',
        'y_label': u'W / m-2 / nm-1',
        'standalone': False}
    settings.update(kwargs)

    single_spd_plot(spd, name, **settings)

    matplotlib.pyplot.subplot(212)

    settings = {
        'title': 'The Blue Sky - Colour',
        'x_label': ('The sky is blue because molecules in the atmosphere '
                    'scatter shorter wavelengths more than longer ones.\n'
                    'The synthetic spectral power distribution is computed as '
                    'follows: '
                    '(ASTM G-173 ETR * Standard Air Rayleigh Scattering).'),
        'y_label': '',
        'aspect': None,
        'standalone': False}

    blue_sky_color = XYZ_to_sRGB(spectral_to_XYZ(spd))
    single_colour_plot(colour_parameter('', normalise(blue_sky_color)),
                       **settings)

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

    boundaries(**settings)
    decorate(**settings)
    return display(**settings)
示例#31
0
文件: quality.py 项目: KevinJW/colour
def colour_rendering_index_bars_plot(illuminant, **kwargs):
    """
    Plots the *colour rendering index* of given illuminant.

    Parameters
    ----------
    illuminant : SpectralPowerDistribution
        Illuminant to plot the *colour rendering index*.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2')
    >>> colour_rendering_index_bars_plot(illuminant)  # doctest: +SKIP
    True
    """

    figure, axis = matplotlib.pyplot.subplots()

    cri, colour_rendering_indexes, additional_data = \
        colour_rendering_index(illuminant, additional_data=True)

    colours = ([[1] * 3] + [normalise(XYZ_to_sRGB(x.XYZ / 100))
                            for x in additional_data[0]])
    x, y = tuple(zip(*sorted(colour_rendering_indexes.items(),
                             key=lambda x: x[0])))
    x, y = np.array([0] + list(x)), np.array(
        [cri] + list(y))

    positive = True if np.sign(min(y)) in (0, 1) else False

    width = 0.5
    bars = pylab.bar(x, y, color=colours, width=width)
    y_ticks_steps = 10
    pylab.yticks(range(0 if positive else -100,
                       100 + y_ticks_steps,
                       y_ticks_steps))
    pylab.xticks(x + width / 2,
                 ['Ra'] + ['R{0}'.format(index) for index in x[1:]])

    def label_bars(bars):
        """
        Add labels above given bars.
        """
        for bar in bars:
            y = bar.get_y()
            height = bar.get_height()
            value = height if np.sign(y) in (0, 1) else -height
            axis.text(bar.get_x() + bar.get_width() / 2,
                      0.025 * height + height + y,
                      '{0:.1f}'.format(value),
                      ha='center', va='bottom')

    label_bars(bars)

    settings = {
        'title': 'Colour Rendering Index - {0}'.format(illuminant.name),
        'grid': True,
        'x_tighten': True,
        'y_tighten': True,
        'limits': [-width, 14 + width * 2, -10 if positive else -110,
                   110]}
    settings.update(kwargs)

    bounding_box(**settings)
    aspect(**settings)
    return display(**settings)
示例#32
0
文件: volume.py 项目: brehm/colour
def RGB_colourspaces_gamuts_plot(colourspaces=None,
                                 reference_colourspace='CIE xyY',
                                 segments=8,
                                 display_grid=True,
                                 grid_segments=10,
                                 spectral_locus=False,
                                 spectral_locus_colour=None,
                                 cmfs='CIE 1931 2 Degree Standard Observer',
                                 **kwargs):
    """
    Plots given *RGB* colourspaces gamuts in given reference colourspace.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT'}**,
        Reference colourspace to plot the gamuts into.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    display_grid : bool, optional
        Display a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    spectral_locus : bool, optional
        Is spectral locus line plotted.
    spectral_locus_colour : array_like, optional
        Spectral locus line colour.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.
    \**kwargs : dict, optional
        **{'face_colours', 'edge_colours', 'edge_alpha', 'face_alpha'}**,
        Arguments for each given colourspace where each key has an array_like
        value such as: ``{ 'face_colours': (None, (0.5, 0.5, 1.0)),
        'edge_colours': (None, (0.5, 0.5, 1.0)), 'edge_alpha': (0.5, 1.0),
        'face_alpha': (0.0, 1.0)}``

        **{'grid_face_colours', 'grid_edge_colours', 'grid_face_alpha',
        'grid_edge_alpha', 'x_axis_colour', 'y_axis_colour', 'x_ticks_colour',
        'y_ticks_colour', 'x_label_colour', 'y_label_colour',
        'ticks_and_label_location'}**,
        Arguments for the nadir grid such as ``{'grid_face_colours':
        (0.25, 0.25, 0.25), 'grid_edge_colours': (0.50, 0.50, 0.50),
        'grid_face_alpha': 0.1, 'grid_edge_alpha': 0.5, 'x_axis_colour':
        (0.0, 0.0, 0.0, 1.0), 'y_axis_colour': (0.0, 0.0, 0.0, 1.0),
        'x_ticks_colour': (0.0, 0.0, 0.0, 0.85), 'y_ticks_colour':
        (0.0, 0.0, 0.0, 0.85), 'x_label_colour': (0.0, 0.0, 0.0, 0.85),
        'y_label_colour': (0.0, 0.0, 0.0, 0.85), 'ticks_and_label_location':
        ('-x', '-y')}``

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_gamuts_plot(c)  # doctest: +SKIP
    True
    """

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg')

    count_c = len(colourspaces)
    settings = Structure(
        **{'face_colours': [None] * count_c,
           'edge_colours': [None] * count_c,
           'face_alpha': [1] * count_c,
           'edge_alpha': [1] * count_c,
           'title': '{0} - {1} Reference Colourspace'.format(
               ', '.join(colourspaces), reference_colourspace)})
    settings.update(kwargs)

    figure = matplotlib.pyplot.figure()
    axes = figure.add_subplot(111, projection='3d')

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    points = np.zeros((4, 3))
    if spectral_locus:
        cmfs = get_cmfs(cmfs)
        XYZ = cmfs.values

        points = XYZ_to_reference_colourspace(XYZ,
                                              illuminant,
                                              reference_colourspace)

        points[np.isnan(points)] = 0

        c = ((0.0, 0.0, 0.0, 0.5)
             if spectral_locus_colour is None else
             spectral_locus_colour)

        pylab.plot(points[..., 0],
                   points[..., 1],
                   points[..., 2],
                   color=c,
                   linewidth=2,
                   zorder=1)
        pylab.plot((points[-1][0], points[0][0]),
                   (points[-1][1], points[0][1]),
                   (points[-1][2], points[0][2]),
                   color=c,
                   linewidth=2,
                   zorder=1)

    quads, RGB_f, RGB_e = [], [], []
    for i, colourspace in enumerate(colourspaces):
        colourspace = get_RGB_colourspace(colourspace)
        quads_c, RGB = RGB_identity_cube(width_segments=segments,
                                         height_segments=segments,
                                         depth_segments=segments)

        XYZ = RGB_to_XYZ(
            quads_c,
            colourspace.whitepoint,
            colourspace.whitepoint,
            colourspace.RGB_to_XYZ_matrix)

        quads.extend(XYZ_to_reference_colourspace(XYZ,
                                                  colourspace.whitepoint,
                                                  reference_colourspace))

        if settings.face_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.face_colours[i]

        RGB_f.extend(np.hstack(
            (RGB, np.full((RGB.shape[0], 1, np.float_),
                          settings.face_alpha[i]))))

        if settings.edge_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.edge_colours[i]

        RGB_e.extend(np.hstack(
            (RGB, np.full((RGB.shape[0], 1, np.float_),
                          settings.edge_alpha[i]))))

    quads = np.asarray(quads)
    quads[np.isnan(quads)] = 0

    if quads.size != 0:
        for i, axis in enumerate('xyz'):
            min_a = np.min(np.vstack((quads[..., i], points[..., i])))
            max_a = np.max(np.vstack((quads[..., i], points[..., i])))
            getattr(axes, 'set_{}lim'.format(axis))((min_a, max_a))

    labels = REFERENCE_COLOURSPACES_TO_LABELS[reference_colourspace]
    for i, axis in enumerate('xyz'):
        getattr(axes, 'set_{}label'.format(axis))(labels[i])

    if display_grid:
        if reference_colourspace == 'CIE Lab':
            limits = np.array([[-450, 450], [-450, 450]])
        elif reference_colourspace == 'CIE Luv':
            limits = np.array([[-650, 650], [-650, 650]])
        elif reference_colourspace == 'CIE UVW':
            limits = np.array([[-850, 850], [-850, 850]])
        else:
            limits = np.array([[-1.5, 1.5], [-1.5, 1.5]])

        quads_g, RGB_gf, RGB_ge = nadir_grid(
            limits, grid_segments, labels, axes, **settings)
        quads = np.vstack((quads_g, quads))
        RGB_f = np.vstack((RGB_gf, RGB_f))
        RGB_e = np.vstack((RGB_ge, RGB_e))

    collection = Poly3DCollection(quads)
    collection.set_facecolors(RGB_f)
    collection.set_edgecolors(RGB_e)

    axes.add_collection3d(collection)

    settings.update({
        'camera_aspect': 'equal',
        'no_axes3d': True})
    settings.update(kwargs)

    camera(**settings)
    decorate(**settings)

    return display(**settings)
示例#33
0
def RGB_scatter_plot(RGB,
                     colourspace,
                     reference_colourspace='CIE xyY',
                     colourspaces=None,
                     segments=8,
                     display_grid=True,
                     grid_segments=10,
                     spectral_locus=False,
                     spectral_locus_colour=None,
                     points_size=12,
                     cmfs='CIE 1931 2 Degree Standard Observer',
                     **kwargs):
    """
    Plots given *RGB* colourspace array in a scatter plot.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace for colour conversion.
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    display_grid : bool, optional
        Display a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    spectral_locus : bool, optional
        Is spectral locus line plotted.
    spectral_locus_colour : array_like, optional
        Spectral locus line colour.
    points_size : numeric, optional
        Scatter points size.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.

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

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> c = 'Rec. 709'
    >>> RGB_scatter_plot(c)  # doctest: +SKIP
    """

    colourspace = get_RGB_colourspace(colourspace)

    if colourspaces is None:
        colourspaces = (colourspace.name, )

    count_c = len(colourspaces)
    settings = Structure(
        **{
            'face_colours': [None] * count_c,
            'edge_colours': [(0.25, 0.25, 0.25)] * count_c,
            'face_alpha': [0.0] * count_c,
            'edge_alpha': [0.1] * count_c,
            'standalone': False
        })
    settings.update(kwargs)

    RGB_colourspaces_gamuts_plot(colourspaces=colourspaces,
                                 reference_colourspace=reference_colourspace,
                                 segments=segments,
                                 display_grid=display_grid,
                                 grid_segments=grid_segments,
                                 spectral_locus=spectral_locus,
                                 spectral_locus_colour=spectral_locus_colour,
                                 cmfs=cmfs,
                                 **settings)

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)

    axes = matplotlib.pyplot.gca()
    axes.scatter(points[..., 0],
                 points[..., 1],
                 points[..., 2],
                 color=np.reshape(RGB, (-1, 3)),
                 s=points_size)

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

    camera(**settings)
    decorate(**settings)

    return display(**settings)
示例#34
0
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs):
    """
    Plots the *Colour Rendering Index* (CRI) of given illuminants or light
    sources spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *Colour Rendering Index* (CRI).

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    labels : bool, optional
        {:func:`colour_quality_bars_plot`},
        Add labels above bars.
    hatching : bool or None, optional
        {:func:`colour_quality_bars_plot`},
        Use hatching for the bars.
    hatching_repeat : int, optional
        {:func:`colour_quality_bars_plot`},
        Hatching pattern repeat.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS['F2']
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS['Kinoton 75P']
    >>> multi_spd_colour_rendering_index_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [
        colour_rendering_index(spd, additional_data=True) for spd in spds
    ]

    # *colour rendering index* colorimetry data tristimulus values are
    # computed in [0, 100] domain however `colour_quality_bars_plot` expects
    # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition
    # agnostic from the colour quality data, we update the test spd
    # colorimetry data tristimulus values domain.
    for specification in specifications:
        colorimetry_data = specification.colorimetry_data
        for i, c_d in enumerate(colorimetry_data[0]):
            colorimetry_data[0][i] = TCS_ColorimetryData(
                c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW)

    colour_quality_bars_plot(specifications, **settings)

    settings = {
        'title':
        'Colour Rendering Index - {0}'.format(', '.join(
            [spd.title for spd in spds]))
    }
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
示例#35
0
def multi_spd_plot(spds,
                   cmfs='CIE 1931 2 Degree Standard Observer',
                   use_spds_colours=False,
                   normalise_spds_colours=False,
                   **kwargs):
    """
    Plots given spectral power distributions.

    Parameters
    ----------
    spds : list
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectrum creation.
    use_spds_colours : bool, optional
        Use spectral power distributions colours.
    normalise_spds_colours : bool
        Should spectral power distributions colours normalised.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import SpectralPowerDistribution
    >>> data1 = {400: 0.0641, 420: 0.0645, 440: 0.0562}
    >>> data2 = {400: 0.134, 420: 0.789, 440: 1.289}
    >>> spd1 = SpectralPowerDistribution('Custom1', data1)
    >>> spd2 = SpectralPowerDistribution('Custom2', data2)
    >>> multi_spd_plot([spd1, spd2])  # doctest: +SKIP
    """

    canvas(**kwargs)

    cmfs = get_cmfs(cmfs)

    if use_spds_colours:
        illuminant = ILLUMINANTS_RELATIVE_SPDS.get('D65')

    x_limit_min, x_limit_max, y_limit_min, y_limit_max = [], [], [], []
    for spd in spds:
        wavelengths, values = tuple(zip(*spd.items))

        shape = spd.shape
        x_limit_min.append(shape.start)
        x_limit_max.append(shape.end)
        y_limit_min.append(min(values))
        y_limit_max.append(max(values))

        if use_spds_colours:
            XYZ = spectral_to_XYZ(spd, cmfs, illuminant) / 100
            if normalise_spds_colours:
                XYZ = normalise_maximum(XYZ, clip=False)
            RGB = np.clip(XYZ_to_sRGB(XYZ), 0, 1)

            pylab.plot(wavelengths,
                       values,
                       color=RGB,
                       label=spd.title,
                       linewidth=2)
        else:
            pylab.plot(wavelengths, values, label=spd.title, linewidth=2)

    settings = {
        'x_label':
        'Wavelength $\\lambda$ (nm)',
        'y_label':
        'Spectral Power Distribution',
        'x_tighten':
        True,
        'legend':
        True,
        'legend_location':
        'upper left',
        'limits': (min(x_limit_min), max(x_limit_max), min(y_limit_min),
                   max(y_limit_max))
    }
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#36
0
文件: models.py 项目: KevinJW/colour
def colourspaces_CIE_1931_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given colourspaces in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : list, optional
        Colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> csps = ['sRGB', 'ACES RGB']
    >>> colourspaces_CIE_1931_chromaticity_diagram_plot(csps)  # doctest: +SKIP
    True
    """

    if colourspaces is None:
        colourspaces = ('sRGB', 'ACES RGB', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    settings = {'title': '{0} - {1}'.format(', '.join(colourspaces), name),
                'standalone': False}
    settings.update(kwargs)

    if not CIE_1931_chromaticity_diagram_plot(**settings):
        return

    x_limit_min, x_limit_max = [-0.1], [0.9]
    y_limit_min, y_limit_max = [-0.1], [0.9]
    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            x, y = tuple(zip(*POINTER_GAMUT_DATA))
            pylab.plot(x,
                       y,
                       label='Pointer Gamut',
                       color='0.95',
                       linewidth=2)
            pylab.plot([x[-1],
                        x[0]],
                       [y[-1],
                        y[0]],
                       color='0.95',
                       linewidth=2)
        else:
            colourspace, name = get_RGB_colourspace(
                colourspace), colourspace

            random_colour = lambda: float(random.randint(64, 224)) / 255
            r, g, b = random_colour(), random_colour(), random_colour()

            primaries = colourspace.primaries
            whitepoint = colourspace.whitepoint

            pylab.plot([whitepoint[0], whitepoint[0]],
                       [whitepoint[1], whitepoint[1]],
                       color=(r, g, b),
                       label=colourspace.name,
                       linewidth=2)
            pylab.plot([whitepoint[0], whitepoint[0]],
                       [whitepoint[1], whitepoint[1]],
                       'o',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot([primaries[0, 0], primaries[1, 0]],
                       [primaries[0, 1], primaries[1, 1]],
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot([primaries[1, 0], primaries[2, 0]],
                       [primaries[1, 1], primaries[2, 1]],
                       'o-',
                       color=(r, g, b),
                       linewidth=2)
            pylab.plot([primaries[2, 0], primaries[0, 0]],
                       [primaries[2, 1], primaries[0, 1]],
                       'o-',
                       color=(r, g, b),
                       linewidth=2)

            x_limit_min.append(np.amin(primaries[:, 0]))
            y_limit_min.append(np.amin(primaries[:, 1]))
            x_limit_max.append(np.amax(primaries[:, 0]))
            y_limit_max.append(np.amax(primaries[:, 1]))

    settings.update({'legend': True,
                     'legend_location': 'upper right',
                     'x_tighten': True,
                     'y_tighten': True,
                     'limits': [min(x_limit_min), max(x_limit_max),
                                min(y_limit_min), max(y_limit_max)],
                     'margins': [-0.05, 0.05, -0.05, 0.05],
                     'standalone': True})

    bounding_box(**settings)
    aspect(**settings)

    return display(**settings)
示例#37
0
def multi_lightness_function_plot(functions=None, **kwargs):
    """
    Plots given *Lightness* functions.

    Parameters
    ----------
    functions : array_like, optional
        *Lightness* functions to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If one of the given *Lightness* function is not found in the factory
        *Lightness* functions.

    Examples
    --------
    >>> fs = ('CIE 1976', 'Wyszecki 1963')
    >>> multi_lightness_function_plot(fs)  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if functions is None:
        functions = ('CIE 1976', 'Wyszecki 1963')

    samples = np.linspace(0, 100, 1000)
    for function in functions:
        function, name = LIGHTNESS_METHODS.get(function), function
        if function is None:
            raise KeyError(('"{0}" "Lightness" function not found in factory '
                            '"Lightness" functions: "{1}".').format(
                                name, sorted(LIGHTNESS_METHODS.keys())))

        pylab.plot(samples, [function(x) for x in samples],
                   label='{0}'.format(name),
                   linewidth=2)

    settings.update({
        'title':
        '{0} - Lightness Functions'.format(', '.join(functions)),
        'x_label':
        'Relative Luminance Y',
        'y_label':
        'Lightness',
        'x_tighten':
        True,
        'legend':
        True,
        'legend_location':
        'upper left',
        'grid':
        True,
        'limits': (0, 100, 0, 100),
        'aspect':
        'equal'
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#38
0
def multi_cctf_plot(colourspaces=None, decoding_cctf=False, **kwargs):
    """
    Plots given colourspaces colour component transfer functions.

    Parameters
    ----------
    colourspaces : array_like, optional
        Colourspaces colour component transfer function to plot.
    decoding_cctf : bool
        Plot decoding colour component transfer function instead.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> multi_cctf_plot(['Rec. 709', 'sRGB'])  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'sRGB')

    samples = np.linspace(0, 1, 1000)
    for colourspace in colourspaces:
        colourspace = get_RGB_colourspace(colourspace)

        RGBs = (colourspace.decoding_cctf(samples)
                if decoding_cctf else colourspace.encoding_cctf(samples))

        pylab.plot(samples,
                   RGBs,
                   label=u'{0}'.format(colourspace.name),
                   linewidth=2)

    settings.update({
        'title':
        '{0} - {1} CCTFs'.format(', '.join(colourspaces),
                                 'Decoding' if decoding_cctf else 'Encoding'),
        'x_tighten':
        True,
        'x_label':
        'Signal Value' if decoding_cctf else 'Tristimulus Value',
        'y_label':
        'Tristimulus Value' if decoding_cctf else 'Signal Value',
        'legend':
        True,
        'legend_location':
        'upper left',
        'grid':
        True,
        'limits': (0, 1, 0, 1),
        'aspect':
        'equal'
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#39
0
def colour_checker_plot(colour_checker='ColorChecker 2005', **kwargs):
    """
    Plots given colour checker.

    Parameters
    ----------
    colour_checker : unicode, optional
        Color checker name.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    width : numeric, optional
        {:func:`multi_colour_plot`},
        Colour polygon width.
    height : numeric, optional
        {:func:`multi_colour_plot`},
        Colour polygon height.
    spacing : numeric, optional
        {:func:`multi_colour_plot`},
        Colour polygons spacing.
    across : int, optional
        {:func:`multi_colour_plot`},
        Colour polygons count per row.
    text_display : bool, optional
        {:func:`multi_colour_plot`},
        Display colour text.
    text_size : numeric, optional
        {:func:`multi_colour_plot`},
        Colour text size.
    text_offset : numeric, optional
        {:func:`multi_colour_plot`},
        Colour text offset.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If the given colour rendition chart is not found in the factory colour
        rendition charts.

    Examples
    --------
    >>> colour_checker_plot()  # doctest: +SKIP
    """

    canvas(**kwargs)

    colour_checker, name = COLOURCHECKERS.get(colour_checker), colour_checker
    if colour_checker is None:
        raise KeyError(('Colour checker "{0}" not found in '
                        'factory colour checkers: "{1}".').format(
                            name, sorted(COLOURCHECKERS.keys())))

    _name, data, illuminant = colour_checker
    colour_parameters = []
    for _index, label, xyY in data:
        XYZ = xyY_to_XYZ(xyY)
        RGB = XYZ_to_sRGB(XYZ, illuminant)

        colour_parameters.append(
            ColourParameter(label.title(), np.clip(np.ravel(RGB), 0, 1)))

    background_colour = '0.1'
    width = height = 1.0
    spacing = 0.25
    across = 6

    settings = {
        'standalone': False,
        'width': width,
        'height': height,
        'spacing': spacing,
        'across': across,
        'text_size': 8,
        'background_colour': background_colour,
        'margins': (-0.125, 0.125, -0.5, 0.125)
    }
    settings.update(kwargs)

    multi_colour_plot(colour_parameters, **settings)

    text_x = width * (across / 2) + (across * (spacing / 2)) - spacing / 2
    text_y = -(len(colour_parameters) / across + spacing / 2)

    pylab.text(
        text_x,
        text_y,
        '{0} - {1} - Colour Rendition Chart'.format(
            name, RGB_COLOURSPACES['sRGB'].name),
        color='0.95',
        clip_on=True,
        ha='center')

    settings.update({
        'title': name,
        'facecolor': background_colour,
        'edgecolor': None,
        'standalone': True
    })

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#40
0
def RGB_scatter_plot(RGB,
                     colourspace,
                     reference_colourspace='CIE xyY',
                     colourspaces=None,
                     segments=8,
                     display_grid=True,
                     grid_segments=10,
                     spectral_locus=False,
                     spectral_locus_colour=None,
                     points_size=12,
                     cmfs='CIE 1931 2 Degree Standard Observer',
                     **kwargs):
    """
    Plots given *RGB* colourspace array in a scatter plot.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT'}**,
        Reference colourspace for colour conversion.
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    display_grid : bool, optional
        Display a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    spectral_locus : bool, optional
        Is spectral locus line plotted.
    spectral_locus_colour : array_like, optional
        Spectral locus line colour.
    points_size : numeric, optional
        Scatter points size.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.
    \**kwargs : dict, optional
        **{'face_colours', 'edge_colours', 'edge_alpha', 'face_alpha'}**,
        Arguments for each given colourspace where each key has an array_like
        value such as: ``{ 'face_colours': (None, (0.5, 0.5, 1.0)),
        'edge_colours': (None, (0.5, 0.5, 1.0)), 'edge_alpha': (0.5, 1.0),
        'face_alpha': (0.0, 1.0)}``

        **{'grid_face_colours', 'grid_edge_colours', 'grid_face_alpha',
        'grid_edge_alpha', 'x_axis_colour', 'y_axis_colour', 'x_ticks_colour',
        'y_ticks_colour', 'x_label_colour', 'y_label_colour',
        'ticks_and_label_location'}**,
        Arguments for the nadir grid such as ``{'grid_face_colours':
        (0.25, 0.25, 0.25), 'grid_edge_colours': (0.50, 0.50, 0.50),
        'grid_face_alpha': 0.1, 'grid_edge_alpha': 0.5, 'x_axis_colour':
        (0.0, 0.0, 0.0, 1.0), 'y_axis_colour': (0.0, 0.0, 0.0, 1.0),
        'x_ticks_colour': (0.0, 0.0, 0.0, 0.85), 'y_ticks_colour':
        (0.0, 0.0, 0.0, 0.85), 'x_label_colour': (0.0, 0.0, 0.0, 0.85),
        'y_label_colour': (0.0, 0.0, 0.0, 0.85), 'ticks_and_label_location':
        ('-x', '-y')}``

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> c = 'Rec. 709'
    >>> RGB_scatter_plot(c)  # doctest: +SKIP
    True
    """

    colourspace = get_RGB_colourspace(colourspace)

    if colourspaces is None:
        colourspaces = (colourspace.name, )

    count_c = len(colourspaces)
    settings = Structure(
        **{
            'face_colours': [None] * count_c,
            'edge_colours': [(0.25, 0.25, 0.25)] * count_c,
            'face_alpha': [0.0] * count_c,
            'edge_alpha': [0.1] * count_c,
            'standalone': False
        })
    settings.update(kwargs)

    RGB_colourspaces_gamuts_plot(colourspaces=colourspaces,
                                 reference_colourspace=reference_colourspace,
                                 segments=segments,
                                 display_grid=display_grid,
                                 grid_segments=grid_segments,
                                 spectral_locus=spectral_locus,
                                 spectral_locus_colour=spectral_locus_colour,
                                 cmfs=cmfs,
                                 **settings)

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    points = XYZ_to_reference_colourspace(XYZ, colourspace.whitepoint,
                                          reference_colourspace)

    axes = matplotlib.pyplot.gca()
    axes.scatter(points[..., 0],
                 points[..., 1],
                 points[..., 2],
                 color=np.reshape(RGB, (-1, 3)),
                 s=points_size)

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

    camera(**settings)
    decorate(**settings)

    return display(**settings)
示例#41
0
def corresponding_chromaticities_prediction_plot(experiment=1,
                                                 model='Von Kries',
                                                 transform='CAT02',
                                                 **kwargs):
    """
    Plots given chromatic adaptation model corresponding chromaticities
    prediction.

    Parameters
    ----------
    experiment : int, optional
        Corresponding chromaticities prediction experiment number.
    model : unicode, optional
        Corresponding chromaticities prediction model name.
    transform : unicode, optional
        Transformation to use with Von Kries chromatic adaptation model.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> corresponding_chromaticities_prediction_plot()  # doctest: +SKIP
    True
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    model, name = (get_corresponding_chromaticities_prediction_model(model),
                   model)

    settings.update({
        'title':
        (('Corresponding Chromaticities Prediction\n{0} ({1}) - '
          'Experiment {2}\nCIE 1976 UCS Chromaticity Diagram').format(
              name, transform, experiment) if name.lower() in ('von kries',
                                                               'vonkries') else
         ('Corresponding Chromaticities Prediction\n{0} - '
          'Experiment {1}\nCIE 1976 UCS Chromaticity Diagram').format(
              name, experiment)),
        'standalone':
        False
    })
    settings.update(kwargs)

    CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    results = model(experiment, transform=transform)

    for result in results:
        name, uvp_t, uvp_m, uvp_p = result
        pylab.arrow(uvp_t[0],
                    uvp_t[1],
                    uvp_p[0] - uvp_t[0] - 0.1 * (uvp_p[0] - uvp_t[0]),
                    uvp_p[1] - uvp_t[1] - 0.1 * (uvp_p[1] - uvp_t[1]),
                    head_width=0.005,
                    head_length=0.005,
                    linewidth=0.5,
                    color='black')
        pylab.plot(uvp_t[0], uvp_t[1], 'o', color='white')
        pylab.plot(uvp_m[0], uvp_m[1], '^', color='white')
        pylab.plot(uvp_p[0], uvp_p[1], '^', color='black')
    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.1, 0.7),
        'standalone': True
    })

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#42
0
def planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
        illuminants=None, **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1960 UCS Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1960_UCS_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'C', 'E']
    >>> planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
    ...     ils)  # doctest: +SKIP
    """

    if illuminants is None:
        illuminants = ('A', 'C', 'E')

    cmfs = CMFS['CIE 1931 2 Degree Standard Observer']

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer'
                  ).format(', '.join(illuminants)) if illuminants else
                 ('Planckian Locus\nCIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer'),
        'standalone':
            False
    }
    settings.update(kwargs)

    CIE_1960_UCS_chromaticity_diagram_plot(**settings)

    start, end = 1667, 100000
    uv = np.array(
        [CCT_to_uv(x, 'Robertson 1968', D_uv=0)
         for x in np.arange(start, end + 250, 250)])  # yapf: disable

    pylab.plot(uv[..., 0], uv[..., 1], color='black', linewidth=2)

    for i in (1667, 2000, 2500, 3000, 4000, 6000, 10000):
        u0, v0 = CCT_to_uv(i, 'Robertson 1968', D_uv=-0.05)
        u1, v1 = CCT_to_uv(i, 'Robertson 1968', D_uv=0.05)
        pylab.plot((u0, u1), (v0, v1), color='black', linewidth=2)
        pylab.annotate(
            '{0}K'.format(i),
            xy=(u0, v0),
            xytext=(0, -10),
            color='black',
            textcoords='offset points',
            size='x-small')

    for illuminant in illuminants:
        xy = ILLUMINANTS.get(cmfs.name).get(illuminant)
        if xy is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS[cmfs.name].keys())))

        uv = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(xy)))

        pylab.plot(uv[0], uv[1], 'o', color='white', linewidth=2)

        pylab.annotate(
            illuminant,
            xy=(uv[0], uv[1]),
            xytext=(-50, 30),
            color='black',
            textcoords='offset points',
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=-0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.2, 0.6),
        'standalone': True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#43
0
文件: volume.py 项目: brehm/colour
def RGB_scatter_plot(RGB,
                     colourspace,
                     reference_colourspace='CIE xyY',
                     colourspaces=None,
                     segments=8,
                     display_grid=True,
                     grid_segments=10,
                     spectral_locus=False,
                     spectral_locus_colour=None,
                     points_size=12,
                     cmfs='CIE 1931 2 Degree Standard Observer',
                     **kwargs):
    """
    Plots given *RGB* colourspace array in a scatter plot.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT'}**,
        Reference colourspace for colour conversion.
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    display_grid : bool, optional
        Display a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    spectral_locus : bool, optional
        Is spectral locus line plotted.
    spectral_locus_colour : array_like, optional
        Spectral locus line colour.
    points_size : numeric, optional
        Scatter points size.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.
    \**kwargs : dict, optional
        **{'face_colours', 'edge_colours', 'edge_alpha', 'face_alpha'}**,
        Arguments for each given colourspace where each key has an array_like
        value such as: ``{ 'face_colours': (None, (0.5, 0.5, 1.0)),
        'edge_colours': (None, (0.5, 0.5, 1.0)), 'edge_alpha': (0.5, 1.0),
        'face_alpha': (0.0, 1.0)}``

        **{'grid_face_colours', 'grid_edge_colours', 'grid_face_alpha',
        'grid_edge_alpha', 'x_axis_colour', 'y_axis_colour', 'x_ticks_colour',
        'y_ticks_colour', 'x_label_colour', 'y_label_colour',
        'ticks_and_label_location'}**,
        Arguments for the nadir grid such as ``{'grid_face_colours':
        (0.25, 0.25, 0.25), 'grid_edge_colours': (0.50, 0.50, 0.50),
        'grid_face_alpha': 0.1, 'grid_edge_alpha': 0.5, 'x_axis_colour':
        (0.0, 0.0, 0.0, 1.0), 'y_axis_colour': (0.0, 0.0, 0.0, 1.0),
        'x_ticks_colour': (0.0, 0.0, 0.0, 0.85), 'y_ticks_colour':
        (0.0, 0.0, 0.0, 0.85), 'x_label_colour': (0.0, 0.0, 0.0, 0.85),
        'y_label_colour': (0.0, 0.0, 0.0, 0.85), 'ticks_and_label_location':
        ('-x', '-y')}``

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> c = 'Rec. 709'
    >>> RGB_scatter_plot(c)  # doctest: +SKIP
    True
    """

    colourspace = get_RGB_colourspace(colourspace)

    if colourspaces is None:
        colourspaces = (colourspace.name,)

    count_c = len(colourspaces)
    settings = Structure(
        **{'face_colours': [None] * count_c,
           'edge_colours': [(0.25, 0.25, 0.25)] * count_c,
           'face_alpha': [0.0] * count_c,
           'edge_alpha': [0.1] * count_c,
           'standalone': False})
    settings.update(kwargs)

    RGB_colourspaces_gamuts_plot(
        colourspaces=colourspaces,
        reference_colourspace=reference_colourspace,
        segments=segments,
        display_grid=display_grid,
        grid_segments=grid_segments,
        spectral_locus=spectral_locus,
        spectral_locus_colour=spectral_locus_colour,
        cmfs=cmfs,
        **settings)

    XYZ = RGB_to_XYZ(
        RGB,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.RGB_to_XYZ_matrix)

    points = XYZ_to_reference_colourspace(XYZ,
                                          colourspace.whitepoint,
                                          reference_colourspace)

    axes = matplotlib.pyplot.gca()
    axes.scatter(points[..., 0],
                 points[..., 1],
                 points[..., 2],
                 color=np.reshape(RGB, (-1, 3)),
                 s=points_size)

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

    camera(**settings)
    decorate(**settings)

    return display(**settings)
示例#44
0
def CIE_1931_chromaticity_diagram_plot(
        cmfs='CIE 1931 2 Degree Standard Observer',
        show_diagram_colours=True,
        **kwargs):
    """
    Plots the *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    show_diagram_colours : bool, optional
        Display the chromaticity diagram background colours.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> CIE_1931_chromaticity_diagram_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    cmfs = get_cmfs(cmfs)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    if show_diagram_colours:
        image = matplotlib.image.imread(
            os.path.join(PLOTTING_RESOURCES_DIRECTORY,
                         'CIE_1931_Chromaticity_Diagram_{0}.png'.format(
                             cmfs.name.replace(' ', '_'))))
        pylab.imshow(image, interpolation=None, extent=(0, 1, 0, 1))

    labels = (
        390, 460, 470, 480, 490, 500, 510, 520, 540, 560, 580, 600, 620, 700)

    wavelengths = cmfs.wavelengths
    equal_energy = np.array([1 / 3] * 2)

    xy = XYZ_to_xy(cmfs.values, illuminant)

    wavelengths_chromaticity_coordinates = dict(tuple(zip(wavelengths, xy)))

    pylab.plot(xy[..., 0], xy[..., 1], color='black', linewidth=2)
    pylab.plot((xy[-1][0], xy[0][0]),
               (xy[-1][1], xy[0][1]),
               color='black',
               linewidth=2)

    for label in labels:
        x, y = wavelengths_chromaticity_coordinates.get(label)
        pylab.plot(x, y, 'o', color='black', linewidth=2)

        index = bisect.bisect(wavelengths, label)
        left = wavelengths[index - 1] if index >= 0 else wavelengths[index]
        right = (wavelengths[index]
                 if index < len(wavelengths) else
                 wavelengths[-1])

        dx = (wavelengths_chromaticity_coordinates.get(right)[0] -
              wavelengths_chromaticity_coordinates.get(left)[0])
        dy = (wavelengths_chromaticity_coordinates.get(right)[1] -
              wavelengths_chromaticity_coordinates.get(left)[1])

        xy = np.array([x, y])
        direction = np.array([-dy, dx])

        normal = (np.array([-dy, dx])
                  if np.dot(normalise_vector(xy - equal_energy),
                            normalise_vector(direction)) > 0 else
                  np.array([dy, -dx]))
        normal = normalise_vector(normal)
        normal /= 25

        pylab.plot((x, x + normal[0] * 0.75),
                   (y, y + normal[1] * 0.75),
                   color='black',
                   linewidth=1.5)
        pylab.text(x + normal[0],
                   y + normal[1],
                   label,
                   color='black',
                   clip_on=True,
                   ha='left' if normal[0] >= 0 else 'right',
                   va='center',
                   fontdict={'size': 'small'})

    ticks = np.arange(-10, 10, 0.1)

    pylab.xticks(ticks)
    pylab.yticks(ticks)

    settings.update({
        'title': 'CIE 1931 Chromaticity Diagram - {0}'.format(cmfs.title),
        'x_label': 'CIE x',
        'y_label': 'CIE y',
        'grid': True,
        'bounding_box': (0, 1, 0, 1)})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#45
0
def multi_spd_colour_quality_scale_bars_plot(spds, **kwargs):
    """
    Plots the *Colour Quality Scale* (CQS) of given illuminants or light
    sources spectral power distributions.

    Parameters
    ----------
    spds : array_like
        Array of illuminants or light sources spectral power distributions to
        plot the *Colour Quality Scale* (CQS).

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    labels : bool, optional
        {:func:`colour_quality_bars_plot`},
        Add labels above bars.
    hatching : bool or None, optional
        {:func:`colour_quality_bars_plot`},
        Use hatching for the bars.
    hatching_repeat : int, optional
        {:func:`colour_quality_bars_plot`},
        Hatching pattern repeat.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import (
    ...     ILLUMINANTS_RELATIVE_SPDS,
    ...     LIGHT_SOURCES_RELATIVE_SPDS)
    >>> illuminant = ILLUMINANTS_RELATIVE_SPDS['F2']
    >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS['Kinoton 75P']
    >>> multi_spd_colour_quality_scale_bars_plot(  # doctest: +SKIP
    ...     [illuminant, light_source])
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    specifications = [
        colour_quality_scale(spd, additional_data=True) for spd in spds
    ]
    colour_quality_bars_plot(specifications, **settings)

    settings = {
        'title':
        'Colour Quality Scale - {0}'.format(', '.join(
            [spd.title for spd in spds]))
    }
    settings.update(kwargs)

    decorate(**settings)

    return display(**settings)
示例#46
0
def CIE_1976_UCS_chromaticity_diagram_plot(
        cmfs='CIE 1931 2 Degree Standard Observer',
        show_diagram_colours=True,
        **kwargs):
    """
    Plots the *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    show_diagram_colours : bool, optional
        Display the chromaticity diagram background colours.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> CIE_1976_UCS_chromaticity_diagram_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    cmfs = get_cmfs(cmfs)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    if show_diagram_colours:
        image = matplotlib.image.imread(
            os.path.join(PLOTTING_RESOURCES_DIRECTORY,
                         'CIE_1976_UCS_Chromaticity_Diagram_{0}.png'.format(
                             cmfs.name.replace(' ', '_'))))
        pylab.imshow(image, interpolation=None, extent=(0, 1, 0, 1))

    labels = (420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530,
              540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 680)

    wavelengths = cmfs.wavelengths
    equal_energy = np.array([1 / 3] * 2)

    uv = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant)

    wavelengths_chromaticity_coordinates = dict(zip(wavelengths, uv))

    pylab.plot(uv[..., 0], uv[..., 1], color='black', linewidth=2)
    pylab.plot((uv[-1][0], uv[0][0]),
               (uv[-1][1], uv[0][1]),
               color='black',
               linewidth=2)

    for label in labels:
        u, v = wavelengths_chromaticity_coordinates.get(label)
        pylab.plot(u, v, 'o', color='black', linewidth=2)

        index = bisect.bisect(wavelengths, label)
        left = wavelengths[index - 1] if index >= 0 else wavelengths[index]
        right = (wavelengths[index]
                 if index < len(wavelengths) else
                 wavelengths[-1])

        dx = (wavelengths_chromaticity_coordinates.get(right)[0] -
              wavelengths_chromaticity_coordinates.get(left)[0])
        dy = (wavelengths_chromaticity_coordinates.get(right)[1] -
              wavelengths_chromaticity_coordinates.get(left)[1])

        uv = np.array([u, v])
        direction = np.array([-dy, dx])

        normal = (np.array([-dy, dx])
                  if np.dot(normalise_vector(uv - equal_energy),
                            normalise_vector(direction)) > 0 else
                  np.array([dy, -dx]))
        normal = normalise_vector(normal)
        normal /= 25

        pylab.plot((u, u + normal[0] * 0.75),
                   (v, v + normal[1] * 0.75),
                   color='black',
                   linewidth=1.5)
        pylab.text(u + normal[0],
                   v + normal[1],
                   label,
                   color='black',
                   clip_on=True,
                   ha='left' if normal[0] >= 0 else 'right',
                   va='center',
                   fontdict={'size': 'small'})

    ticks = np.arange(-10, 10, 0.1)

    pylab.xticks(ticks)
    pylab.yticks(ticks)

    settings.update({
        'title': 'CIE 1976 UCS Chromaticity Diagram - {0}'.format(cmfs.title),
        'x_label': 'CIE u\'',
        'y_label': 'CIE v\'',
        'grid': True,
        'bounding_box': (0, 1, 0, 1)})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#47
0
def planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
        illuminants=None,
        **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1960 UCS Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.
    \*\*kwargs : \*\*
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'C', 'E']
    >>> planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(ils)  # noqa  # doctest: +SKIP
    True
    """

    if illuminants is None:
        illuminants = ('A', 'C', 'E')

    cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer').format(
            ', '.join(illuminants))
        if illuminants else
        ('Planckian Locus\nCIE 1960 UCS Chromaticity Diagram - '
         'CIE 1931 2 Degree Standard Observer'),
        'standalone': False}
    settings.update(kwargs)

    if not CIE_1960_UCS_chromaticity_diagram_plot(**settings):
        return

    xy_to_uv = lambda x: UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(x)))

    start, end = 1667, 100000
    uv = np.array([CCT_to_uv(x, 0, cmfs=cmfs)
                   for x in np.arange(start, end + 250, 250)])

    pylab.plot(uv[:, 0], uv[:, 1], color='black', linewidth=2)

    for i in [1667, 2000, 2500, 3000, 4000, 6000, 10000]:
        u0, v0 = CCT_to_uv(i, -0.05)
        u1, v1 = CCT_to_uv(i, 0.05)
        pylab.plot([u0, u1], [v0, v1], color='black', linewidth=2)
        pylab.annotate('{0}K'.format(i),
                       xy=(u0, v0),
                       xytext=(0, -10),
                       textcoords='offset points',
                       size='x-small')

    for illuminant in illuminants:
        uv = xy_to_uv(ILLUMINANTS.get(cmfs.name).get(illuminant))
        if uv is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS.get(cmfs.name).keys())))

        pylab.plot(uv[0], uv[1], 'o', color='white', linewidth=2)

        pylab.annotate(illuminant,
                       xy=(uv[0], uv[1]),
                       xytext=(-50, 30),
                       textcoords='offset points',
                       arrowprops=dict(arrowstyle='->',
                                       connectionstyle='arc3, rad=-0.2'))

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

    return display(**settings)
示例#48
0
def spds_CIE_1931_chromaticity_diagram_plot(
        spds,
        cmfs='CIE 1931 2 Degree Standard Observer',
        annotate=True,
        **kwargs):
    """
    Plots given spectral power distribution chromaticity coordinates into the
    *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    spds : array_like, optional
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    annotate : bool
        Should resulting chromaticity coordinates annotated with their
        respective spectral power distribution names.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> A = ILLUMINANTS_RELATIVE_SPDS['A']
    >>> D65 = ILLUMINANTS_RELATIVE_SPDS['D65']
    >>> spds_CIE_1931_chromaticity_diagram_plot([A, D65])  # doctest: +SKIP
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    CIE_1931_chromaticity_diagram_plot(cmfs=cmfs, **settings)

    for spd in spds:
        XYZ = spectral_to_XYZ(spd) / 100
        xy = XYZ_to_xy(XYZ)

        pylab.plot(xy[0], xy[1], 'o', color='white')

        if spd.name is not None and annotate:
            pylab.annotate(spd.name,
                           xy=xy,
                           xytext=(50, 30),
                           color='black',
                           textcoords='offset points',
                           arrowprops=dict(arrowstyle='->',
                                           connectionstyle='arc3, rad=0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.9, -0.1, 0.9),
        'standalone': True})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#49
0
def colour_checker_plot(colour_checker='ColorChecker 2005', **kwargs):
    """
    Plots given colour checker.

    Parameters
    ----------
    colour_checker : unicode, optional
        Color checker name.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Raises
    ------
    KeyError
        If the given colour rendition chart is not found in the factory colour
        rendition charts.

    Examples
    --------
    >>> colour_checker_plot()  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    colour_checker, name = COLOURCHECKERS.get(colour_checker), colour_checker
    if colour_checker is None:
        raise KeyError(
            ('Colour checker "{0}" not found in '
             'factory colour checkers: "{1}".').format(
                name, sorted(COLOURCHECKERS.keys())))

    _name, data, illuminant = colour_checker
    colour_parameters = []
    for _index, label, x, y, Y in data:
        XYZ = xyY_to_XYZ((x, y, Y))
        RGB = XYZ_to_sRGB(XYZ, illuminant)

        colour_parameters.append(
            ColourParameter(label.title(), np.clip(np.ravel(RGB), 0, 1)))

    background_colour = '0.1'
    matplotlib.pyplot.gca().patch.set_facecolor(background_colour)

    width = height = 1.0
    spacing = 0.25
    across = 6

    settings = {
        'standalone': False,
        'width': width,
        'height': height,
        'spacing': spacing,
        'across': across,
        'text_size': 8,
        'margins': (-0.125, 0.125, -0.5, 0.125)}
    settings.update(kwargs)

    multi_colour_plot(colour_parameters, **settings)

    text_x = width * (across / 2) + (across * (spacing / 2)) - spacing / 2
    text_y = -(len(colour_parameters) / across + spacing / 2)

    pylab.text(text_x,
               text_y,
               '{0} - {1} - Colour Rendition Chart'.format(
                   name, RGB_COLOURSPACES.get('sRGB').name),
               color='0.95',
               clip_on=True,
               ha='center')

    settings.update({
        'title': name,
        'facecolor': background_colour,
        'edgecolor': None,
        'standalone': True})

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#50
0
def CIE_1931_chromaticity_diagram_colours_plot(
        surface=1,
        samples=4096,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots the *CIE 1931 Chromaticity Diagram* colours.

    Parameters
    ----------
    surface : numeric, optional
        Generated markers surface.
    samples : numeric, optional
        Samples count on one axis.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> CIE_1931_chromaticity_diagram_colours_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (64, 64)}
    settings.update(kwargs)

    canvas(**settings)

    cmfs = get_cmfs(cmfs)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    triangulation = Delaunay(XYZ_to_xy(cmfs.values, illuminant),
                             qhull_options='QJ')
    xx, yy = np.meshgrid(np.linspace(0, 1, samples),
                         np.linspace(0, 1, samples))
    xy = tstack((xx, yy))
    xy = xy[triangulation.find_simplex(xy) > 0]

    XYZ = xy_to_XYZ(xy)

    RGB = normalise_maximum(XYZ_to_sRGB(XYZ, illuminant), axis=-1)

    x_dot, y_dot = tsplit(xy)

    pylab.scatter(x_dot, y_dot, color=RGB, s=surface)

    settings.update({
        'x_ticker': False,
        'y_ticker': False,
        'bounding_box': (0, 1, 0, 1)})
    settings.update(kwargs)

    ax = matplotlib.pyplot.gca()
    matplotlib.pyplot.setp(ax, frame_on=False)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#51
0
s = [i[1] for i in data.values]
data_formated = dict(zip(w, s))
print(data)
print(data.values)
print(data_formated)
spd = SpectralPowerDistribution('Sample', data_formated)
illuminant = ILLUMINANTS_RELATIVE_SPDS['D50']
XYZ = spectral_to_XYZ(spd, cmfs, illuminant)
print(XYZ)
xy = XYZ_to_xy(XYZ)
print(xy)

CIE_1931_chromaticity_diagram_plot(standalone=False)
x, y = xy
pylab.plot(x, y, 'o-', color='white')
pylab.annotate('test',
               xy=xy,
               xytext=(-50, 30),
               textcoords='offset points',
               arrowprops=dict(arrowstyle='->',
                               connectionstyle='arc3, rad=-0.2'))

a = display(standalone=False)
print(type(a))
figfile = BytesIO()
a.savefig(figfile, format='svg')
figfile.seek(0)
figdata_svg = '<svg' + str(figfile.getvalue()).split('<svg')[1]
#figdata_svg = figdata_svg.encode('utf-8')
print(figdata_svg)
示例#52
0
def spds_CIE_1976_UCS_chromaticity_diagram_plot(
        spds,
        cmfs='CIE 1931 2 Degree Standard Observer',
        annotate=True,
        **kwargs):
    """
    Plots given spectral power distribution chromaticity coordinates into the
    *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    spds : array_like, optional
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    annotate : bool
        Should resulting chromaticity coordinates annotated with their
        respective spectral power distribution names.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> A = ILLUMINANTS_RELATIVE_SPDS['A']
    >>> D65 = ILLUMINANTS_RELATIVE_SPDS['D65']
    >>> spds_CIE_1976_UCS_chromaticity_diagram_plot([A, D65])  # doctest: +SKIP
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    CIE_1976_UCS_chromaticity_diagram_plot(cmfs=cmfs, **settings)

    for spd in spds:
        XYZ = spectral_to_XYZ(spd) / 100
        uv = Luv_to_uv(XYZ_to_Luv(XYZ))

        pylab.plot(uv[0], uv[1], 'o', color='white')

        if spd.name is not None and annotate:
            pylab.annotate(spd.name,
                           xy=uv,
                           xytext=(50, 30),
                           color='black',
                           textcoords='offset points',
                           arrowprops=dict(arrowstyle='->',
                                           connectionstyle='arc3, rad=0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.1, 0.7),
        'standalone': True})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#53
0
def CIE_1976_UCS_chromaticity_diagram_plot(
        cmfs='CIE 1931 2 Degree Standard Observer',
        show_diagram_colours=True,
        **kwargs):
    """
    Plots the *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    show_diagram_colours : bool, optional
        Whether to display the chromaticity diagram background colours.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> CIE_1976_UCS_chromaticity_diagram_plot()  # doctest: +SKIP
    """

    settings = {'figure_size': (DEFAULT_FIGURE_WIDTH, DEFAULT_FIGURE_WIDTH)}
    settings.update(kwargs)

    canvas(**settings)

    cmfs = get_cmfs(cmfs)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    if show_diagram_colours:
        image = matplotlib.image.imread(
            os.path.join(
                PLOTTING_RESOURCES_DIRECTORY,
                'CIE_1976_UCS_Chromaticity_Diagram_{0}.png'.format(
                    cmfs.name.replace(' ', '_'))))
        pylab.imshow(image, interpolation=None, extent=(0, 1, 0, 1))

    labels = (420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540,
              550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 680)

    wavelengths = cmfs.wavelengths
    equal_energy = np.array([1 / 3] * 2)

    uv = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant)

    wavelengths_chromaticity_coordinates = dict(zip(wavelengths, uv))

    pylab.plot(uv[..., 0], uv[..., 1], color='black', linewidth=2)
    pylab.plot((uv[-1][0], uv[0][0]), (uv[-1][1], uv[0][1]),
               color='black',
               linewidth=2)

    for label in labels:
        u, v = wavelengths_chromaticity_coordinates[label]
        pylab.plot(u, v, 'o', color='black', linewidth=2)

        index = bisect.bisect(wavelengths, label)
        left = wavelengths[index - 1] if index >= 0 else wavelengths[index]
        right = (wavelengths[index]
                 if index < len(wavelengths) else wavelengths[-1])

        dx = (wavelengths_chromaticity_coordinates[right][0] -
              wavelengths_chromaticity_coordinates[left][0])
        dy = (wavelengths_chromaticity_coordinates[right][1] -
              wavelengths_chromaticity_coordinates[left][1])

        uv = np.array([u, v])
        direction = np.array([-dy, dx])

        normal = (np.array([
            -dy, dx
        ]) if np.dot(normalise_vector(uv - equal_energy),
                     normalise_vector(direction)) > 0 else np.array([dy, -dx]))
        normal = normalise_vector(normal)
        normal /= 25

        pylab.plot((u, u + normal[0] * 0.75), (v, v + normal[1] * 0.75),
                   color='black',
                   linewidth=1.5)
        pylab.text(u + normal[0],
                   v + normal[1],
                   label,
                   color='black',
                   clip_on=True,
                   ha='left' if normal[0] >= 0 else 'right',
                   va='center',
                   fontdict={'size': 'small'})

    ticks = np.arange(-10, 10, 0.1)

    pylab.xticks(ticks)
    pylab.yticks(ticks)

    settings.update({
        'title':
        'CIE 1976 UCS Chromaticity Diagram - {0}'.format(cmfs.title),
        'x_label':
        'CIE u\'',
        'y_label':
        'CIE v\'',
        'grid':
        True,
        'bounding_box': (0, 1, 0, 1)
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#54
0
def multi_spd_plot(spds,
                   cmfs='CIE 1931 2 Degree Standard Observer',
                   use_spds_colours=False,
                   normalise_spds_colours=False,
                   **kwargs):
    """
    Plots given spectral power distributions.

    Parameters
    ----------
    spds : list
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectrum creation.
    use_spds_colours : bool, optional
        Use spectral power distributions colours.
    normalise_spds_colours : bool
        Should spectral power distributions colours normalised.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> from colour import SpectralPowerDistribution
    >>> data1 = {400: 0.0641, 420: 0.0645, 440: 0.0562}
    >>> data2 = {400: 0.134, 420: 0.789, 440: 1.289}
    >>> spd1 = SpectralPowerDistribution('Custom1', data1)
    >>> spd2 = SpectralPowerDistribution('Custom2', data2)
    >>> multi_spd_plot([spd1, spd2])  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    cmfs = get_cmfs(cmfs)

    if use_spds_colours:
        illuminant = ILLUMINANTS_RELATIVE_SPDS.get('D65')

    x_limit_min, x_limit_max, y_limit_min, y_limit_max = [], [], [], []
    for spd in spds:
        wavelengths, values = tuple(zip(*spd.items))

        shape = spd.shape
        x_limit_min.append(shape.start)
        x_limit_max.append(shape.end)
        y_limit_min.append(min(values))
        y_limit_max.append(max(values))

        if use_spds_colours:
            XYZ = spectral_to_XYZ(spd, cmfs, illuminant) / 100
            if normalise_spds_colours:
                XYZ = normalise(XYZ, clip=False)
            RGB = np.clip(XYZ_to_sRGB(XYZ), 0, 1)

            pylab.plot(wavelengths, values, color=RGB, label=spd.title,
                       linewidth=2)
        else:
            pylab.plot(wavelengths, values, label=spd.title, linewidth=2)

    settings = {
        'x_label': 'Wavelength $\\lambda$ (nm)',
        'y_label': 'Spectral Power Distribution',
        'x_tighten': True,
        'legend': True,
        'legend_location': 'upper left',
        'limits': (min(x_limit_min), max(x_limit_max),
                   min(y_limit_min), max(y_limit_max))}
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#55
0
def spds_CIE_1976_UCS_chromaticity_diagram_plot(
        spds,
        cmfs='CIE 1931 2 Degree Standard Observer',
        annotate=True,
        **kwargs):
    """
    Plots given spectral power distribution chromaticity coordinates into the
    *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    spds : array_like, optional
        Spectral power distributions to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for diagram bounds.
    annotate : bool
        Should resulting chromaticity coordinates annotated with their
        respective spectral power distribution names.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1976_UCS_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Examples
    --------
    >>> from colour import ILLUMINANTS_RELATIVE_SPDS
    >>> A = ILLUMINANTS_RELATIVE_SPDS['A']
    >>> D65 = ILLUMINANTS_RELATIVE_SPDS['D65']
    >>> spds_CIE_1976_UCS_chromaticity_diagram_plot([A, D65])  # doctest: +SKIP
    """

    settings = {}
    settings.update(kwargs)
    settings.update({'standalone': False})

    CIE_1976_UCS_chromaticity_diagram_plot(cmfs=cmfs, **settings)

    for spd in spds:
        XYZ = spectral_to_XYZ(spd) / 100
        uv = Luv_to_uv(XYZ_to_Luv(XYZ))

        pylab.plot(uv[0], uv[1], 'o', color='white')

        if spd.name is not None and annotate:
            pylab.annotate(spd.name,
                           xy=uv,
                           xytext=(50, 30),
                           color='black',
                           textcoords='offset points',
                           arrowprops=dict(arrowstyle='->',
                                           connectionstyle='arc3, rad=0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.1, 0.7),
        'standalone': True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
示例#56
0
def multi_cmfs_plot(cmfs=None, **kwargs):
    """
    Plots given colour matching functions.

    Parameters
    ----------
    cmfs : array_like, optional
        Colour matching functions to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> cmfs = [
    ... 'CIE 1931 2 Degree Standard Observer',
    ... 'CIE 1964 10 Degree Standard Observer']
    >>> multi_cmfs_plot(cmfs)  # doctest: +SKIP
    True
    """

    canvas(**kwargs)

    if cmfs is None:
        cmfs = ('CIE 1931 2 Degree Standard Observer',
                'CIE 1964 10 Degree Standard Observer')

    x_limit_min, x_limit_max, y_limit_min, y_limit_max = [], [], [], []
    for axis, rgb in (('x', (1, 0, 0)),
                      ('y', (0, 1, 0)),
                      ('z', (0, 0, 1))):
        for i, cmfs_i in enumerate(cmfs):
            cmfs_i = get_cmfs(cmfs_i)

            rgb = [reduce(lambda y, _: y * 0.5, range(i), x)  # noqa
                   for x in rgb]
            wavelengths, values = tuple(
                zip(*[(key, value) for key, value in getattr(cmfs_i, axis)]))

            shape = cmfs_i.shape
            x_limit_min.append(shape.start)
            x_limit_max.append(shape.end)
            y_limit_min.append(min(values))
            y_limit_max.append(max(values))

            pylab.plot(wavelengths,
                       values,
                       color=rgb,
                       label=u'{0} - {1}'.format(
                           cmfs_i.labels.get(axis), cmfs_i.title),
                       linewidth=2)

    settings = {
        'title': '{0} - Colour Matching Functions'.format(', '.join(
            [get_cmfs(c).title for c in cmfs])),
        'x_label': 'Wavelength $\\lambda$ (nm)',
        'y_label': 'Tristimulus Values',
        'x_tighten': True,
        'legend': True,
        'legend_location': 'upper right',
        'grid': True,
        'y_axis_line': True,
        'limits': (min(x_limit_min), max(x_limit_max),
                   min(y_limit_min), max(y_limit_max))}
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)