Example #1
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)
Example #2
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 : 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_1976_UCS_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_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})
    settings.update(kwargs)

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

    return display(**settings)
def RGB_colourspace_triangle_visual(colourspace='ITU-R BT.709',
                                    diagram='CIE 1931',
                                    uniform_colour=None,
                                    uniform_opacity=1.0,
                                    width=4.0,
                                    parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a *RGB* colourspace triangle visual.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace triangle to draw.
    diagram : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Chromaticity diagram to use.
    uniform_colour : array_like, optional
        Uniform triangle colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    width : numeric, optional
        Triangle edge width.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    if uniform_colour is None:
        uniform_colour = (0.8, 0.8, 0.8)

    colourspace = get_RGB_colourspace(colourspace)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    XYZ_to_ij = CHROMATICITY_DIAGRAM_TRANSFORMATIONS[diagram]['XYZ_to_ij']

    ij = XYZ_to_ij(xy_to_XYZ(colourspace.primaries), illuminant)
    # TODO: Remove following hack dealing with 'agg' method issues.
    ij = np.vstack((ij[-1, ...], ij, ij[0, ...]))

    ij[np.isnan(ij)] = 0

    RGB = np.hstack((uniform_colour, uniform_opacity)),

    line = Line(ij, RGB, width=width, method='agg', parent=parent)

    return line
def RGB_colourspace_whitepoint_axis_visual(colourspace='ITU-R BT.709',
                                           reference_colourspace='CIE xyY',
                                           width=2.0,
                                           method='gl',
                                           parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a given RGB colourspace whitepoint axis.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace whitepoint axis to draw.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to use for colour conversions / transformations.
    width : numeric, optional
        Line width.
    method : unicode, optional
        **{'gl', 'agg'}**,
        Line drawing method.
    parent : Node, optional
        Parent of the spectral locus visual in the `SceneGraph`.

    Returns
    -------
    Line
        RGB colourspace whitepoint axis.
    """

    colourspace = get_RGB_colourspace(colourspace)
    XYZ_o = xy_to_XYZ(colourspace.whitepoint + (0, ))
    XYZ_f = xy_to_XYZ(colourspace.whitepoint + (1.1, ))
    XYZ_l = np.vstack((XYZ_o, XYZ_f))

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

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

    line = Line(points, (1, 1, 1), width=width, method=method, parent=parent)

    return line
def plot_grid(filename, data_points, grid, bbox_xystar, xystar=True):
    if not have_matplotlib or not have_colour_package:
        return

    print("Plotting the grid ...")

    plt.figure()
    # Draw a nice chromaticity diagram.
    clr.CIE_1931_chromaticity_diagram_plot(standalone=False)
    clr.canvas(figure_size=(7,7))

    # Show the sRGB gamut.
    color_space = clr.get_RGB_colourspace('sRGB')
    x = color_space.primaries[:,0].tolist()
    y = color_space.primaries[:,1].tolist()
    plt.fill(x, y, color='black', label='sRGB', fill=False)

    # Draw crosses into all internal grid cells.
    # for gridcell in grid:
    #     if len(gridcell.indices) > 0 and gridcell.inside:
    #         if xystar:
    #             pointx = sum([data_points[i].xystar[0] for i in gridcell.indices])
    #             pointy = sum([data_points[i].xystar[1] for i in gridcell.indices])
    #             pointx /= len(gridcell.indices)
    #             pointy /= len(gridcell.indices)
    #             (pointx, pointy) = Transform.xy_from_xystar((pointx, pointy))
    #             plt.plot(pointx, pointy, "x", color="black")
    #         else:
    #             pointx = sum([data_points[i].uv[0] for i in gridcell.indices])
    #             pointy = sum([data_points[i].uv[1] for i in gridcell.indices])
    #             pointx /= len(gridcell.indices)
    #             pointy /= len(gridcell.indices)
    #             (pointx, pointy) = Transform.xy_from_uv((pointx, pointy))
    #             plt.plot(pointx, pointy, "x", color="black")
 
    # Draw data points.
    for i, data_point in enumerate(data_points):
        if xystar:
            p = Transform.xy_from_xystar(data_point.xystar)
        else:
            p = Transform.xy_from_uv(data_point.uv)

        if data_point.equal_energy_white:
            plt.plot(p[0], p[1], "o", color="white", ms=4)
        elif data_point.broken:
            plt.plot(p[0], p[1], "o", color="red", ms=4)
        else:
            plt.plot(p[0], p[1], "o", color="green", ms=4)

        # Show grid point indices, for debugging.
        # plt.text(p[0]+0.01, p[1]-0.01, '{}'.format(i))

    bp0 = Transform.xy_from_xystar([bbox_xystar[0][0], bbox_xystar[0][1]])
    bp1 = Transform.xy_from_xystar([bbox_xystar[0][0], bbox_xystar[1][1]])
    bp2 = Transform.xy_from_xystar([bbox_xystar[1][0], bbox_xystar[1][1]])
    bp3 = Transform.xy_from_xystar([bbox_xystar[1][0], bbox_xystar[0][1]])
    plt.plot([bp0[0], bp1[0], bp2[0], bp3[0], bp0[0]],
             [bp0[1], bp1[1], bp2[1], bp3[1], bp0[1]],
             label="Grid Bounding Box")

    plt.xlabel('$x$')
    plt.ylabel('$y$')

    plt.legend()
    plt.savefig(filename)
Example #6
0
def RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    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.
    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
    --------
    >>> c = ['Rec. 709', 'ACEScg', 'S-Gamut']
    >>> RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(
    ...     c)  # doctest: +SKIP
    """

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

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

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

    CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.7]
    y_limit_min, y_limit_max = [-0.1], [0.7]

    settings = {
        'colour_cycle_map': 'rainbow',
        'colour_cycle_count': len(colourspaces)
    }
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            uv = Luv_to_uv(
                XYZ_to_Luv(xy_to_XYZ(POINTER_GAMUT_BOUNDARIES), illuminant),
                illuminant)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(uv[..., 0],
                       uv[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((uv[-1][0], uv[0][0]), (uv[-1][1], uv[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            uv = Luv_to_uv(XYZ_to_Luv(XYZ, illuminant), illuminant)
            pylab.scatter(uv[..., 0],
                          uv[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            # RGB colourspaces such as *ACES2065-1* have primaries with
            # chromaticity coordinates set to 0 thus we prevent nan from being
            # yield by zero division in later colour transformations.
            P = np.where(colourspace.primaries == 0, EPSILON,
                         colourspace.primaries)

            P = Luv_to_uv(XYZ_to_Luv(xy_to_XYZ(P), illuminant), illuminant)
            W = Luv_to_uv(
                XYZ_to_Luv(xy_to_XYZ(colourspace.whitepoint), illuminant),
                illuminant)

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

            x_limit_min.append(np.amin(P[..., 0]) - 0.1)
            y_limit_min.append(np.amin(P[..., 1]) - 0.1)
            x_limit_max.append(np.amax(P[..., 0]) + 0.1)
            y_limit_max.append(np.amax(P[..., 1]) + 0.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)),
        'standalone':
        True
    })
    settings.update(kwargs)

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

    return display(**settings)
def RGB_colourspace_triangle_visual(colourspace='Rec. 709',
                                    diagram='CIE 1931',
                                    uniform_colour=None,
                                    uniform_opacity=1.0,
                                    width=4.0,
                                    parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a *RGB* colourspace triangle visual.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace triangle to draw.
    diagram : unicode, optional
        {'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}

        Chromaticity diagram to use.
    uniform_colour : array_like, optional
        Uniform triangle colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    vertex_colour : array_like, optional
        Per vertex varying colour.
    wireframe : bool, optional
        Use wireframe display.
        Uniform mesh opacity.
    wireframe_colour : array_like, optional
        Wireframe mesh colour.
    wireframe_opacity : numeric, optional
        Wireframe mesh opacity.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    if uniform_colour is None:
        uniform_colour = (0.8, 0.8, 0.8)

    colourspace = get_RGB_colourspace(colourspace)

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    XYZ_to_ij = CHROMATICITY_DIAGRAM_TRANSFORMATIONS[diagram]['XYZ_to_ij']

    ij = XYZ_to_ij(xy_to_XYZ(colourspace.primaries), illuminant)
    # TODO: Remove following hack dealing with 'agg' method issues.
    ij = np.vstack((ij[-1, ...], ij, ij[0, ...]))

    ij[np.isnan(ij)] = 0

    RGB = np.hstack((uniform_colour, uniform_opacity)),

    line = Line(ij,
                RGB,
                width=width,
                method='agg',
                parent=parent)

    return line
Example #8
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'}**,
        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)
Example #9
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)
Example #10
0
def RGB_scatter_visual(RGB,
                       colourspace='ITU-R BT.709',
                       reference_colourspace='CIE xyY',
                       symbol='disc',
                       size=4.0,
                       edge_size=0.5,
                       uniform_colour=None,
                       uniform_opacity=1.0,
                       uniform_edge_colour=None,
                       uniform_edge_opacity=1.0,
                       resampling='auto',
                       parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Symbol` class instance representing
    *RGB* data using given symbols.

    Parameters
    ----------
    RGB : array_like
        *RGB* data to draw.
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace of the data to draw.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to use for colour conversions / transformations.
    symbol : unicode, optional
        Symbol type to draw.
    size : numeric, optional
        Symbol size.
    edge_size : numeric, optional
        Symbol edge size.
    uniform_colour : array_like, optional
        Uniform symbol colour.
    uniform_opacity : numeric, optional
        Uniform symbol opacity.
    uniform_edge_colour : array_like, optional
        Uniform symbol edge colour.
    uniform_edge_opacity : numeric, optional
        Uniform symbol edge opacity.
    resampling : numeric or unicode, optional
        Resampling value, if numeric input, one pixel every `resampling`
        argument value will be kept.
    parent : Node, optional
        Parent of the *RGB* scatter visual in the `SceneGraph`.

    Returns
    -------
    Symbol
        *RGB* scatter visual.
    """

    colourspace = get_RGB_colourspace(colourspace)

    RGB = np.asarray(RGB)

    if resampling == 'auto':
        resampling = max(int((0.0078125 * np.average(RGB.shape[0:1])) // 2), 1)

        RGB = RGB[::resampling, ::resampling].reshape((-1, 3))

    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)

    points[np.isnan(points)] = 0

    RGB = np.clip(RGB, 0, 1)

    if uniform_colour is None:
        RGB = np.hstack((RGB,
                         np.full((RGB.shape[0], 1), uniform_opacity,
                                 DEFAULT_FLOAT_DTYPE)))
    else:
        RGB = ColorArray(uniform_colour, alpha=uniform_opacity).rgba

    if uniform_edge_colour is None:
        RGB_e = RGB
    else:
        RGB_e = ColorArray(uniform_edge_colour,
                           alpha=uniform_edge_opacity).rgba

    markers = Symbol(symbol=symbol,
                     positions=points,
                     size=size,
                     edge_size=edge_size,
                     face_colour=RGB,
                     edge_colour=RGB_e,
                     parent=parent)

    return markers
Example #11
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)
Example #12
0
def RGB_colourspaces_CIE_1960_UCS_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1960 UCS Chromaticity Diagram*.

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

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

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

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

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

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

    CIE_1960_UCS_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.7]
    y_limit_min, y_limit_max = [-0.2], [0.6]

    settings = {'colour_cycle_map': 'rainbow',
                'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            uv = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(POINTER_GAMUT_BOUNDARIES)))
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(uv[..., 0],
                       uv[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((uv[-1][0], uv[0][0]),
                       (uv[-1][1], uv[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            uv = UCS_to_uv(XYZ_to_UCS(XYZ))
            pylab.scatter(uv[..., 0],
                          uv[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            # RGB colourspaces such as *ACES2065-1* have primaries with
            # chromaticity coordinates set to 0 thus we prevent nan from being
            # yield by zero division in later colour transformations.
            primaries = np.where(colourspace.primaries == 0,
                                 EPSILON,
                                 colourspace.primaries)

            primaries = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(primaries)))
            whitepoint = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(
                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]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.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)),
        'standalone': True})
    settings.update(kwargs)

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

    return display(**settings)
Example #13
0
def RGB_chromaticity_coordinates_chromaticity_diagram_plot_CIE1976UCS(
        RGB,
        colourspace='sRGB',
        chromaticity_diagram_callable_CIE1976UCS=(
            RGB_colourspaces_chromaticity_diagram_plot_CIE1976UCS),
        **kwargs):
    """
    Plots given *RGB* colourspace array in *CIE 1976 UCS Chromaticity Diagram*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : optional, unicode
        *RGB* colourspace of the *RGB* array.
    chromaticity_diagram_callable_CIE1976UCS : callable, optional
        Callable responsible for drawing the
        *CIE 1976 UCS Chromaticity Diagram*.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definition.
    show_diagram_colours : bool, optional
        {:func:`colour.plotting.chromaticity_diagram_plot_CIE1976UCS`},
        Whether to display the chromaticity diagram background colours.
    use_cached_diagram_colours : bool, optional
        {:func:`colour.plotting.chromaticity_diagram_plot_CIE1976UCS`},
        Whether to used the cached chromaticity diagram background colours
        image.

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

    Examples
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> c = 'ITU-R BT.709'
    >>> RGB_chromaticity_coordinates_chromaticity_diagram_plot_CIE1976UCS(
    ...     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', []))

    chromaticity_diagram_callable_CIE1976UCS(**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})
    settings.update(kwargs)

    return render(**settings)
def RGB_colourspace_volume_visual(colourspace='ITU-R BT.709',
                                  reference_colourspace='CIE xyY',
                                  segments=16,
                                  uniform_colour=None,
                                  uniform_opacity=0.5,
                                  wireframe=True,
                                  wireframe_colour=None,
                                  wireframe_opacity=1.0,
                                  parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Node` class instance with one or two
    :class:`colour_analysis.visuals.Box` class instance children representing
    a *RGB* colourspace volume visual.

    Parameters
    ----------
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace volume to draw.
    reference_colourspace : unicode
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to convert the *CIE XYZ* tristimulus values to.
    segments : int, optional
        Box segments.
    uniform_colour : array_like, optional
        Uniform mesh colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    wireframe : bool, optional
        Use wireframe display.
        Uniform mesh opacity.
    wireframe_colour : array_like, optional
        Wireframe mesh colour.
    wireframe_opacity : numeric, optional
        Wireframe mesh opacity.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    node = Node(parent)

    colourspace = get_RGB_colourspace(colourspace)

    RGB_cube_f = RGB_identity_cube(width_segments=segments,
                                   height_segments=segments,
                                   depth_segments=segments,
                                   uniform_colour=uniform_colour,
                                   uniform_opacity=uniform_opacity,
                                   vertex_colours=not uniform_colour,
                                   parent=node)

    vertices = RGB_cube_f.mesh_data.get_vertices()
    XYZ = RGB_to_XYZ(vertices, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)
    value = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)
    value[np.isnan(value)] = 0

    RGB_cube_f.mesh_data.set_vertices(value)

    if wireframe:
        RGB_cube_w = RGB_identity_cube(width_segments=segments,
                                       height_segments=segments,
                                       depth_segments=segments,
                                       uniform_colour=wireframe_colour,
                                       uniform_opacity=wireframe_opacity,
                                       vertex_colours=not wireframe_colour,
                                       wireframe=True,
                                       parent=node)
        RGB_cube_w.mesh_data.set_vertices(value)

    return node
def plot_grid(filename, data_points, grid, bbox_xystar, xystar=True):
    if not have_matplotlib or not have_colour_package:
        return

    print("Plotting the grid ...")

    plt.figure()
    # Draw a nice chromaticity diagram.
    clr.CIE_1931_chromaticity_diagram_plot(standalone=False)
    clr.canvas(figure_size=(7,7))

    # Show the sRGB gamut.
    color_space = clr.get_RGB_colourspace('sRGB')
    x = color_space.primaries[:,0].tolist()
    y = color_space.primaries[:,1].tolist()
    plt.fill(x, y, color='black', label='sRGB', fill=False)

    # Draw crosses into all internal grid cells.
    # for gridcell in grid:
    #     if len(gridcell.indices) > 0 and gridcell.inside:
    #         if xystar:
    #             pointx = sum([data_points[i].xystar[0] for i in gridcell.indices])
    #             pointy = sum([data_points[i].xystar[1] for i in gridcell.indices])
    #             pointx /= len(gridcell.indices)
    #             pointy /= len(gridcell.indices)
    #             (pointx, pointy) = Transform.xy_from_xystar((pointx, pointy))
    #             plt.plot(pointx, pointy, "x", color="black")
    #         else:
    #             pointx = sum([data_points[i].uv[0] for i in gridcell.indices])
    #             pointy = sum([data_points[i].uv[1] for i in gridcell.indices])
    #             pointx /= len(gridcell.indices)
    #             pointy /= len(gridcell.indices)
    #             (pointx, pointy) = Transform.xy_from_uv((pointx, pointy))
    #             plt.plot(pointx, pointy, "x", color="black")
 
    # Draw data points.
    for i, data_point in enumerate(data_points):
        if xystar:
            p = Transform.xy_from_xystar(data_point.xystar)
        else:
            p = Transform.xy_from_uv(data_point.uv)

        if data_point.equal_energy_white:
            plt.plot(p[0], p[1], "o", color="white", ms=4)
        elif data_point.broken:
            plt.plot(p[0], p[1], "o", color="red", ms=4)
        else:
            plt.plot(p[0], p[1], "o", color="green", ms=4)

        # Show grid point indices, for debugging.
        # plt.text(p[0]+0.01, p[1]-0.01, '{}'.format(i))

    bp0 = Transform.xy_from_xystar([bbox_xystar[0][0], bbox_xystar[0][1]])
    bp1 = Transform.xy_from_xystar([bbox_xystar[0][0], bbox_xystar[1][1]])
    bp2 = Transform.xy_from_xystar([bbox_xystar[1][0], bbox_xystar[1][1]])
    bp3 = Transform.xy_from_xystar([bbox_xystar[1][0], bbox_xystar[0][1]])
    plt.plot([bp0[0], bp1[0], bp2[0], bp3[0], bp0[0]],
             [bp0[1], bp1[1], bp2[1], bp3[1], bp0[1]],
             label="Grid Bounding Box")

    plt.xlabel('$x$')
    plt.ylabel('$y$')

    plt.legend()
    plt.savefig(filename)
Example #16
0
def RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    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.
    show_diagram_colours : bool, optional
        {:func:`CIE_1931_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

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

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

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

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

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

    CIE_1931_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.9]
    y_limit_min, y_limit_max = [-0.1], [0.9]

    settings = {
        'colour_cycle_map': 'rainbow',
        'colour_cycle_count': len(colourspaces)
    }
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            xy = np.asarray(POINTER_GAMUT_BOUNDARIES)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(xy[..., 0],
                       xy[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((xy[-1][0], xy[0][0]), (xy[-1][1], xy[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            xy = XYZ_to_xy(XYZ, POINTER_GAMUT_ILLUMINANT)
            pylab.scatter(xy[..., 0],
                          xy[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            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]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.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)),
        'standalone':
        True
    })
    settings.update(kwargs)

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

    return display(**settings)
Example #17
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 : unicode
        *RGB* colourspace of the *RGB* array.

    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
    --------
    >>> RGB = np.random.random((10, 10, 3))
    >>> c = 'Rec. 709'
    >>> RGB_chromaticity_coordinates_CIE_1976_UCS_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_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})
    settings.update(kwargs)

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

    return display(**settings)
Example #18
0
def RGB_colourspaces_CIE_1976_UCS_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1976 UCS Chromaticity Diagram*.

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

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

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

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

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

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

    CIE_1976_UCS_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.7]
    y_limit_min, y_limit_max = [-0.1], [0.7]

    settings = {'colour_cycle_map': 'rainbow',
                'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            uv = Luv_to_uv(XYZ_to_Luv(xy_to_XYZ(
                POINTER_GAMUT_BOUNDARIES), illuminant), illuminant)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(uv[..., 0],
                       uv[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((uv[-1][0], uv[0][0]),
                       (uv[-1][1], uv[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            uv = Luv_to_uv(XYZ_to_Luv(XYZ, illuminant), illuminant)
            pylab.scatter(uv[..., 0],
                          uv[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            # RGB colourspaces such as *ACES2065-1* have primaries with
            # chromaticity coordinates set to 0 thus we prevent nan from being
            # yield by zero division in later colour transformations.
            primaries = np.where(colourspace.primaries == 0,
                                 EPSILON,
                                 colourspace.primaries)

            primaries = Luv_to_uv(XYZ_to_Luv(xy_to_XYZ(
                primaries), illuminant), illuminant)
            whitepoint = Luv_to_uv(XYZ_to_Luv(xy_to_XYZ(
                colourspace.whitepoint), illuminant), illuminant)

            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]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.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)),
        'standalone': True})
    settings.update(kwargs)

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

    return display(**settings)
Example #19
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)
Example #20
0
def multi_conversion_function_plot(colourspaces=None,
                                   EOCF=False,
                                   **kwargs):
    """
    Plots given colourspaces opto-electronic conversion functions.

    Parameters
    ----------
    colourspaces : array_like, optional
        Colourspaces opto-electronic conversion functions to plot.
    EOCF : bool
        Plot electro-optical conversion functions instead.
    \**kwargs : dict, optional
        Keywords arguments.

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

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

    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.EOCF(samples) if EOCF else colourspace.OECF(samples)

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

    settings.update({
        'title': '{0} - {1} Conversion Functions'.format(
            ', '.join(colourspaces),
            'Electro-Optical' if EOCF else 'Opto-Electronic'),
        'x_tighten': True,
        '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)
Example #21
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)
Example #22
0
def RGB_colourspaces_CIE_1931_chromaticity_diagram_plot(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        **kwargs):
    """
    Plots given *RGB* colourspaces in *CIE 1931 Chromaticity Diagram*.

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

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

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

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

    canvas(**settings)

    if colourspaces is None:
        colourspaces = ('Rec. 709', 'ACEScg', 'S-Gamut', 'Pointer Gamut')

    cmfs, name = get_cmfs(cmfs), cmfs

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

    CIE_1931_chromaticity_diagram_plot(**settings)

    x_limit_min, x_limit_max = [-0.1], [0.9]
    y_limit_min, y_limit_max = [-0.1], [0.9]

    settings = {'colour_cycle_map': 'rainbow',
                'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        if colourspace == 'Pointer Gamut':
            xy = np.asarray(POINTER_GAMUT_BOUNDARIES)
            alpha_p, colour_p = 0.85, '0.95'
            pylab.plot(xy[..., 0],
                       xy[..., 1],
                       label='Pointer\'s Gamut',
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)
            pylab.plot((xy[-1][0], xy[0][0]),
                       (xy[-1][1], xy[0][1]),
                       color=colour_p,
                       alpha=alpha_p,
                       linewidth=2)

            XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA),
                             POINTER_GAMUT_ILLUMINANT)
            xy = XYZ_to_xy(XYZ, POINTER_GAMUT_ILLUMINANT)
            pylab.scatter(xy[..., 0],
                          xy[..., 1],
                          alpha=alpha_p / 2,
                          color=colour_p,
                          marker='+')

        else:
            colourspace, name = get_RGB_colourspace(colourspace), colourspace

            r, g, b, _a = next(cycle)

            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]) - 0.1)
            y_limit_min.append(np.amin(primaries[..., 1]) - 0.1)
            x_limit_max.append(np.amax(primaries[..., 0]) + 0.1)
            y_limit_max.append(np.amax(primaries[..., 1]) + 0.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)),
        'standalone': True})
    settings.update(kwargs)

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

    return display(**settings)
def RGB_scatter_visual(RGB,
                       colourspace='Rec. 709',
                       reference_colourspace='CIE xyY',
                       symbol='disc',
                       size=4.0,
                       edge_size=0.5,
                       uniform_colour=None,
                       uniform_opacity=1.0,
                       uniform_edge_colour=None,
                       uniform_edge_opacity=1.0,
                       resampling='auto',
                       parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Symbol` class instance representing
    *RGB* data using given symbols.

    Parameters
    ----------
    RGB : array_like
        *RGB* data to draw.
    colourspace : unicode, optional
        {'Rec. 709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut RGB', 'Adobe RGB 1998', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'Ekta Space PS 5', 'Max RGB', 'NTSC RGB',
        'Pal/Secam RGB', 'ProPhoto RGB', 'REDcolor', 'REDcolor2', 'REDcolor3',
        'REDcolor4', 'Rec. 2020', 'Russell RGB', 'S-Gamut', 'S-Gamut3',
        'S-Gamut3.Cine', 'SMPTE-C RGB', 'V-Gamut', 'Xtreme RGB', 'aces',
        'adobe1998', 'prophoto', 'sRGB'}

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace of the data to draw.
    reference_colourspace : unicode, optional
        {'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT'}

        Reference colourspace to use for colour conversions / transformations.
    symbol : unicode, optional
        Symbol type to draw.
    size : numeric, optional
        Symbol size.
    edge_size : numeric, optional
        Symbol edge size.
    uniform_colour : array_like, optional
        Uniform symbol colour.
    uniform_opacity : numeric, optional
        Uniform symbol opacity.
    uniform_edge_colour : array_like, optional
        Uniform symbol edge colour.
    uniform_edge_opacity : numeric, optional
        Uniform symbol edge opacity.
    resampling : numeric or unicode, optional
        Resampling value, if numeric input, one pixel every `resampling`
        argument value will be kept.
    parent : Node, optional
        Parent of the *RGB* scatter visual in the `SceneGraph`.

    Returns
    -------
    Symbol
        *RGB* scatter visual.
    """

    colourspace = get_RGB_colourspace(colourspace)

    RGB = np.asarray(RGB)

    if resampling == 'auto':
        resampling = int((0.0078125 * np.average(RGB.shape[0:1])) // 2)

        RGB = RGB[::resampling, ::resampling].reshape((-1, 3))

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

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

        points[np.isnan(points)] = 0

        RGB = np.clip(RGB, 0, 1)

        if uniform_colour is None:
            RGB = np.hstack((RGB, np.full((RGB.shape[0], 1), uniform_opacity)))
        else:
            RGB = ColorArray(uniform_colour, alpha=uniform_opacity).rgba

        if uniform_edge_colour is None:
            RGB_e = RGB
        else:
            RGB_e = ColorArray(uniform_edge_colour,
                               alpha=uniform_edge_opacity).rgba

        markers = Symbol(symbol=symbol,
                         positions=points,
                         size=size,
                         edge_size=edge_size,
                         face_colour=RGB,
                         edge_colour=RGB_e,
                         parent=parent)

        return markers
Example #24
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.
    \**kwargs : dict, optional
        Keywords arguments.

    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)
Example #25
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)
def RGB_colourspace_volume_visual(colourspace='Rec. 709',
                                  reference_colourspace='CIE xyY',
                                  segments=16,
                                  uniform_colour=None,
                                  uniform_opacity=0.5,
                                  wireframe=True,
                                  wireframe_colour=None,
                                  wireframe_opacity=1.0,
                                  parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Node` class instance with one or two
    :class:`colour_analysis.visuals.Box` class instance children representing
    a *RGB* colourspace volume visual.

    Parameters
    ----------
    colourspace : unicode, optional
        {'Rec. 709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut RGB', 'Adobe RGB 1998', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'Ekta Space PS 5', 'Max RGB', 'NTSC RGB',
        'Pal/Secam RGB', 'ProPhoto RGB', 'REDcolor', 'REDcolor2', 'REDcolor3',
        'REDcolor4', 'Rec. 2020', 'Russell RGB', 'S-Gamut', 'S-Gamut3',
        'S-Gamut3.Cine', 'SMPTE-C RGB', 'V-Gamut', 'Xtreme RGB', 'aces',
        'adobe1998', 'prophoto', 'sRGB'}

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace volume to draw.
    segments : int, optional
        Box segments.
    uniform_colour : array_like, optional
        Uniform mesh colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    vertex_colour : array_like, optional
        Per vertex varying colour.
    wireframe : bool, optional
        Use wireframe display.
        Uniform mesh opacity.
    wireframe_colour : array_like, optional
        Wireframe mesh colour.
    wireframe_opacity : numeric, optional
        Wireframe mesh opacity.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    node = Node(parent)

    colourspace = get_RGB_colourspace(colourspace)

    RGB_cube_f = RGB_identity_cube(
        width_segments=segments,
        height_segments=segments,
        depth_segments=segments,
        uniform_colour=uniform_colour,
        uniform_opacity=uniform_opacity,
        vertex_colours=not uniform_colour,
        parent=node)

    vertices = RGB_cube_f.mesh_data.get_vertices()
    XYZ = RGB_to_XYZ(
        vertices,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.RGB_to_XYZ_matrix)
    value = XYZ_to_reference_colourspace(XYZ,
                                         colourspace.whitepoint,
                                         reference_colourspace)
    value[np.isnan(value)] = 0

    RGB_cube_f.mesh_data.set_vertices(value)

    if wireframe:
        RGB_cube_w = RGB_identity_cube(
            width_segments=segments,
            height_segments=segments,
            depth_segments=segments,
            uniform_colour=wireframe_colour,
            uniform_opacity=wireframe_opacity,
            vertex_colours=not wireframe_colour,
            wireframe=True,
            parent=node)
        RGB_cube_w.mesh_data.set_vertices(value)

    return node