def test_point_at_angle_on_ellipse(self): """ Tests :func:`colour.algebra.geometry.point_at_angle_on_ellipse` definition. """ np.testing.assert_almost_equal(point_at_angle_on_ellipse( np.array([0, 90, 180, 270]), np.array([0.0, 0.0, 2, 1, 0])), np.array([[2, 0], [0, 1], [-2, 0], [0, -1]]), decimal=7) np.testing.assert_almost_equal(point_at_angle_on_ellipse( np.linspace(0, 360, 10), np.array([0.5, 0.5, 2, 1, 45])), np.array([ [1.91421356, 1.91421356], [1.12883096, 2.03786992], [0.04921137, 1.44193985], [-0.81947922, 0.40526565], [-1.07077081, -0.58708129], [-0.58708129, -1.07077081], [0.40526565, -0.81947922], [1.44193985, 0.04921137], [2.03786992, 1.12883096], [1.91421356, 1.91421356], ]), decimal=7)
def test_point_at_angle_on_ellipse(self): """ Tests :func:`colour.algebra.geometry.point_at_angle_on_ellipse` definition. """ np.testing.assert_almost_equal( point_at_angle_on_ellipse( np.array([0, 90, 180, 270]), np.array([0.0, 0.0, 2, 1, 0])), np.array([[2, 0], [0, 1], [-2, 0], [0, -1]]), decimal=7) np.testing.assert_almost_equal( point_at_angle_on_ellipse( np.linspace(0, 360, 10), np.array([0.5, 0.5, 2, 1, 45])), np.array([ [1.91421356, 1.91421356], [1.12883096, 2.03786992], [0.04921137, 1.44193985], [-0.81947922, 0.40526565], [-1.07077081, -0.58708129], [-0.58708129, -1.07077081], [0.40526565, -0.81947922], [1.44193985, 0.04921137], [2.03786992, 1.12883096], [1.91421356, 1.91421356], ]), decimal=7)
def plot_ellipses_MacAdam1942_in_chromaticity_diagram( chromaticity_diagram_callable=plot_chromaticity_diagram, method='CIE 1931', chromaticity_diagram_clipping=False, ellipse_parameters=None, **kwargs): """ Plots *MacAdam (1942) Ellipses (Observer PGN)* in the *Chromaticity Diagram* according to given method. Parameters ---------- chromaticity_diagram_callable : callable, optional Callable responsible for drawing the *Chromaticity Diagram*. method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, *Chromaticity Diagram* method. chromaticity_diagram_clipping : bool, optional, Whether to clip the *Chromaticity Diagram* colours with the ellipses. ellipse_parameters : dict or array_like, optional Parameters for the :class:`Ellipse` class, ``ellipse_parameters`` can be either a single dictionary applied to all the ellipses with same settings or a sequence of dictionaries with different settings for each ellipse. Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.diagrams.plot_chromaticity_diagram`, :func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definitions. Returns ------- tuple Current figure and axes. Examples -------- >>> plot_ellipses_MacAdam1942_in_chromaticity_diagram() # doctest: +SKIP .. image:: ../_static/\ Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png :align: center :alt: plot_ellipses_MacAdam1942_in_chromaticity_diagram """ settings = {'uniform': True} settings.update(kwargs) figure, axes = artist(**settings) settings = dict(kwargs) settings.update({'axes': axes, 'standalone': False}) ellipses_coefficients = ellipses_MacAdam1942(method=method) if chromaticity_diagram_clipping: diagram_clipping_path_x = [] diagram_clipping_path_y = [] for coefficients in ellipses_coefficients: coefficients = np.copy(coefficients) coefficients[2:4] /= 2 x, y = tsplit( point_at_angle_on_ellipse( np.linspace(0, 360, 36), coefficients, )) diagram_clipping_path_x.append(x) diagram_clipping_path_y.append(y) diagram_clipping_path = np.rollaxis( np.array([diagram_clipping_path_x, diagram_clipping_path_y]), 0, 3) diagram_clipping_path = Path.make_compound_path_from_polys( diagram_clipping_path).vertices settings.update({'diagram_clipping_path': diagram_clipping_path}) chromaticity_diagram_callable(**settings) ellipse_settings_collection = [{ 'color': COLOUR_STYLE_CONSTANTS.colour.cycle[4], 'alpha': 0.4, 'edgecolor': COLOUR_STYLE_CONSTANTS.colour.cycle[1], 'linewidth': colour_style()['lines.linewidth'] } for _ in range(len(ellipses_coefficients))] if ellipse_parameters is not None: if not isinstance(ellipse_parameters, dict): assert len(ellipse_parameters) == len(ellipses_coefficients), ( 'Multiple ellipse parameters defined, but they do not match ' 'the ellipses count!') for i, ellipse_settings in enumerate(ellipse_settings_collection): if isinstance(ellipse_parameters, dict): ellipse_settings.update(ellipse_parameters) else: ellipse_settings.update(ellipse_parameters[i]) for i, coefficients in enumerate(ellipses_coefficients): x_c, y_c, a_a, a_b, theta_e = coefficients ellipse = Ellipse((x_c, y_c), a_a, a_b, theta_e, **ellipse_settings_collection[i]) axes.add_artist(ellipse) settings.update({'standalone': True}) settings.update(kwargs) return render(**settings)
def ellipses_MacAdam1942(method='CIE 1931'): """ Returns *MacAdam (1942) Ellipses (Observer PGN)* coefficients according to given method. Parameters ---------- method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, Computation method. Returns ------- tuple Current figure and axes. Examples -------- >>> ellipses_MacAdam1942()[0] # doctest: +SKIP array([ 1.60000000e-01, 5.70000000e-02, 5.00000023e-03, 1.56666660e-02, -2.77000015e+01]) """ method = method.upper() if method == 'CIE 1931': def xy_to_ij(xy): """ Converts given *xy* chromaticity coordinates to *ij* chromaticity coordinates. """ return xy elif method == 'CIE 1960 UCS': 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 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)) x, y, _a, _b, _theta, a, b, theta = tsplit(MACADAM_1942_ELLIPSES_DATA) ellipses_coefficients = [] for i in range(len(theta)): xy = point_at_angle_on_ellipse( np.linspace(0, 360, 36), [x[i], y[i], a[i] / 60, b[i] / 60, theta[i]], ) ij = xy_to_ij(xy) ellipses_coefficients.append( ellipse_coefficients_canonical_form(ellipse_fitting(ij))) return ellipses_coefficients
def plot_ellipses_MacAdam1942_in_chromaticity_diagram( chromaticity_diagram_callable=plot_chromaticity_diagram, method='CIE 1931', chromaticity_diagram_clipping=False, ellipse_parameters=None, **kwargs): """ Plots *MacAdam (1942) Ellipses (Observer PGN)* in the *Chromaticity Diagram* according to given method. Parameters ---------- chromaticity_diagram_callable : callable, optional Callable responsible for drawing the *Chromaticity Diagram*. method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, *Chromaticity Diagram* method. chromaticity_diagram_clipping : bool, optional, Whether to clip the *Chromaticity Diagram* colours with the ellipses. ellipse_parameters : dict or array_like, optional Parameters for the :class:`Ellipse` class, ``ellipse_parameters`` can be either a single dictionary applied to all the ellipses with same settings or a sequence of dictionaries with different settings for each ellipse. Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.diagrams.plot_chromaticity_diagram`, :func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definitions. Returns ------- tuple Current figure and axes. Examples -------- >>> plot_ellipses_MacAdam1942_in_chromaticity_diagram() # doctest: +SKIP .. image:: ../_static/\ Plotting_Plot_Ellipses_MacAdam1942_In_Chromaticity_Diagram.png :align: center :alt: plot_ellipses_MacAdam1942_in_chromaticity_diagram """ settings = {'uniform': True} settings.update(kwargs) _figure, axes = artist(**settings) settings = dict(kwargs) settings.update({'axes': axes, 'standalone': False}) ellipses_coefficients = ellipses_MacAdam1942(method=method) if chromaticity_diagram_clipping: diagram_clipping_path_x = [] diagram_clipping_path_y = [] for coefficients in ellipses_coefficients: coefficients = np.copy(coefficients) coefficients[2:4] /= 2 x, y = tsplit( point_at_angle_on_ellipse( np.linspace(0, 360, 36), coefficients, )) diagram_clipping_path_x.append(x) diagram_clipping_path_y.append(y) diagram_clipping_path = np.rollaxis( np.array([diagram_clipping_path_x, diagram_clipping_path_y]), 0, 3) diagram_clipping_path = Path.make_compound_path_from_polys( diagram_clipping_path).vertices settings.update({'diagram_clipping_path': diagram_clipping_path}) chromaticity_diagram_callable(**settings) ellipse_settings_collection = [{ 'color': COLOUR_STYLE_CONSTANTS.colour.cycle[4], 'alpha': 0.4, 'edgecolor': COLOUR_STYLE_CONSTANTS.colour.cycle[1], 'linewidth': colour_style()['lines.linewidth'] } for _ellipses_coefficient in ellipses_coefficients] if ellipse_parameters is not None: if not isinstance(ellipse_parameters, dict): assert len(ellipse_parameters) == len(ellipses_coefficients), ( 'Multiple ellipse parameters defined, but they do not match ' 'the ellipses count!') for i, ellipse_settings in enumerate(ellipse_settings_collection): if isinstance(ellipse_parameters, dict): ellipse_settings.update(ellipse_parameters) else: ellipse_settings.update(ellipse_parameters[i]) for i, coefficients in enumerate(ellipses_coefficients): x_c, y_c, a_a, a_b, theta_e = coefficients ellipse = Ellipse((x_c, y_c), a_a, a_b, theta_e, **ellipse_settings_collection[i]) axes.add_artist(ellipse) settings.update({'standalone': True}) settings.update(kwargs) return render(**settings)
def ellipses_MacAdam1942(method='CIE 1931'): """ Returns *MacAdam (1942) Ellipses (Observer PGN)* coefficients according to given method. Parameters ---------- method : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, Computation method. Returns ------- tuple Current figure and axes. Examples -------- >>> ellipses_MacAdam1942()[0] # doctest: +SKIP array([ 1.60000000e-01, 5.70000000e-02, 5.00000023e-03, 1.56666660e-02, -2.77000015e+01]) """ method = method.upper() if method == 'CIE 1931': def xy_to_ij(xy): """ Converts given *xy* chromaticity coordinates to *ij* chromaticity coordinates. """ return xy elif method == 'CIE 1960 UCS': 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 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)) x, y, _a, _b, _theta, a, b, theta = tsplit(MACADAM_1942_ELLIPSES_DATA) ellipses_coefficients = [] # pylint: disable=C0200 for i in range(len(theta)): xy = point_at_angle_on_ellipse( np.linspace(0, 360, 36), [x[i], y[i], a[i] / 60, b[i] / 60, theta[i]], ) ij = xy_to_ij(xy) ellipses_coefficients.append( ellipse_coefficients_canonical_form(ellipse_fitting(ij))) return ellipses_coefficients