def test_domain_range_scale_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition domain and range scale support. """ LCHab = np.array([41.52787529, 59.12425901, 27.08848784]) Lab = LCHab_to_Lab(LCHab) d_r = (('reference', 1, 1), (1, np.array([0.01, 0.01, 1 / 360]), 0.01), (100, np.array([1, 1, 1 / 3.6]), 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): np.testing.assert_almost_equal( LCHab_to_Lab(LCHab * factor_a), Lab * factor_b, decimal=7)
def is_within_pointer_gamut(XYZ, tolerance=None): """ Returns if given *CIE XYZ* tristimulus values are within Pointer's Gamut volume. Parameters ---------- XYZ : array_like *CIE XYZ* tristimulus values. tolerance : numeric, optional Tolerance allowed in the inside-triangle check. Returns ------- bool Is within Pointer's Gamut. Notes ----- - Input *CIE XYZ* tristimulus values are in domain [0, 1]. Examples -------- >>> import numpy as np >>> is_within_pointer_gamut(np.array([0.3205, 0.4131, 0.5100])) array(True, dtype=bool) >>> a = np.array([[0.3205, 0.4131, 0.5100], [0.0005, 0.0031, 0.0010]]) >>> is_within_pointer_gamut(a) array([ True, False], dtype=bool) """ XYZ_p = Lab_to_XYZ( LCHab_to_Lab(POINTER_GAMUT_DATA), POINTER_GAMUT_ILLUMINANT) return is_within_mesh_volume(XYZ, XYZ_p, tolerance)
def test_n_dimensional_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition n-dimensional arrays support. """ LCHab = np.array([41.52787529, 59.12425901, 27.08848784]) Lab = LCHab_to_Lab(LCHab) LCHab = np.tile(LCHab, (6, 1)) Lab = np.tile(Lab, (6, 1)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7) LCHab = np.reshape(LCHab, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7)
def test_n_dimensional_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition n-dimensional arrays support. """ LCHab = np.array([37.98562910, 24.03190365, 190.58415972]) Lab = np.array([37.98562910, -23.62302887, -4.41417036]) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7) LCHab = np.tile(LCHab, (6, 1)) Lab = np.tile(Lab, (6, 1)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7) LCHab = np.reshape(LCHab, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7)
def test_n_dimensional_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition n-dimensional arrays support. """ LCHab = np.array([37.98562910, 24.03845422, 190.58923377]) Lab = np.array([37.98562910, -23.62907688, -4.41746615]) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7) LCHab = np.tile(LCHab, (6, 1)) Lab = np.tile(Lab, (6, 1)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7) LCHab = np.reshape(LCHab, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) np.testing.assert_almost_equal(LCHab_to_Lab(LCHab), Lab, decimal=7)
def test_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition. """ np.testing.assert_almost_equal( LCHab_to_Lab(np.array([41.52787529, 59.12425901, 27.08848784])), np.array([41.52787529, 52.63858304, 26.92317922]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([55.11636304, 51.42135412, 143.03889556])), np.array([55.11636304, -41.08791787, 30.91825778]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([29.80565520, 52.32945383, 292.49133666])), np.array([29.80565520, 20.01830466, -48.34913874]), decimal=7)
def test_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition. """ np.testing.assert_almost_equal( LCHab_to_Lab(np.array([37.98562910, 24.03845422, 190.58923377])), np.array([37.98562910, -23.62907688, -4.41746615]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([65.70971880, 56.17077461, 42.27159870])), np.array([65.70971880, 41.56438554, 37.78303554]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([50.86223896, 38.51719507, 31.72647736])), np.array([50.86223896, 32.76150086, 20.25483590]), decimal=7)
def test_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition. """ np.testing.assert_almost_equal( LCHab_to_Lab(np.array([100, 21.57210357, 272.2281935])), np.array([100., 0.83871284, -21.55579303]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([100, 426.67945353, 72.39590835])), np.array([100., 129.04406346, 406.69765889]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([100, 74.05216981, 276.45318193])), np.array([100., 8.32281957, -73.58297716]), decimal=7)
def test_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition. """ np.testing.assert_almost_equal( LCHab_to_Lab(np.array([37.98562910, 24.03190365, 190.58415972])), np.array([37.98562910, -23.62302887, -4.41417036]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([65.70971880, 56.18154795, 42.26641468])), np.array([65.70971880, 41.57577646, 37.78652063]), decimal=7) np.testing.assert_almost_equal( LCHab_to_Lab(np.array([50.86223896, 38.52678179, 31.72327940])), np.array([50.86223896, 32.77078577, 20.25804815]), decimal=7)
def test_nan_LCHab_to_Lab(self): """ Tests :func:`colour.models.cie_lab.LCHab_to_Lab` definition nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = set(permutations(cases * 3, r=3)) for case in cases: LCHab = np.array(case) LCHab_to_Lab(LCHab)
def highlights_recovery_LCHab(RGB, threshold=None, RGB_colourspace=sRGB_COLOURSPACE): """ Performs highlights recovery in *CIE L\\*C\\*Hab* colourspace. Parameters ---------- RGB : array_like *RGB* colourspace array. threshold : numeric, optional Threshold for highlights selection, automatically computed if not given. RGB_colourspace : RGB_Colourspace, optional Working *RGB* colourspace to perform the *CIE L\\*C\\*Hab* to and from. Returns ------- ndarray Highlights recovered *RGB* colourspace array. """ L, _C, H = tsplit( Lab_to_LCHab( XYZ_to_Lab( RGB_to_XYZ(RGB, RGB_colourspace.whitepoint, RGB_colourspace.whitepoint, RGB_colourspace.RGB_to_XYZ_matrix), RGB_colourspace.whitepoint))) _L_c, C_c, _H_c = tsplit( Lab_to_LCHab( XYZ_to_Lab( RGB_to_XYZ(np.clip(RGB, 0, threshold), RGB_colourspace.whitepoint, RGB_colourspace.whitepoint, RGB_colourspace.RGB_to_XYZ_matrix), RGB_colourspace.whitepoint))) return XYZ_to_RGB( Lab_to_XYZ(LCHab_to_Lab(tstack([L, C_c, H])), RGB_colourspace.whitepoint), RGB_colourspace.whitepoint, RGB_colourspace.whitepoint, RGB_colourspace.XYZ_to_RGB_matrix)
def is_within_pointer_gamut(XYZ: ArrayLike, tolerance: Optional[Floating] = None) -> NDArray: """ Return whether given *CIE XYZ* tristimulus values are within Pointer's Gamut volume. Parameters ---------- XYZ *CIE XYZ* tristimulus values. tolerance Tolerance allowed in the inside-triangle check. Returns ------- :class:`numpy.ndarray` Wether given *CIE XYZ* tristimulus values are within Pointer's Gamut volume. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``XYZ`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ Examples -------- >>> import numpy as np >>> is_within_pointer_gamut(np.array([0.3205, 0.4131, 0.5100])) array(True, dtype=bool) >>> a = np.array([[0.3205, 0.4131, 0.5100], [0.0005, 0.0031, 0.0010]]) >>> is_within_pointer_gamut(a) array([ True, False], dtype=bool) """ XYZ_p = Lab_to_XYZ(LCHab_to_Lab(DATA_POINTER_GAMUT_VOLUME), CCS_ILLUMINANT_POINTER_GAMUT) return is_within_mesh_volume(XYZ, XYZ_p, tolerance)
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)
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 plot_pointer_gamut(method='CIE 1931', **kwargs): """ Plots *Pointer's Gamut* according to given method. Parameters ---------- method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, Plotting method. Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definitions. Returns ------- tuple Current figure and axes. Examples -------- >>> plot_pointer_gamut() # doctest: +SKIP .. image:: ../_static/Plotting_Plot_Pointer_Gamut.png :align: center :alt: plot_pointer_gamut """ settings = {'uniform': True} settings.update(kwargs) figure, axes = artist(**settings) method = method.upper() if method == 'CIE 1931': def XYZ_to_ij(XYZ, *args): """ Converts given *CIE XYZ* tristimulus values to *ij* chromaticity coordinates. """ return XYZ_to_xy(XYZ, *args) def xy_to_ij(xy): """ Converts given *xy* chromaticity coordinates to *ij* chromaticity coordinates. """ return xy elif method == 'CIE 1960 UCS': def XYZ_to_ij(XYZ, *args): """ Converts given *CIE XYZ* tristimulus values to *ij* chromaticity coordinates. """ return UCS_to_uv(XYZ_to_UCS(XYZ)) def xy_to_ij(xy): """ Converts given *xy* chromaticity coordinates to *ij* chromaticity coordinates. """ return xy_to_UCS_uv(xy) elif method == 'CIE 1976 UCS': def XYZ_to_ij(XYZ, *args): """ Converts given *CIE XYZ* tristimulus values to *ij* chromaticity coordinates. """ return Luv_to_uv(XYZ_to_Luv(XYZ, *args), *args) def xy_to_ij(xy): """ Converts given *xy* chromaticity coordinates to *ij* chromaticity coordinates. """ return xy_to_Luv_uv(xy) else: raise ValueError( 'Invalid method: "{0}", must be one of ' '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format( method)) ij = xy_to_ij(as_float_array(POINTER_GAMUT_BOUNDARIES)) alpha_p = COLOUR_STYLE_CONSTANTS.opacity.high colour_p = COLOUR_STYLE_CONSTANTS.colour.darkest axes.plot(ij[..., 0], ij[..., 1], label='Pointer\'s Gamut', color=colour_p, alpha=alpha_p) axes.plot((ij[-1][0], ij[0][0]), (ij[-1][1], ij[0][1]), color=colour_p, alpha=alpha_p) XYZ = Lab_to_XYZ(LCHab_to_Lab(POINTER_GAMUT_DATA), POINTER_GAMUT_ILLUMINANT) ij = XYZ_to_ij(XYZ, POINTER_GAMUT_ILLUMINANT) axes.scatter(ij[..., 0], ij[..., 1], alpha=alpha_p / 2, color=colour_p, marker='+') settings.update({'axes': axes}) settings.update(kwargs) return render(**settings)
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)