def corresponding_chromaticities_prediction_CMCCAT2000(experiment=1, **kwargs): """ Returns the corresponding chromaticities prediction for CMCCAT2000 chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. \**kwargs : dict, optional Keywords arguments. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_CMCCAT2000(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.20832101929657834, 0.47271680534693694)), ((0.449, 0.511), (0.44592707020371486, 0.50777351504395707)), ((0.263, 0.505), (0.26402624712986333, 0.4955361681706304)), ((0.322, 0.545), (0.33168840090358015, 0.54315801981008516)), ((0.316, 0.537), (0.32226245779851387, 0.53576245377085929)), ((0.265, 0.553), (0.27107058097430181, 0.5501997842556422)), ((0.221, 0.538), (0.22618269421847523, 0.52947407170848704)), ((0.135, 0.532), (0.14396930475660724, 0.51909841743126817)), ((0.145, 0.472), (0.14948357434418671, 0.45567605010224305)), ((0.163, 0.331), (0.15631720730028753, 0.31641514460738623)), ((0.176, 0.431), (0.17631993066748047, 0.41275893424542082)), ((0.244, 0.349), (0.22876382018951744, 0.3499324084859976))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) XYZ_w = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) * 100 XYZ_wr = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) * 100 xy_wr = XYZ_to_xy(XYZ_wr) L_A1 = L_A2 = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES.get( experiment).Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) * 100 XYZ_2 = chromatic_adaptation_CMCCAT2000( XYZ_1, XYZ_w, XYZ_wr, L_A1, L_A2) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr) prediction.append(CorrespondingChromaticitiesPrediction( result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def corresponding_chromaticities_prediction_Fairchild1990(experiment=1): """ Returns the corresponding chromaticities prediction for *Fairchild (1990)* chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} *Breneman (1987)* experiment number. Returns ------- tuple Corresponding chromaticities prediction. References ---------- :cite:`Breneman1987b`, :cite:`Fairchild1991a`, :cite:`Fairchild2013s` Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_Fairchild1990(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2089528..., 0.4724034...)), ((0.449, 0.511), (0.4375652..., 0.5121030...)), ((0.263, 0.505), (0.2621362..., 0.4972538...)), ((0.322, 0.545), (0.3235312..., 0.5475665...)), ((0.316, 0.537), (0.3151390..., 0.5398333...)), ((0.265, 0.553), (0.2634745..., 0.5544335...)), ((0.221, 0.538), (0.2211595..., 0.5324470...)), ((0.135, 0.532), (0.1396949..., 0.5207234...)), ((0.145, 0.472), (0.1512288..., 0.4533041...)), ((0.163, 0.331), (0.1715691..., 0.3026264...)), ((0.176, 0.431), (0.1825792..., 0.4077892...)), ((0.244, 0.349), (0.2418904..., 0.3413401...))] """ with domain_range_scale(1): experiment_results = list(BRENEMAN_EXPERIMENTS[experiment]) illuminants = experiment_results.pop(0) XYZ_n = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) XYZ_r = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) xy_r = XYZ_to_xy(XYZ_r) Y_n = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES[experiment].Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) XYZ_2 = chromatic_adaptation_Fairchild1990(XYZ_1, XYZ_n, XYZ_r, Y_n) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_r), xy_r) prediction.append( CorrespondingChromaticitiesPrediction( result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def test_n_dimensional_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition n-dimensional arrays support. """ uv = np.array([0.15085310, 0.48532971]) xy = np.array([0.26414773, 0.37770001]) np.testing.assert_almost_equal( Luv_uv_to_xy(uv), xy, decimal=7) uv = np.tile(uv, (6, 1)) xy = np.tile(xy, (6, 1)) np.testing.assert_almost_equal( Luv_uv_to_xy(uv), xy, decimal=7) uv = np.reshape(uv, (2, 3, 2)) xy = np.reshape(xy, (2, 3, 2)) np.testing.assert_almost_equal( Luv_uv_to_xy(uv), xy, decimal=7)
def corresponding_chromaticities_prediction_Fairchild1990(experiment=1, **kwargs): """ Returns the corresponding chromaticities prediction for Fairchild (1990) chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. \**kwargs : dict, optional Keywords arguments. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_Fairchild1990(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2089528677990308, 0.47240345174230519)), ((0.449, 0.511), (0.43756528098582792, 0.51210303139041924)), ((0.263, 0.505), (0.26213623665658092, 0.49725385033264224)), ((0.322, 0.545), (0.3235312762825191, 0.54756652922585702)), ((0.316, 0.537), (0.3151390992740366, 0.53983332031574016)), ((0.265, 0.553), (0.26347459238415272, 0.55443357809543037)), ((0.221, 0.538), (0.22115956537655593, 0.53244703908294599)), ((0.135, 0.532), (0.13969494108553854, 0.52072342107668024)), ((0.145, 0.472), (0.1512288710743511, 0.45330415352961834)), ((0.163, 0.331), (0.17156913711903982, 0.30262647410866889)), ((0.176, 0.431), (0.18257922398137369, 0.40778921192793854)), ((0.244, 0.349), (0.24189049501108895, 0.34134012046930529))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) XYZ_n = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) * 100 XYZ_r = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) * 100 xy_r = XYZ_to_xy(XYZ_r) Y_n = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES.get(experiment).Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) * 100 XYZ_2 = chromatic_adaptation_Fairchild1990( XYZ_1, XYZ_n, XYZ_r, Y_n) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_r), xy_r) prediction.append(CorrespondingChromaticitiesPrediction( result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def corresponding_chromaticities_prediction_VonKries(experiment=1, transform='CAT02'): """ Returns the corresponding chromaticities prediction for *Von Kries* chromatic adaptation model using given transform. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} *Breneman (1987)* experiment number. transform : unicode, optional **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', 'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco', 'Bianco PC'}**, Chromatic adaptation transform. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_VonKries(2, 'Bradford') >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2082014..., 0.4722922...)), ((0.449, 0.511), (0.4489102..., 0.5071602...)), ((0.263, 0.505), (0.2643545..., 0.4959631...)), ((0.322, 0.545), (0.3348730..., 0.5471220...)), ((0.316, 0.537), (0.3248758..., 0.5390589...)), ((0.265, 0.553), (0.2733105..., 0.5555028...)), ((0.221, 0.538), (0.2271480..., 0.5331317...)), ((0.135, 0.532), (0.1442730..., 0.5226804...)), ((0.145, 0.472), (0.1498745..., 0.4550785...)), ((0.163, 0.331), (0.1564975..., 0.3148795...)), ((0.176, 0.431), (0.1760593..., 0.4103772...)), ((0.244, 0.349), (0.2259805..., 0.3465291...))] """ experiment_results = list(BRENEMAN_EXPERIMENTS[experiment]) illuminants = experiment_results.pop(0) XYZ_w = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) XYZ_wr = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) xy_wr = XYZ_to_xy(XYZ_wr) prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) XYZ_2 = chromatic_adaptation_VonKries(XYZ_1, XYZ_w, XYZ_wr, transform) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr) prediction.append( CorrespondingChromaticitiesPrediction(result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def corresponding_chromaticities_prediction_CIE1994(experiment=1): """ Returns the corresponding chromaticities prediction for CIE 1994 chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_CIE1994(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2133909..., 0.4939794...)), ((0.449, 0.511), (0.4450345..., 0.5120939...)), ((0.263, 0.505), (0.2693262..., 0.5083212...)), ((0.322, 0.545), (0.3308593..., 0.5443940...)), ((0.316, 0.537), (0.3225195..., 0.5377826...)), ((0.265, 0.553), (0.2709737..., 0.5513666...)), ((0.221, 0.538), (0.2280786..., 0.5351592...)), ((0.135, 0.532), (0.1439436..., 0.5303576...)), ((0.145, 0.472), (0.1500743..., 0.4842895...)), ((0.163, 0.331), (0.1559955..., 0.3772379...)), ((0.176, 0.431), (0.1806318..., 0.4518475...)), ((0.244, 0.349), (0.2454445..., 0.4018004...))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) xy_o1 = Luv_uv_to_xy(illuminants.uvp_t) xy_o2 = Luv_uv_to_xy(illuminants.uvp_m) # :math:`Y_o` is set to an arbitrary value in domain [18, 100]. Y_o = 18 E_o1 = E_o2 = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES.get( experiment).Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) * 100 XYZ_2 = chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_o2), xy_o2) prediction.append( CorrespondingChromaticitiesPrediction(result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def corresponding_chromaticities_prediction_CMCCAT2000(experiment=1): """ Returns the corresponding chromaticities prediction for CMCCAT2000 chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_CMCCAT2000(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2083210..., 0.4727168...)), ((0.449, 0.511), (0.4459270..., 0.5077735...)), ((0.263, 0.505), (0.2640262..., 0.4955361...)), ((0.322, 0.545), (0.3316884..., 0.5431580...)), ((0.316, 0.537), (0.3222624..., 0.5357624...)), ((0.265, 0.553), (0.2710705..., 0.5501997...)), ((0.221, 0.538), (0.2261826..., 0.5294740...)), ((0.135, 0.532), (0.1439693..., 0.5190984...)), ((0.145, 0.472), (0.1494835..., 0.4556760...)), ((0.163, 0.331), (0.1563172..., 0.3164151...)), ((0.176, 0.431), (0.1763199..., 0.4127589...)), ((0.244, 0.349), (0.2287638..., 0.3499324...))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) XYZ_w = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) * 100 XYZ_wr = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) * 100 xy_wr = XYZ_to_xy(XYZ_wr) L_A1 = L_A2 = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES.get( experiment).Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) * 100 XYZ_2 = chromatic_adaptation_CMCCAT2000(XYZ_1, XYZ_w, XYZ_wr, L_A1, L_A2) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr) prediction.append( CorrespondingChromaticitiesPrediction(result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def chromaticity_diagram_colours_CIE1976UCS( samples=4096, cmfs='CIE 1931 2 Degree Standard Observer', antialiasing=True): """ Plots the *CIE 1976 UCS Chromaticity Diagram* colours. Parameters ---------- samples : numeric, optional Samples count on one axis. cmfs : unicode, optional Standard observer colour matching functions used for diagram bounds. antialiasing : bool, optional Whether to apply anti-aliasing to the image. Other Parameters ---------------- \**kwargs : dict, optional {:func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definition. Returns ------- Figure Current figure or None. Examples -------- >>> chromaticity_diagram_colours_CIE1976UCS() # doctest: +SKIP """ cmfs = get_cmfs(cmfs) illuminant = DEFAULT_PLOTTING_ILLUMINANT triangulation = Delaunay(Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant), qhull_options='Qu QJ') xx, yy = np.meshgrid(np.linspace(0, 1, samples), np.linspace(1, 0, samples)) xy = tstack((xx, yy)) mask = (triangulation.find_simplex(xy) < 0).astype(DEFAULT_FLOAT_DTYPE) if antialiasing: kernel = np.array([ [0, 1, 0], [1, 2, 1], [0, 1, 0], ]).astype(DEFAULT_FLOAT_DTYPE) kernel /= np.sum(kernel) mask = convolve(mask, kernel) mask = 1 - mask[:, :, np.newaxis] XYZ = xy_to_XYZ(Luv_uv_to_xy(xy)) RGB = normalise_maximum(XYZ_to_sRGB(XYZ, illuminant), axis=-1) return np.dstack([RGB, mask])
def test_n_dimensional_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition n-dimensional arrays support. """ uv = np.array([0.37720213, 0.50120264]) xy = np.array([0.54369558, 0.32107944]) np.testing.assert_almost_equal(Luv_uv_to_xy(uv), xy, decimal=7) uv = np.tile(uv, (6, 1)) xy = np.tile(xy, (6, 1)) np.testing.assert_almost_equal(Luv_uv_to_xy(uv), xy, decimal=7) uv = np.reshape(uv, (2, 3, 2)) xy = np.reshape(xy, (2, 3, 2)) np.testing.assert_almost_equal(Luv_uv_to_xy(uv), xy, decimal=7)
def test_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition. """ np.testing.assert_almost_equal(Luv_uv_to_xy( np.array([0.37720213, 0.50120264])), np.array([0.54369558, 0.32107944]), decimal=7) np.testing.assert_almost_equal(Luv_uv_to_xy( np.array([0.14536327, 0.52992069])), np.array([0.29777734, 0.48246445]), decimal=7) np.testing.assert_almost_equal(Luv_uv_to_xy( np.array([0.16953603, 0.30039234])), np.array([0.18582824, 0.14633764]), decimal=7)
def test_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition. """ np.testing.assert_almost_equal(Luv_uv_to_xy( (0.20048615433157738, 0.4654903849082484)), (0.31352792378977895, 0.32353408235422665), decimal=7) np.testing.assert_almost_equal(Luv_uv_to_xy( (0.46412000081619281, 0.54388500014670993)), (0.6867305880410077, 0.3576684816384643), decimal=7) np.testing.assert_almost_equal(Luv_uv_to_xy( (0.18133000048542355, 0.40268999998517152)), (0.2455958975694641, 0.2424039944946324), decimal=7)
def test_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition. """ np.testing.assert_almost_equal( Luv_uv_to_xy(np.array([0.15085310, 0.48532971])), np.array([0.26414773, 0.37770001]), decimal=7) np.testing.assert_almost_equal( Luv_uv_to_xy(np.array([0.31125983, 0.51970032])), np.array([0.50453169, 0.37440000]), decimal=7) np.testing.assert_almost_equal( Luv_uv_to_xy(np.array([0.30069387, 0.50794847])), np.array([0.47670437, 0.35790000]), decimal=7)
def test_nan_Luv_uv_to_xy(self): """ Tests :func:`colour.models.cie_luv.Luv_uv_to_xy` definition nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = set(permutations(cases * 3, r=2)) for case in cases: uv = np.array(case) Luv_uv_to_xy(uv)
def plot_chromaticity_diagram_colours( samples=256, diagram_opacity=1.0, diagram_clipping_path=None, cmfs='CIE 1931 2 Degree Standard Observer', method='CIE 1931', **kwargs): """ Plots the *Chromaticity Diagram* colours according to given method. Parameters ---------- samples : numeric, optional Samples count on one axis. diagram_opacity : numeric, optional Opacity of the *Chromaticity Diagram* colours. diagram_clipping_path : array_like, optional Path of points used to clip the *Chromaticity Diagram* colours. cmfs : unicode, optional Standard observer colour matching functions used for *Chromaticity Diagram* bounds. method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, *Chromaticity Diagram* 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_chromaticity_diagram_colours() # doctest: +SKIP .. image:: ../_static/Plotting_Plot_Chromaticity_Diagram_Colours.png :align: center :alt: plot_chromaticity_diagram_colours """ settings = {'uniform': True} settings.update(kwargs) figure, axes = artist(**settings) method = method.upper() cmfs = first_item(filter_cmfs(cmfs).values()) illuminant = COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint ii, jj = np.meshgrid( np.linspace(0, 1, samples), np.linspace(1, 0, samples)) ij = tstack([ii, jj]) if method == 'CIE 1931': XYZ = xy_to_XYZ(ij) spectral_locus = XYZ_to_xy(cmfs.values, illuminant) elif method == 'CIE 1960 UCS': XYZ = xy_to_XYZ(UCS_uv_to_xy(ij)) spectral_locus = UCS_to_uv(XYZ_to_UCS(cmfs.values)) elif method == 'CIE 1976 UCS': XYZ = xy_to_XYZ(Luv_uv_to_xy(ij)) spectral_locus = Luv_to_uv( XYZ_to_Luv(cmfs.values, illuminant), illuminant) else: raise ValueError( 'Invalid method: "{0}", must be one of ' '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format( method)) RGB = normalise_maximum( XYZ_to_plotting_colourspace(XYZ, illuminant), axis=-1) polygon = Polygon( spectral_locus if diagram_clipping_path is None else diagram_clipping_path, facecolor='none', edgecolor='none') axes.add_patch(polygon) # Preventing bounding box related issues as per # https://github.com/matplotlib/matplotlib/issues/10529 image = axes.imshow( RGB, interpolation='bilinear', extent=(0, 1, 0, 1), clip_path=None, alpha=diagram_opacity) image.set_clip_path(polygon) settings = {'axes': axes} settings.update(kwargs) return render(**kwargs)
def convert_experiment_results_Breneman1987(experiment): """ Converts *Breneman (1987)* experiment results to a :class:`colour.CorrespondingColourDataset` class instance. Parameters ---------- experiment : integer {1, 2, 3, 4, 6, 8, 9, 11, 12} *Breneman (1987)* experiment number. Returns ------- CorrespondingColourDataset :class:`colour.CorrespondingColourDataset` class instance. Examples -------- >>> from pprint import pprint >>> pprint(tuple(convert_experiment_results_Breneman1987(2))) ... # doctest: +ELLIPSIS (2, array([ 0.9582463..., 1. , 0.9436325...]), array([ 0.9587332..., 1. , 0.4385796...]), array([[ 388.125 , 405. , 345.625 ], [ 266.8957925..., 135. , 28.5983365...], [ 474.5717821..., 405. , 222.75 ...], [ 538.3899082..., 405. , 24.8944954...], [ 178.7430167..., 135. , 19.6089385...], [ 436.6749547..., 405. , 26.5483725...], [ 124.7746282..., 135. , 36.1965613...], [ 77.0794172..., 135. , 60.5850563...], [ 279.9390889..., 405. , 455.8395127...], [ 149.5808157..., 135. , 498.7046827...], [ 372.1113689..., 405. , 669.9883990...], [ 212.3638968..., 135. , 414.6704871...]]), array([[ 400.1039651..., 405. , 191.7287234...], [ 271.0384615..., 135. , 13.5 ...], [ 495.4705323..., 405. , 119.7290874...], [ 580.7967033..., 405. , 6.6758241...], [ 190.1933701..., 135. , 7.4585635...], [ 473.7184115..., 405. , 10.2346570...], [ 135.4936014..., 135. , 20.2376599...], [ 86.4689781..., 135. , 35.2281021...], [ 283.5396281..., 405. , 258.1775929...], [ 119.7044335..., 135. , 282.6354679...], [ 359.9532224..., 405. , 381.0031185...], [ 181.8271461..., 135. , 204.0661252...]]), array(1500), array(1500), 0.3, 0.3, {}) """ valid_experiment_results = (1, 2, 3, 4, 6, 8, 9, 11, 12) assert experiment in valid_experiment_results, ( '"Breneman (1987)" experiment result must be one of "{0}"!'.format( valid_experiment_results)) samples_luminance = [ 0.270, 0.090, 0.270, 0.270, 0.090, 0.270, 0.090, 0.090, 0.270, 0.090, 0.270, 0.090, ] experiment_results = list(BRENEMAN_EXPERIMENTS[experiment]) illuminant_chromaticities = experiment_results.pop(0) Y_r = Y_t = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES[experiment].Y B_r = B_t = 0.3 XYZ_t, XYZ_r = xy_to_XYZ( np.hstack([ Luv_uv_to_xy(illuminant_chromaticities[1:3]), np.full([2, 1], Y_r) ])) / Y_r xyY_cr, xyY_ct = [], [] for i, experiment_result in enumerate(experiment_results): xyY_cr.append( np.hstack([ Luv_uv_to_xy(experiment_result[2]), samples_luminance[i] * Y_r ])) xyY_ct.append( np.hstack([ Luv_uv_to_xy(experiment_result[1]), samples_luminance[i] * Y_t ])) XYZ_cr = xyY_to_XYZ(xyY_cr) XYZ_ct = xyY_to_XYZ(xyY_ct) return CorrespondingColourDataset(experiment, XYZ_r, XYZ_t, XYZ_cr, XYZ_ct, Y_r, Y_t, B_r, B_t, {})
def CIE_1976_UCS_chromaticity_diagram_colours_plot( surface=1.25, spacing=0.00075, cmfs='CIE 1931 2 Degree Standard Observer', **kwargs): """ Plots the *CIE 1976 UCS Chromaticity Diagram* colours. Parameters ---------- surface : numeric, optional Generated markers surface. spacing : numeric, optional Spacing between markers. cmfs : unicode, optional Standard observer colour matching functions used for diagram bounds. \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> CIE_1976_UCS_chromaticity_diagram_colours_plot() # doctest: +SKIP True """ cmfs, name = get_cmfs(cmfs), cmfs illuminant = ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get( 'D50') Luvs = [XYZ_to_Luv(value, illuminant) for key, value in cmfs] u, v = tuple(zip(*([Luv_to_uv(x) for x in Luvs]))) path = matplotlib.path.Path(tuple(zip(u, v))) x_dot, y_dot, colours = [], [], [] for i in np.arange(0, 1, spacing): for j in np.arange(0, 1, spacing): if path.contains_path(matplotlib.path.Path([[i, j], [i, j]])): x_dot.append(i) y_dot.append(j) XYZ = xy_to_XYZ(Luv_uv_to_xy((i, j))) RGB = normalise(XYZ_to_sRGB(XYZ, illuminant)) colours.append(RGB) pylab.scatter(x_dot, y_dot, color=colours, s=surface) settings = { 'no_ticks': True, 'bounding_box': [0, 1, 0, 1], 'bbox_inches': 'tight', 'pad_inches': 0 } settings.update(kwargs) bounding_box(**settings) aspect(**settings) return display(**settings)
def plot_chromaticity_diagram_colours( samples=256, diagram_opacity=1.0, diagram_clipping_path=None, cmfs='CIE 1931 2 Degree Standard Observer', method='CIE 1931', **kwargs): """ Plots the *Chromaticity Diagram* colours according to given method. Parameters ---------- samples : numeric, optional Samples count on one axis. diagram_opacity : numeric, optional Opacity of the *Chromaticity Diagram* colours. diagram_clipping_path : array_like, optional Path of points used to clip the *Chromaticity Diagram* colours. cmfs : unicode or XYZ_ColourMatchingFunctions, optional Standard observer colour matching functions used for computing the spectral locus boundaries. ``cmfs`` can be of any type or form supported by the :func:`colour.plotting.filter_cmfs` definition. method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, *Chromaticity Diagram* 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_chromaticity_diagram_colours() # doctest: +ELLIPSIS (<Figure size ... with 1 Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_Plot_Chromaticity_Diagram_Colours.png :align: center :alt: plot_chromaticity_diagram_colours """ settings = {'uniform': True} settings.update(kwargs) _figure, axes = artist(**settings) method = method.upper() cmfs = first_item(filter_cmfs(cmfs).values()) illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint ii, jj = np.meshgrid(np.linspace(0, 1, samples), np.linspace(1, 0, samples)) ij = tstack([ii, jj]) # NOTE: Various values in the grid have potential to generate # zero-divisions, they could be avoided by perturbing the grid, e.g. adding # a small epsilon. It was decided instead to disable warnings. with suppress_warnings(python_warnings=True): if method == 'CIE 1931': XYZ = xy_to_XYZ(ij) spectral_locus = XYZ_to_xy(cmfs.values, illuminant) elif method == 'CIE 1960 UCS': XYZ = xy_to_XYZ(UCS_uv_to_xy(ij)) spectral_locus = UCS_to_uv(XYZ_to_UCS(cmfs.values)) elif method == 'CIE 1976 UCS': XYZ = xy_to_XYZ(Luv_uv_to_xy(ij)) spectral_locus = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant) else: raise ValueError( 'Invalid method: "{0}", must be one of ' '[\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\']'.format( method)) RGB = normalise_maximum(XYZ_to_plotting_colourspace(XYZ, illuminant), axis=-1) polygon = Polygon(spectral_locus if diagram_clipping_path is None else diagram_clipping_path, facecolor='none', edgecolor='none') axes.add_patch(polygon) # Preventing bounding box related issues as per # https://github.com/matplotlib/matplotlib/issues/10529 image = axes.imshow(RGB, interpolation='bilinear', extent=(0, 1, 0, 1), clip_path=None, alpha=diagram_opacity) image.set_clip_path(polygon) settings = {'axes': axes} settings.update(kwargs) return render(**kwargs)
def corresponding_chromaticities_prediction_CIE1994(experiment=1, **kwargs): """ Returns the corresponding chromaticities prediction for CIE 1994 chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. \**kwargs : dict, optional Keywords arguments. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_CIE1994(2) >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.21339093279517196, 0.49397945742298016)), ((0.449, 0.511), (0.4450345313098153, 0.5120939085633327)), ((0.263, 0.505), (0.26932620724691858, 0.50832124608390727)), ((0.322, 0.545), (0.33085939370840811, 0.54439408389253441)), ((0.316, 0.537), (0.3225195584183046, 0.53778269440789594)), ((0.265, 0.553), (0.2709737181087471, 0.5513666373694861)), ((0.221, 0.538), (0.22807869730753863, 0.53515923458385406)), ((0.135, 0.532), (0.14394366662060523, 0.53035769204585748)), ((0.145, 0.472), (0.15007438031976222, 0.48428958620888679)), ((0.163, 0.331), (0.15599555781959967, 0.37723798698131394)), ((0.176, 0.431), (0.18063180902005657, 0.45184759430042898)), ((0.244, 0.349), (0.24544456656434688, 0.40180048388092021))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) xy_o1 = Luv_uv_to_xy(illuminants.uvp_t) xy_o2 = Luv_uv_to_xy(illuminants.uvp_m) # :math:`Y_o` is set to an arbitrary value in domain [18, 100]. Y_o = 18 E_o1 = E_o2 = BRENEMAN_EXPERIMENTS_PRIMARIES_CHROMATICITIES.get( experiment).Y prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) * 100 XYZ_2 = chromatic_adaptation_CIE1994( XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_o2), xy_o2) prediction.append(CorrespondingChromaticitiesPrediction( result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)
def CIE_1976_UCS_chromaticity_diagram_colours_plot( surface=1, samples=4096, cmfs='CIE 1931 2 Degree Standard Observer', **kwargs): """ Plots the *CIE 1976 UCS Chromaticity Diagram* colours. Parameters ---------- surface : numeric, optional Generated markers surface. samples : numeric, optional Samples count on one axis. cmfs : unicode, optional Standard observer colour matching functions used for diagram bounds. \**kwargs : dict, optional Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> CIE_1976_UCS_chromaticity_diagram_colours_plot() # doctest: +SKIP True """ if is_scipy_installed(raise_exception=True): from scipy.spatial import Delaunay settings = {'figure_size': (64, 64)} settings.update(kwargs) canvas(**settings) cmfs = get_cmfs(cmfs) illuminant = DEFAULT_PLOTTING_ILLUMINANT triangulation = Delaunay(Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant), qhull_options='QJ Qf') xx, yy = np.meshgrid(np.linspace(0, 1, samples), np.linspace(0, 1, samples)) xy = tstack((xx, yy)) xy = xy[triangulation.find_simplex(xy) > 0] XYZ = xy_to_XYZ(Luv_uv_to_xy(xy)) RGB = normalise(XYZ_to_sRGB(XYZ, illuminant), axis=-1) x_dot, y_dot = tsplit(xy) pylab.scatter(x_dot, y_dot, color=RGB, s=surface) settings.update({ 'x_ticker': False, 'y_ticker': False, 'bounding_box': (0, 1, 0, 1), 'bbox_inches': 'tight', 'pad_inches': 0 }) settings.update(kwargs) ax = matplotlib.pyplot.gca() matplotlib.pyplot.setp(ax, frame_on=False) boundaries(**settings) decorate(**settings) return display(**settings)
def plot_spectral_locus(cmfs='CIE 1931 2 Degree Standard Observer', spectral_locus_colours=None, spectral_locus_labels=None, method='CIE 1931', **kwargs): """ Plots the *Spectral Locus* according to given method. Parameters ---------- cmfs : unicode, optional Standard observer colour matching functions defining the *Spectral Locus*. spectral_locus_colours : array_like or unicode, optional *Spectral Locus* colours, if ``spectral_locus_colours`` is set to *RGB*, the colours will be computed according to the corresponding chromaticity coordinates. spectral_locus_labels : array_like, optional Array of wavelength labels used to customise which labels will be drawn around the spectral locus. Passing an empty array will result in no wavelength labels being drawn. method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, *Chromaticity Diagram* 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_spectral_locus(spectral_locus_colours='RGB') # doctest: +SKIP .. image:: ../_static/Plotting_Plot_Spectral_Locus.png :align: center :alt: plot_spectral_locus """ if spectral_locus_colours is None: spectral_locus_colours = COLOUR_STYLE_CONSTANTS.colour.dark settings = {'uniform': True} settings.update(kwargs) figure, axes = artist(**settings) method = method.upper() cmfs = first_item(filter_cmfs(cmfs).values()) illuminant = COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint wavelengths = cmfs.wavelengths equal_energy = np.array([1 / 3] * 2) if method == 'CIE 1931': ij = XYZ_to_xy(cmfs.values, illuminant) labels = ((390, 460, 470, 480, 490, 500, 510, 520, 540, 560, 580, 600, 620, 700) if spectral_locus_labels is None else spectral_locus_labels) elif method == 'CIE 1960 UCS': ij = UCS_to_uv(XYZ_to_UCS(cmfs.values)) labels = ((420, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 645, 680) if spectral_locus_labels is None else spectral_locus_labels) elif method == 'CIE 1976 UCS': ij = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant) labels = ((420, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 645, 680) if spectral_locus_labels is None else spectral_locus_labels) else: raise ValueError( 'Invalid method: "{0}", must be one of ' '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format( method)) pl_ij = tstack([ np.linspace(ij[0][0], ij[-1][0], 20), np.linspace(ij[0][1], ij[-1][1], 20) ]).reshape(-1, 1, 2) sl_ij = np.copy(ij).reshape(-1, 1, 2) if spectral_locus_colours.upper() == 'RGB': spectral_locus_colours = normalise_maximum( XYZ_to_plotting_colourspace(cmfs.values), axis=-1) if method == 'CIE 1931': XYZ = xy_to_XYZ(pl_ij) elif method == 'CIE 1960 UCS': XYZ = xy_to_XYZ(UCS_uv_to_xy(pl_ij)) elif method == 'CIE 1976 UCS': XYZ = xy_to_XYZ(Luv_uv_to_xy(pl_ij)) purple_line_colours = normalise_maximum( XYZ_to_plotting_colourspace(XYZ.reshape(-1, 3)), axis=-1) else: purple_line_colours = spectral_locus_colours for slp_ij, slp_colours in ((pl_ij, purple_line_colours), (sl_ij, spectral_locus_colours)): line_collection = LineCollection( np.concatenate([slp_ij[:-1], slp_ij[1:]], axis=1), colors=slp_colours) axes.add_collection(line_collection) wl_ij = dict(tuple(zip(wavelengths, ij))) for label in labels: i, j = wl_ij[label] index = bisect.bisect(wavelengths, label) left = wavelengths[index - 1] if index >= 0 else wavelengths[index] right = (wavelengths[index] if index < len(wavelengths) else wavelengths[-1]) dx = wl_ij[right][0] - wl_ij[left][0] dy = wl_ij[right][1] - wl_ij[left][1] ij = np.array([i, j]) direction = np.array([-dy, dx]) normal = (np.array([-dy, dx]) if np.dot( normalise_vector(ij - equal_energy), normalise_vector(direction)) > 0 else np.array([dy, -dx])) normal = normalise_vector(normal) / 30 label_colour = (spectral_locus_colours if is_string(spectral_locus_colours) else spectral_locus_colours[index]) axes.plot( (i, i + normal[0] * 0.75), (j, j + normal[1] * 0.75), color=label_colour) axes.plot(i, j, 'o', color=label_colour) axes.text( i + normal[0], j + normal[1], label, clip_on=True, ha='left' if normal[0] >= 0 else 'right', va='center', fontdict={'size': 'small'}) settings = {'axes': axes} settings.update(kwargs) return render(**kwargs)
def plot_spectral_locus( cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[ MultiSpectralDistributions, str]], ] = "CIE 1931 2 Degree Standard Observer", spectral_locus_colours: Optional[Union[ArrayLike, str]] = None, spectral_locus_opacity: Floating = 1, spectral_locus_labels: Optional[Sequence] = None, method: Union[Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"], str] = "CIE 1931", **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: """ Plot the *Spectral Locus* according to given method. Parameters ---------- cmfs Standard observer colour matching functions used for computing the spectral locus boundaries. ``cmfs`` can be of any type or form supported by the :func:`colour.plotting.filter_cmfs` definition. spectral_locus_colours Colours of the *Spectral Locus*, if ``spectral_locus_colours`` is set to *RGB*, the colours will be computed according to the corresponding chromaticity coordinates. spectral_locus_opacity Opacity of the *Spectral Locus*. spectral_locus_labels Array of wavelength labels used to customise which labels will be drawn around the spectral locus. Passing an empty array will result in no wavelength labels being drawn. method *Chromaticity Diagram* method. Other Parameters ---------------- kwargs {:func:`colour.plotting.artist`, :func:`colour.plotting.render`}, See the documentation of the previously listed definitions. Returns ------- :class:`tuple` Current figure and axes. Examples -------- >>> plot_spectral_locus(spectral_locus_colours='RGB') # doctest: +ELLIPSIS (<Figure size ... with 1 Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_Plot_Spectral_Locus.png :align: center :alt: plot_spectral_locus """ method = validate_method(method, ["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"]) spectral_locus_colours = optional(spectral_locus_colours, CONSTANTS_COLOUR_STYLE.colour.dark) settings: Dict[str, Any] = {"uniform": True} settings.update(kwargs) _figure, axes = artist(**settings) cmfs = cast(MultiSpectralDistributions, first_item(filter_cmfs(cmfs).values())) illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint wavelengths = list(cmfs.wavelengths) equal_energy = np.array([1 / 3] * 2) if method == "cie 1931": ij = XYZ_to_xy(cmfs.values, illuminant) labels = cast( Tuple, optional( spectral_locus_labels, ( 390, 460, 470, 480, 490, 500, 510, 520, 540, 560, 580, 600, 620, 700, ), ), ) elif method == "cie 1960 ucs": ij = UCS_to_uv(XYZ_to_UCS(cmfs.values)) labels = cast( Tuple, optional( spectral_locus_labels, ( 420, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 645, 680, ), ), ) elif method == "cie 1976 ucs": ij = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant) labels = cast( Tuple, optional( spectral_locus_labels, ( 420, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 645, 680, ), ), ) pl_ij = np.reshape( tstack([ np.linspace(ij[0][0], ij[-1][0], 20), np.linspace(ij[0][1], ij[-1][1], 20), ]), (-1, 1, 2), ) sl_ij = np.copy(ij).reshape(-1, 1, 2) purple_line_colours: Optional[Union[ArrayLike, str]] if str(spectral_locus_colours).upper() == "RGB": spectral_locus_colours = normalise_maximum(XYZ_to_plotting_colourspace( cmfs.values), axis=-1) if method == "cie 1931": XYZ = xy_to_XYZ(pl_ij) elif method == "cie 1960 ucs": XYZ = xy_to_XYZ(UCS_uv_to_xy(pl_ij)) elif method == "cie 1976 ucs": XYZ = xy_to_XYZ(Luv_uv_to_xy(pl_ij)) purple_line_colours = normalise_maximum(XYZ_to_plotting_colourspace( np.reshape(XYZ, (-1, 3))), axis=-1) else: purple_line_colours = spectral_locus_colours for slp_ij, slp_colours in ( (pl_ij, purple_line_colours), (sl_ij, spectral_locus_colours), ): line_collection = LineCollection( np.concatenate([slp_ij[:-1], slp_ij[1:]], axis=1), colors=slp_colours, alpha=spectral_locus_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_scatter, ) axes.add_collection(line_collection) wl_ij = dict(zip(wavelengths, ij)) for label in labels: ij_l = wl_ij.get(label) if ij_l is None: continue ij_l = as_float_array([ij_l]) i, j = tsplit(ij_l) index = bisect.bisect(wavelengths, label) left = wavelengths[index - 1] if index >= 0 else wavelengths[index] right = (wavelengths[index] if index < len(wavelengths) else wavelengths[-1]) dx = wl_ij[right][0] - wl_ij[left][0] dy = wl_ij[right][1] - wl_ij[left][1] direction = np.array([-dy, dx]) normal = (np.array([-dy, dx]) if np.dot( normalise_vector(ij_l - equal_energy), normalise_vector(direction), ) > 0 else np.array([dy, -dx])) normal = normalise_vector(normal) / 30 label_colour = ( spectral_locus_colours if is_string(spectral_locus_colours) else spectral_locus_colours[index] # type: ignore[index] ) axes.plot( (i, i + normal[0] * 0.75), (j, j + normal[1] * 0.75), color=label_colour, alpha=spectral_locus_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, ) axes.plot( i, j, "o", color=label_colour, alpha=spectral_locus_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, ) axes.text( i + normal[0], j + normal[1], label, clip_on=True, ha="left" if normal[0] >= 0 else "right", va="center", fontdict={"size": "small"}, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_label, ) settings = {"axes": axes} settings.update(kwargs) return render(**kwargs)
def plot_chromaticity_diagram_colours( samples: Integer = 256, diagram_colours: Optional[Union[ArrayLike, str]] = None, diagram_opacity: Floating = 1, diagram_clipping_path: Optional[ArrayLike] = None, cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[ MultiSpectralDistributions, str]], ] = "CIE 1931 2 Degree Standard Observer", method: Union[Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"], str] = "CIE 1931", **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: """ Plot the *Chromaticity Diagram* colours according to given method. Parameters ---------- samples Samples count on one axis when computing the *Chromaticity Diagram* colours. diagram_colours Colours of the *Chromaticity Diagram*, if ``diagram_colours`` is set to *RGB*, the colours will be computed according to the corresponding coordinates. diagram_opacity Opacity of the *Chromaticity Diagram*. diagram_clipping_path Path of points used to clip the *Chromaticity Diagram* colours. cmfs Standard observer colour matching functions used for computing the spectral locus boundaries. ``cmfs`` can be of any type or form supported by the :func:`colour.plotting.filter_cmfs` definition. method *Chromaticity Diagram* method. Other Parameters ---------------- kwargs {:func:`colour.plotting.artist`, :func:`colour.plotting.render`}, See the documentation of the previously listed definitions. Returns ------- :class:`tuple` Current figure and axes. Examples -------- >>> plot_chromaticity_diagram_colours(diagram_colours='RGB') ... # doctest: +ELLIPSIS (<Figure size ... with 1 Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_Plot_Chromaticity_Diagram_Colours.png :align: center :alt: plot_chromaticity_diagram_colours """ method = validate_method(method, ["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"]) settings: Dict[str, Any] = {"uniform": True} settings.update(kwargs) _figure, axes = artist(**settings) diagram_colours = cast( ArrayLike, optional(diagram_colours, HEX_to_RGB(CONSTANTS_COLOUR_STYLE.colour.average)), ) cmfs = cast(MultiSpectralDistributions, first_item(filter_cmfs(cmfs).values())) illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint if method == "cie 1931": spectral_locus = XYZ_to_xy(cmfs.values, illuminant) elif method == "cie 1960 ucs": spectral_locus = UCS_to_uv(XYZ_to_UCS(cmfs.values)) elif method == "cie 1976 ucs": spectral_locus = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant) use_RGB_diagram_colours = str(diagram_colours).upper() == "RGB" if use_RGB_diagram_colours: ii, jj = np.meshgrid(np.linspace(0, 1, samples), np.linspace(1, 0, samples)) ij = tstack([ii, jj]) # NOTE: Various values in the grid have potential to generate # zero-divisions, they could be avoided by perturbing the grid, e.g. # adding a small epsilon. It was decided instead to disable warnings. with suppress_warnings(python_warnings=True): if method == "cie 1931": XYZ = xy_to_XYZ(ij) elif method == "cie 1960 ucs": XYZ = xy_to_XYZ(UCS_uv_to_xy(ij)) elif method == "cie 1976 ucs": XYZ = xy_to_XYZ(Luv_uv_to_xy(ij)) diagram_colours = normalise_maximum(XYZ_to_plotting_colourspace( XYZ, illuminant), axis=-1) polygon = Polygon( spectral_locus if diagram_clipping_path is None else diagram_clipping_path, facecolor="none" if use_RGB_diagram_colours else np.hstack( [diagram_colours, diagram_opacity]), edgecolor="none" if use_RGB_diagram_colours else np.hstack( [diagram_colours, diagram_opacity]), zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon, ) axes.add_patch(polygon) if use_RGB_diagram_colours: # Preventing bounding box related issues as per # https://github.com/matplotlib/matplotlib/issues/10529 image = axes.imshow( diagram_colours, interpolation="bilinear", extent=(0, 1, 0, 1), clip_path=None, alpha=diagram_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon, ) image.set_clip_path(polygon) settings = {"axes": axes} settings.update(kwargs) return render(**kwargs)
def CIE_1976_UCS_chromaticity_diagram_colours_plot( surface=1, samples=4096, cmfs='CIE 1931 2 Degree Standard Observer', **kwargs): """ Plots the *CIE 1976 UCS Chromaticity Diagram* colours. Parameters ---------- surface : numeric, optional Generated markers surface. samples : numeric, optional Samples count on one axis. cmfs : unicode, optional Standard observer colour matching functions used for diagram bounds. Other Parameters ---------------- \**kwargs : dict, optional {:func:`boundaries`, :func:`canvas`, :func:`decorate`, :func:`display`}, Please refer to the documentation of the previously listed definitions. Returns ------- Figure Current figure or None. Examples -------- >>> CIE_1976_UCS_chromaticity_diagram_colours_plot() # doctest: +SKIP """ settings = {'figure_size': (64, 64)} settings.update(kwargs) canvas(**settings) cmfs = get_cmfs(cmfs) illuminant = DEFAULT_PLOTTING_ILLUMINANT triangulation = Delaunay(Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant), qhull_options='QJ Qf') xx, yy = np.meshgrid(np.linspace(0, 1, samples), np.linspace(0, 1, samples)) xy = tstack((xx, yy)) xy = xy[triangulation.find_simplex(xy) > 0] XYZ = xy_to_XYZ(Luv_uv_to_xy(xy)) RGB = normalise_maximum(XYZ_to_sRGB(XYZ, illuminant), axis=-1) x_dot, y_dot = tsplit(xy) pylab.scatter(x_dot, y_dot, color=RGB, s=surface) settings.update({ 'x_ticker': False, 'y_ticker': False, 'bounding_box': (0, 1, 0, 1) }) settings.update(kwargs) ax = matplotlib.pyplot.gca() matplotlib.pyplot.setp(ax, frame_on=False) boundaries(**settings) decorate(**settings) return display(**settings)
def corresponding_chromaticities_prediction_VonKries(experiment=1, transform='CAT02'): """ Returns the corresponding chromaticities prediction for Von Kries chromatic adaptation model using given transform. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. transform : unicode, optional **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', 'Fairchild, 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco', 'Bianco PC'}**, Chromatic adaptation transform. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction_VonKries(2, 'Bradford') >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.20820148430638033, 0.47229226819364528)), ((0.449, 0.511), (0.44891022948064191, 0.50716028901449561)), ((0.263, 0.505), (0.26435459360846608, 0.49596314494922683)), ((0.322, 0.545), (0.33487309037107632, 0.54712207251983425)), ((0.316, 0.537), (0.32487581236911361, 0.53905899356457776)), ((0.265, 0.553), (0.27331050571632376, 0.55550280647813977)), ((0.221, 0.538), (0.22714800102072819, 0.53313179748041983)), ((0.135, 0.532), (0.14427303768336433, 0.52268044497913713)), ((0.145, 0.472), (0.14987451889726533, 0.45507852741116867)), ((0.163, 0.331), (0.15649757464732098, 0.31487959772753954)), ((0.176, 0.431), (0.17605936460371163, 0.41037722722471409)), ((0.244, 0.349), (0.22598059059292835, 0.34652914678030416))] """ experiment_results = list(BRENEMAN_EXPERIMENTS.get(experiment)) illuminants = experiment_results.pop(0) XYZ_w = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_t)) XYZ_wr = xy_to_XYZ(Luv_uv_to_xy(illuminants.uvp_m)) xy_wr = XYZ_to_xy(XYZ_wr) prediction = [] for result in experiment_results: XYZ_1 = xy_to_XYZ(Luv_uv_to_xy(result.uvp_t)) XYZ_2 = chromatic_adaptation_VonKries(XYZ_1, XYZ_w, XYZ_wr, transform) uvp = Luv_to_uv(XYZ_to_Luv(XYZ_2, xy_wr), xy_wr) prediction.append(CorrespondingChromaticitiesPrediction( result.name, result.uvp_t, result.uvp_m, uvp)) return tuple(prediction)