def camera(**kwargs): """ Sets the camera settings. Parameters ---------- \**kwargs : dict, optional **{'camera_aspect', 'elevation', 'azimuth'}** Keywords arguments such as ``{'camera_aspect': unicode (Matplotlib axes aspect), 'elevation' : numeric, 'azimuth' : numeric}`` Returns ------- Axes Current axes. """ settings = Structure( **{'camera_aspect': 'equal', 'elevation': None, 'azimuth': None}) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.camera_aspect == 'equal': equal_axes3d(axes) axes.view_init(elev=settings.elevation, azim=settings.azimuth) return axes
def canvas(**kwargs): """ Sets the figure size. Parameters ---------- \**kwargs : dict, optional **{'figure_size', }** Keywords arguments such as ``{'figure_size': array_like (width, height), }`` Returns ------- Figure Current figure. """ settings = Structure( **{'figure_size': DEFAULT_FIGURE_SIZE}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if figure is None: figure = matplotlib.pyplot.figure(figsize=settings.figure_size) else: figure.set_size_inches(settings.figure_size) return figure
def canvas(**kwargs): """ Sets the figure size and aspect. Parameters ---------- \*\*kwargs : \*\* Keywords arguments. Returns ------- Figure Current figure. """ settings = Structure( **{'figure_size': DEFAULT_FIGURE_SIZE}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if figure is None: figure = matplotlib.pyplot.figure(figsize=settings.figure_size) else: figure.set_size_inches(settings.figure_size) return figure
def display(**kwargs): """ Sets the figure display. Parameters ---------- \**kwargs : dict, optional **{'standalone', 'filename'}** Keywords arguments such as ``{'standalone': bool (figure is shown), 'filename': unicode (figure is saved as `filename`)}`` Returns ------- bool Definition success. """ settings = Structure( **{'standalone': True, 'filename': None}) settings.update(kwargs) if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return True
def display(**kwargs): """ Sets the figure display. Parameters ---------- \**kwargs : dict, optional **{'standalone', 'filename'}** Keywords arguments such as ``{'standalone': bool (figure is shown), 'filename': unicode (figure is saved as `filename`)}`` Returns ------- Figure Current figure or None. """ settings = Structure( **{'standalone': True, 'filename': None}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return None else: return figure
def colour_cycle(**kwargs): """ Returns a colour cycle iterator using given colour map. Parameters ---------- \**kwargs : dict, optional **{'colour_cycle_map', 'colour_cycle_count'}** Keywords arguments such as ``{'colour_cycle_map': unicode (Matplotlib colormap name), 'colour_cycle_count': int}`` Returns ------- cycle Colour cycle iterator. """ settings = Structure( **{'colour_cycle_map': 'hsv', 'colour_cycle_count': len(DEFAULT_COLOUR_CYCLE)}) settings.update(kwargs) if settings.colour_cycle_map is None: cycle = DEFAULT_COLOUR_CYCLE else: cycle = getattr(matplotlib.pyplot.cm, settings.colour_cycle_map)( np.linspace(0, 1, settings.colour_cycle_count)) return itertools.cycle(cycle)
def test_Structure(self): """ Tests :class:`colour.utilities.data_structures.Structure` class. """ structure = Structure(John='Doe', Jane='Doe') self.assertIn('John', structure) self.assertTrue(hasattr(structure, 'John')) setattr(structure, 'John', 'Nemo') self.assertEqual(structure['John'], 'Nemo') structure['John'] = 'Vador' self.assertEqual(structure['John'], 'Vador') del structure['John'] self.assertNotIn('John', structure) self.assertFalse(hasattr(structure, 'John')) structure.John = 'Doe' self.assertIn('John', structure) self.assertTrue(hasattr(structure, 'John')) del structure.John self.assertNotIn('John', structure) self.assertFalse(hasattr(structure, 'John')) structure = Structure(John=None, Jane=None) self.assertIsNone(structure.John) self.assertIsNone(structure['John']) structure.update(**{'John': 'Doe', 'Jane': 'Doe'}) self.assertEqual(structure.John, 'Doe') self.assertEqual(structure['John'], 'Doe')
def eotf_BT2020( E_p: FloatingOrArrayLike, is_12_bits_system: Boolean = False, constants: Structure = CONSTANTS_BT2020, ) -> FloatingOrNDArray: """ Define *Recommendation ITU-R BT.2020* electro-optical transfer function (EOTF). Parameters ---------- E_p Non-linear signal :math:`E'`. is_12_bits_system *BT.709* *alpha* and *beta* constants are used if system is not 12-bit. constants *Recommendation ITU-R BT.2020* constants. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Resulting voltage :math:`E`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``E_p`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``E`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`InternationalTelecommunicationUnion2015h` Examples -------- >>> eotf_BT2020(0.705515089922121) # doctest: +ELLIPSIS 0.4999999... """ E_p = to_domain_1(E_p) a = constants.alpha(is_12_bits_system) b = constants.beta(is_12_bits_system) with domain_range_scale("ignore"): E = np.where( E_p < eotf_inverse_BT2020(b), E_p / 4.5, spow((E_p + (a - 1)) / a, 1 / 0.45), ) return as_float(from_range_1(E))
def display(**kwargs): """ Sets the figure display. Other Parameters ---------------- standalone : bool, optional Whether to show the figure. filename : unicode, optional Figure will be saved using given `filename` argument. Returns ------- Figure Current figure or None. """ settings = Structure(**{'standalone': True, 'filename': None}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return None else: return figure
def camera(**kwargs): """ Sets the camera settings. Other Parameters ---------------- azimuth : numeric, optional Camera azimuth. camera_aspect : unicode, optional Matplotlib axes aspect. Default is *equal*. elevation : numeric, optional Camera elevation. Returns ------- Axes Current axes. """ axes = kwargs.get('axes', plt.gca()) settings = Structure(**{ 'camera_aspect': 'equal', 'elevation': None, 'azimuth': None }) settings.update(kwargs) if settings.camera_aspect == 'equal': uniform_axes3d(axes) axes.view_init(elev=settings.elevation, azim=settings.azimuth) return axes
def display(**kwargs): """ Sets the figure display. Parameters ---------- \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. """ settings = Structure( **{'standalone': True, 'filename': None}) settings.update(kwargs) if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return True
def canvas(**kwargs): """ Sets the figure size. Other Parameters ---------------- figure_size : array_like, optional Array defining figure `width` and `height` such as `figure_size = (width, height)`. Returns ------- Figure Current figure. """ settings = Structure(**{'figure_size': DEFAULT_FIGURE_SIZE}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if figure is None: figure = matplotlib.pyplot.figure(figsize=settings.figure_size) else: figure.set_size_inches(settings.figure_size) return figure
def colour_cycle(**kwargs): """ Returns a colour cycle iterator using given colour map. Other Parameters ---------------- colour_cycle_map : unicode, optional Matplotlib colourmap name. colour_cycle_count : int, optional Colours count to pick in the colourmap. Returns ------- cycle Colour cycle iterator. """ settings = Structure(**{ 'colour_cycle_map': 'hsv', 'colour_cycle_count': len(DEFAULT_COLOUR_CYCLE) }) settings.update(kwargs) if settings.colour_cycle_map is None: cycle = DEFAULT_COLOUR_CYCLE else: cycle = getattr(matplotlib.pyplot.cm, settings.colour_cycle_map)(np.linspace( 0, 1, settings.colour_cycle_count)) return itertools.cycle(cycle)
def camera(**kwargs): """ Sets the camera settings. Parameters ---------- \**kwargs : dict, optional **{'camera_aspect', 'elevation', 'azimuth'}** Keywords arguments such as ``{'camera_aspect': unicode (Matplotlib axes aspect), 'elevation' : numeric, 'azimuth' : numeric}`` Returns ------- bool Definition success. """ settings = Structure(**{ 'camera_aspect': 'equal', 'elevation': None, 'azimuth': None }) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.camera_aspect == 'equal': equal_axes3d(axes) axes.view_init(elev=settings.elevation, azim=settings.azimuth) return True
def display(**kwargs): """ Sets the figure display. Parameters ---------- \**kwargs : dict, optional **{'standalone', 'filename'}** Keywords arguments such as ``{'standalone': bool (figure is shown), 'filename': unicode (figure is saved as `filename`)}`` Returns ------- bool Definition success. """ settings = Structure(**{'standalone': True, 'filename': None}) settings.update(kwargs) if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return True
def colour_cycle(**kwargs): """ Returns a colour cycle iterator using given colour map. Parameters ---------- \**kwargs : dict, optional **{'colour_cycle_map', 'colour_cycle_count'}** Keywords arguments such as ``{'colour_cycle_map': unicode (Matplotlib colormap name), 'colour_cycle_count': int}`` Returns ------- cycle Colour cycle iterator. """ settings = Structure(**{ 'colour_cycle_map': 'hsv', 'colour_cycle_count': len(DEFAULT_COLOUR_CYCLE) }) settings.update(kwargs) if settings.colour_cycle_map is None: cycle = DEFAULT_COLOUR_CYCLE else: cycle = getattr(matplotlib.pyplot.cm, settings.colour_cycle_map)(np.linspace( 0, 1, settings.colour_cycle_count)) return itertools.cycle(cycle)
def canvas(**kwargs): """ Sets the figure size. Parameters ---------- \**kwargs : dict, optional **{'figure_size', }** Keywords arguments such as ``{'figure_size': array_like (width, height), }`` Returns ------- Figure Current figure. """ settings = Structure(**{'figure_size': DEFAULT_FIGURE_SIZE}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if figure is None: figure = matplotlib.pyplot.figure(figsize=settings.figure_size) else: figure.set_size_inches(settings.figure_size) return figure
def display(**kwargs): """ Sets the figure display. Parameters ---------- \**kwargs : dict, optional **{'standalone', 'filename'}** Keywords arguments such as ``{'standalone': bool (figure is shown), 'filename': unicode (figure is saved as `filename`)}`` Returns ------- Figure Current figure or None. """ settings = Structure(**{'standalone': True, 'filename': None}) settings.update(kwargs) figure = matplotlib.pyplot.gcf() if settings.standalone: if settings.filename is not None: pylab.savefig(**kwargs) else: pylab.show() pylab.close() return None else: return figure
def colour_cycle(**kwargs): """ Returns a colour cycle iterator using given colour map. Other Parameters ---------------- colour_cycle_map : unicode or LinearSegmentedColormap, optional Matplotlib colourmap name. colour_cycle_count : int, optional Colours count to pick in the colourmap. Returns ------- cycle Colour cycle iterator. """ settings = Structure( **{ 'colour_cycle_map': COLOUR_STYLE_CONSTANTS.colour.map, 'colour_cycle_count': len(COLOUR_STYLE_CONSTANTS.colour.cycle) }) settings.update(kwargs) samples = np.linspace(0, 1, settings.colour_cycle_count) if isinstance(settings.colour_cycle_map, LinearSegmentedColormap): cycle = settings.colour_cycle_map(samples) else: cycle = getattr(plt.cm, settings.colour_cycle_map)(samples) return itertools.cycle(cycle)
def colour_cycle(**kwargs): """ Returns a colour cycle iterator using given colour map. Parameters ---------- \*\*kwargs : \*\* Keywords arguments. Returns ------- cycle Colour cycle iterator. """ settings = Structure( **{'colour_cycle_map': 'hsv', 'colour_cycle_count': len(DEFAULT_COLOUR_CYCLE)}) settings.update(kwargs) if settings.colour_cycle_map is None: cycle = DEFAULT_COLOUR_CYCLE else: cycle = getattr(matplotlib.pyplot.cm, settings.colour_cycle_map)( np.linspace(0, 1, settings.colour_cycle_count)) return itertools.cycle(cycle)
def camera(**kwargs: Union[KwargsCamera, Any]) -> Tuple[plt.Figure, plt.Axes]: """ Set the camera settings. Other Parameters ---------------- kwargs {:func:`colour.plotting.common.KwargsCamera`}, See the documentation of the previously listed class. Returns ------- :class:`tuple` Current figure and axes. """ figure = cast(plt.Figure, kwargs.get("figure", plt.gcf())) axes = cast(plt.Axes, kwargs.get("axes", plt.gca())) settings = Structure(**{ "camera_aspect": "equal", "elevation": None, "azimuth": None }) settings.update(kwargs) if settings.camera_aspect == "equal": uniform_axes3d(axes=axes) axes.view_init(elev=settings.elevation, azim=settings.azimuth) return figure, axes
def colour_cycle(**kwargs: Any) -> itertools.cycle: """ Return a colour cycle iterator using given colour map. Other Parameters ---------------- colour_cycle_map Matplotlib colourmap name. colour_cycle_count Colours count to pick in the colourmap. Returns ------- :class:`itertools.cycle` Colour cycle iterator. """ settings = Structure( **{ "colour_cycle_map": CONSTANTS_COLOUR_STYLE.colour.map, "colour_cycle_count": len(CONSTANTS_COLOUR_STYLE.colour.cycle), }) settings.update(kwargs) samples = np.linspace(0, 1, settings.colour_cycle_count) if isinstance(settings.colour_cycle_map, LinearSegmentedColormap): cycle = settings.colour_cycle_map(samples) else: cycle = getattr(plt.cm, settings.colour_cycle_map)(samples) return itertools.cycle(cycle)
def eotf_inverse_BT2020( E: FloatingOrArrayLike, is_12_bits_system: Boolean = False, constants: Structure = CONSTANTS_BT2020, ) -> FloatingOrNDArray: """ Define *Recommendation ITU-R BT.2020* inverse electro-optical transfer function (EOTF). Parameters ---------- E Voltage :math:`E` normalised by the reference white level and proportional to the implicit light intensity that would be detected with a reference camera colour channel R, G, B. is_12_bits_system *BT.709* *alpha* and *beta* constants are used if system is not 12-bit. constants *Recommendation ITU-R BT.2020* constants. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Resulting non-linear signal :math:`E'`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``E`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``E_p`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`InternationalTelecommunicationUnion2015h` Examples -------- >>> eotf_inverse_BT2020(0.18) # doctest: +ELLIPSIS 0.4090077... """ E = to_domain_1(E) a = constants.alpha(is_12_bits_system) b = constants.beta(is_12_bits_system) E_p = np.where(E < b, E * 4.5, a * spow(E, 0.45) - (a - 1)) return as_float(from_range_1(E_p))
def boundaries(**kwargs): """ Sets the plot boundaries. Other Parameters ---------------- bounding_box : array_like, optional Array defining current axes limits such `bounding_box = (x min, x max, y min, y max)`. x_tighten : bool, optional Whether to tighten the *X* axis limit. Default is `False`. y_tighten : bool, optional Whether to tighten the *Y* axis limit. Default is `False`. limits : array_like, optional Array defining current axes limits such as `limits = (x limit min, x limit max, y limit min, y limit max)`. `limits` argument values are added to the `margins` argument values to define the final bounding box for the current axes. margins : array_like, optional Array defining current axes margins such as `margins = (x margin min, x margin max, y margin min, y margin max)`. `margins` argument values are added to the `limits` argument values to define the final bounding box for the current axes. Returns ------- Axes Current axes. """ settings = Structure( **{ 'bounding_box': None, 'x_tighten': False, 'y_tighten': False, 'limits': (0, 1, 0, 1), 'margins': (0, 0, 0, 0) }) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.bounding_box is None: x_limit_min, x_limit_max, y_limit_min, y_limit_max = (settings.limits) x_margin_min, x_margin_max, y_margin_min, y_margin_max = ( settings.margins) if settings.x_tighten: pylab.xlim(x_limit_min + x_margin_min, x_limit_max + x_margin_max) if settings.y_tighten: pylab.ylim(y_limit_min + y_margin_min, y_limit_max + y_margin_max) else: pylab.xlim(settings.bounding_box[0], settings.bounding_box[1]) pylab.ylim(settings.bounding_box[2], settings.bounding_box[3]) return axes
def test_Structure(self): """Test :class:`colour.utilities.data_structures.Structure` class.""" structure = Structure(John="Doe", Jane="Doe") self.assertIn("John", structure) self.assertTrue(hasattr(structure, "John")) setattr(structure, "John", "Nemo") self.assertEqual(structure["John"], "Nemo") structure["John"] = "Vador" self.assertEqual(structure["John"], "Vador") del structure["John"] self.assertNotIn("John", structure) self.assertFalse(hasattr(structure, "John")) structure.John = "Doe" self.assertIn("John", structure) self.assertTrue(hasattr(structure, "John")) del structure.John self.assertNotIn("John", structure) self.assertFalse(hasattr(structure, "John")) structure = Structure(John=None, Jane=None) self.assertIsNone(structure.John) self.assertIsNone(structure["John"]) structure.update(**{"John": "Doe", "Jane": "Doe"}) self.assertEqual(structure.John, "Doe") self.assertEqual(structure["John"], "Doe")
def __init__(self, path=None, header=None, spectral_quantity=None, reflection_geometry=None, transmission_geometry=None, bandwidth_FWHM=None, bandwidth_corrected=None): super(IES_TM2714_Spd, self).__init__(name=None, data={}) self._mapping = Structure(**{ 'element': 'SpectralDistribution', 'elements': ( IES_TM2714_ElementSpecification( 'SpectralQuantity', 'spectral_quantity', required=True), IES_TM2714_ElementSpecification( 'ReflectionGeometry', 'reflection_geometry'), IES_TM2714_ElementSpecification( 'TransmissionGeometry', 'transmission_geometry'), IES_TM2714_ElementSpecification( 'BandwidthFWHM', 'bandwidth_FWHM', read_conversion=np.float_), IES_TM2714_ElementSpecification( 'BandwidthCorrected', 'bandwidth_corrected', read_conversion=( lambda x: True if x == 'true' else False), write_conversion=( lambda x: 'true' if x is True else 'False'))), 'data': IES_TM2714_ElementSpecification( 'SpectralData', 'wavelength', required=True)}) self._path = None self.path = path self._header = None self.header = header if header is not None else IES_TM2714_Header() self._spectral_quantity = None self.spectral_quantity = spectral_quantity self._reflection_geometry = None self.reflection_geometry = reflection_geometry self._transmission_geometry = None self.transmission_geometry = transmission_geometry self._bandwidth_FWHM = None self.bandwidth_FWHM = bandwidth_FWHM self._bandwidth_corrected = None self.bandwidth_corrected = bandwidth_corrected
def boundaries(**kwargs): """ Sets the plot boundaries. Parameters ---------- \**kwargs : dict, optional **{'bounding_box', 'x_tighten', 'y_tighten', 'limits', 'margins'}** Keywords arguments such as ``{'bounding_box': array_like (x min, x max, y min, y max), 'x_tighten': bool, 'y_tighten': bool, 'limits': array_like (x min, x max, y min, y max), 'limits': array_like (x min, x max, y min, y max)}`` Returns ------- Axes Current axes. """ settings = Structure( **{ 'bounding_box': None, 'x_tighten': False, 'y_tighten': False, 'limits': (0, 1, 0, 1), 'margins': (0, 0, 0, 0) }) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.bounding_box is None: x_limit_min, x_limit_max, y_limit_min, y_limit_max = (settings.limits) x_margin_min, x_margin_max, y_margin_min, y_margin_max = ( settings.margins) if settings.x_tighten: pylab.xlim(x_limit_min + x_margin_min, x_limit_max + x_margin_max) if settings.y_tighten: pylab.ylim(y_limit_min + y_margin_min, y_limit_max + y_margin_max) else: pylab.xlim(settings.bounding_box[0], settings.bounding_box[1]) pylab.ylim(settings.bounding_box[2], settings.bounding_box[3]) return axes
def boundaries(**kwargs): """ Sets the plot boundaries. Parameters ---------- \**kwargs : dict, optional **{'bounding_box', 'x_tighten', 'y_tighten', 'limits', 'margins'}** Keywords arguments such as ``{'bounding_box': array_like (x min, x max, y min, y max), 'x_tighten': bool, 'y_tighten': bool, 'limits': array_like (x min, x max, y min, y max), 'limits': array_like (x min, x max, y min, y max)}`` Returns ------- Axes Current axes. """ settings = Structure( **{'bounding_box': None, 'x_tighten': False, 'y_tighten': False, 'limits': (0, 1, 0, 1), 'margins': (0, 0, 0, 0)}) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.bounding_box is None: x_limit_min, x_limit_max, y_limit_min, y_limit_max = ( settings.limits) x_margin_min, x_margin_max, y_margin_min, y_margin_max = ( settings.margins) if settings.x_tighten: pylab.xlim(x_limit_min + x_margin_min, x_limit_max + x_margin_max) if settings.y_tighten: pylab.ylim(y_limit_min + y_margin_min, y_limit_max + y_margin_max) else: pylab.xlim(settings.bounding_box[0], settings.bounding_box[1]) pylab.ylim(settings.bounding_box[2], settings.bounding_box[3]) return axes
def __init__(self, path=None, header=None, spectral_quantity=None, reflection_geometry=None, transmission_geometry=None, bandwidth_FWHM=None, bandwidth_corrected=None, **kwargs): super(SpectralDistribution_IESTM2714, self).__init__(**kwargs) self._mapping = Structure( **{ 'element': 'SpectralDistribution', 'elements': (Element_Specification_IESTM2714( 'SpectralQuantity', 'spectral_quantity', required=True), Element_Specification_IESTM2714('ReflectionGeometry', 'reflection_geometry'), Element_Specification_IESTM2714('TransmissionGeometry', 'transmission_geometry'), Element_Specification_IESTM2714( 'BandwidthFWHM', 'bandwidth_FWHM', read_conversion=DEFAULT_FLOAT_DTYPE), Element_Specification_IESTM2714( 'BandwidthCorrected', 'bandwidth_corrected', read_conversion=( lambda x: True if x == 'true' else False), write_conversion=( lambda x: 'true' if x is True else 'False'))), 'data': Element_Specification_IESTM2714( 'SpectralData', 'wavelength', required=True) }) self._path = None self.path = path self._header = None self.header = header if header is not None else Header_IESTM2714() self._spectral_quantity = None self.spectral_quantity = spectral_quantity self._reflection_geometry = None self.reflection_geometry = reflection_geometry self._transmission_geometry = None self.transmission_geometry = transmission_geometry self._bandwidth_FWHM = None self.bandwidth_FWHM = bandwidth_FWHM self._bandwidth_corrected = None self.bandwidth_corrected = bandwidth_corrected
def camera(**kwargs): """ Sets the camera settings. Other Parameters ---------------- figure : Figure, optional Figure to apply the render elements onto. axes : Axes, optional Axes to apply the render elements onto. azimuth : numeric, optional Camera azimuth. camera_aspect : unicode, optional Matplotlib axes aspect. Default is *equal*. elevation : numeric, optional Camera elevation. Returns ------- tuple Current figure and axes. """ figure = kwargs.get('figure', plt.gcf()) axes = kwargs.get('axes', plt.gca()) settings = Structure(**{ 'camera_aspect': 'equal', 'elevation': None, 'azimuth': None }) settings.update(kwargs) if settings.camera_aspect == 'equal': uniform_axes3d(axes=axes) axes.view_init(elev=settings.elevation, azim=settings.azimuth) return figure, axes
def boundaries(**kwargs): """ Sets the plot boundaries. Parameters ---------- \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. """ settings = Structure( **{'bounding_box': None, 'x_tighten': False, 'y_tighten': False, 'limits': [0, 1, 0, 1], 'margins': [0, 0, 0, 0]}) settings.update(kwargs) if settings.bounding_box is None: x_limit_min, x_limit_max, y_limit_min, y_limit_max = ( settings.limits) x_margin_min, x_margin_max, y_margin_min, y_margin_max = ( settings.margins) if settings.x_tighten: pylab.xlim(x_limit_min + x_margin_min, x_limit_max + x_margin_max) if settings.y_tighten: pylab.ylim(y_limit_min + y_margin_min, y_limit_max + y_margin_max) else: pylab.xlim(settings.bounding_box[0], settings.bounding_box[1]) pylab.ylim(settings.bounding_box[2], settings.bounding_box[3]) return True
def test_Structure_pickle(self): """ Tests :class:`colour.utilities.data_structures.Structure` class pickling. """ structure = Structure(John='Doe', Jane='Doe') data = pickle.dumps(structure) data = pickle.loads(data) self.assertEqual(structure, data) data = pickle.dumps(structure, pickle.HIGHEST_PROTOCOL) data = pickle.loads(data) self.assertEqual(structure, data)
def test_Structure_pickle(self): """ Test :class:`colour.utilities.data_structures.Structure` class pickling. """ structure = Structure(John="Doe", Jane="Doe") data = pickle.dumps(structure) data = pickle.loads(data) self.assertEqual(structure, data) data = pickle.dumps(structure, pickle.HIGHEST_PROTOCOL) data = pickle.loads(data) self.assertEqual(structure, data) self.assertEqual(sorted(dir(data)), ["Jane", "John"])
from colour.algebra import spow from colour.utilities import Structure, from_range_1, to_domain_1 __author__ = 'Colour Developers' __copyright__ = 'Copyright (C) 2013-2019 - Colour Developers' __license__ = 'New BSD License - https://opensource.org/licenses/BSD-3-Clause' __maintainer__ = 'Colour Developers' __email__ = '*****@*****.**' __status__ = 'Production' __all__ = ['ST2084_CONSTANTS', 'oetf_ST2084', 'eotf_ST2084'] ST2084_CONSTANTS = Structure(m_1=2610 / 4096 * (1 / 4), m_2=2523 / 4096 * 128, c_1=3424 / 4096, c_2=2413 / 4096 * 32, c_3=2392 / 4096 * 32) """ Constants for *SMPTE ST 2084:2014* opto-electrical transfer function (OETF / OECF) and electro-optical transfer function (EOTF / EOCF). ST2084_CONSTANTS : Structure """ def oetf_ST2084(C, L_p=10000, constants=ST2084_CONSTANTS): """ Defines *SMPTE ST 2084:2014* optimised perceptual opto-electronic transfer function (OETF / OECF).
def nadir_grid( limits: Optional[ArrayLike] = None, segments: Integer = 10, labels: Optional[Sequence[str]] = None, axes: Optional[plt.Axes] = None, **kwargs: Any, ) -> Tuple[NDArray, NDArray, NDArray]: """ Return a grid on *CIE xy* plane made of quad geometric elements and its associated faces and edges colours. Ticks and labels are added to the given axes according to the extended grid settings. Parameters ---------- limits Extended grid limits. segments Edge segments count for the extended grid. labels Axis labels. axes Axes to add the grid. Other Parameters ---------------- grid_edge_alpha Grid edge opacity value such as `grid_edge_alpha = 0.5`. grid_edge_colours Grid edge colours array such as `grid_edge_colours = (0.25, 0.25, 0.25)`. grid_face_alpha Grid face opacity value such as `grid_face_alpha = 0.1`. grid_face_colours Grid face colours array such as `grid_face_colours = (0.25, 0.25, 0.25)`. ticks_and_label_location Location of the *X* and *Y* axis ticks and labels such as `ticks_and_label_location = ('-x', '-y')`. x_axis_colour *X* axis colour array such as `x_axis_colour = (0.0, 0.0, 0.0, 1.0)`. x_label_colour *X* axis label colour array such as `x_label_colour = (0.0, 0.0, 0.0, 0.85)`. x_ticks_colour *X* axis ticks colour array such as `x_ticks_colour = (0.0, 0.0, 0.0, 0.85)`. y_axis_colour *Y* axis colour array such as `y_axis_colour = (0.0, 0.0, 0.0, 1.0)`. y_label_colour *Y* axis label colour array such as `y_label_colour = (0.0, 0.0, 0.0, 0.85)`. y_ticks_colour *Y* axis ticks colour array such as `y_ticks_colour = (0.0, 0.0, 0.0, 0.85)`. Returns ------- :class:`tuple` Grid quads, faces colours, edges colours. Examples -------- >>> nadir_grid(segments=1) (array([[[-1. , -1. , 0. ], [ 1. , -1. , 0. ], [ 1. , 1. , 0. ], [-1. , 1. , 0. ]], <BLANKLINE> [[-1. , -1. , 0. ], [ 0. , -1. , 0. ], [ 0. , 0. , 0. ], [-1. , 0. , 0. ]], <BLANKLINE> [[-1. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 1. , 0. ], [-1. , 1. , 0. ]], <BLANKLINE> [[ 0. , -1. , 0. ], [ 1. , -1. , 0. ], [ 1. , 0. , 0. ], [ 0. , 0. , 0. ]], <BLANKLINE> [[ 0. , 0. , 0. ], [ 1. , 0. , 0. ], [ 1. , 1. , 0. ], [ 0. , 1. , 0. ]], <BLANKLINE> [[-1. , -0.001, 0. ], [ 1. , -0.001, 0. ], [ 1. , 0.001, 0. ], [-1. , 0.001, 0. ]], <BLANKLINE> [[-0.001, -1. , 0. ], [ 0.001, -1. , 0. ], [ 0.001, 1. , 0. ], [-0.001, 1. , 0. ]]]), array([[ 0.25, 0.25, 0.25, 0.1 ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , 1. ]]), array([[ 0.5 , 0.5 , 0.5 , 0.5 ], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , 1. ]])) """ limits = as_float_array( cast(ArrayLike, optional(limits, np.array([[-1, 1], [-1, 1]])))) labels = cast(Sequence, optional(labels, ("x", "y"))) extent = np.max(np.abs(limits[..., 1] - limits[..., 0])) settings = Structure( **{ "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"), }) settings.update(**kwargs) # Outer grid. quads_g = primitive_vertices_grid_mpl( origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments, width_segments=segments, ) RGB_g = ones((quads_g.shape[0], quads_g.shape[-1])) RGB_gf = RGB_g * settings.grid_face_colours RGB_gf = np.hstack( [RGB_gf, full((RGB_gf.shape[0], 1), settings.grid_face_alpha)]) RGB_ge = RGB_g * settings.grid_edge_colours RGB_ge = np.hstack( [RGB_ge, full((RGB_ge.shape[0], 1), settings.grid_edge_alpha)]) # Inner grid. quads_gs = primitive_vertices_grid_mpl( origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments * 2, width_segments=segments * 2, ) RGB_gs = ones((quads_gs.shape[0], quads_gs.shape[-1])) RGB_gsf = RGB_gs * 0 RGB_gsf = np.hstack([RGB_gsf, full((RGB_gsf.shape[0], 1), 0)]) RGB_gse = np.clip(RGB_gs * settings.grid_edge_colours * 1.5, 0, 1) RGB_gse = np.hstack( (RGB_gse, full((RGB_gse.shape[0], 1), settings.grid_edge_alpha / 2))) # Axis. thickness = extent / 1000 quad_x = primitive_vertices_grid_mpl(origin=(limits[0, 0], -thickness / 2), width=extent, height=thickness) RGB_x = ones((quad_x.shape[0], quad_x.shape[-1] + 1)) RGB_x = RGB_x * settings.x_axis_colour quad_y = primitive_vertices_grid_mpl(origin=(-thickness / 2, limits[1, 0]), width=thickness, height=extent) RGB_y = ones((quad_y.shape[0], quad_y.shape[-1] + 1)) RGB_y = RGB_y * settings.y_axis_colour if axes is not None: # Ticks. x_s = 1 if "+x" in settings.ticks_and_label_location else -1 y_s = 1 if "+y" in settings.ticks_and_label_location else -1 for i, axis in enumerate("xy"): h_a = "center" if axis == "x" else "left" if x_s == 1 else "right" v_a = "center" ticks = list(sorted(set(quads_g[..., 0, i]))) ticks += [ticks[-1] + ticks[-1] - ticks[-2]] for tick in ticks: x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 25) if i else tick) y = (tick if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 25)) tick = as_int_scalar(tick) if is_integer(tick) else tick c = settings[f"{axis}_ticks_colour"] axes.text( x, y, 0, tick, "x", horizontalalignment=h_a, verticalalignment=v_a, color=c, clip_on=True, ) # Labels. for i, axis in enumerate("xy"): h_a = "center" if axis == "x" else "left" if x_s == 1 else "right" v_a = "center" x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 10) if i else 0) y = (0 if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 10)) c = settings[f"{axis}_label_colour"] axes.text( x, y, 0, labels[i], "x", horizontalalignment=h_a, verticalalignment=v_a, color=c, size=20, clip_on=True, ) quads = np.vstack([quads_g, quads_gs, quad_x, quad_y]) RGB_f = np.vstack([RGB_gf, RGB_gsf, RGB_x, RGB_y]) RGB_e = np.vstack([RGB_ge, RGB_gse, RGB_x, RGB_y]) return quads, RGB_f, RGB_e
from colour.utilities import (Structure, as_float, domain_range_scale, from_range_1, to_domain_1) __author__ = 'Colour Developers' __copyright__ = 'Copyright (C) 2013-2019 - Colour Developers' __license__ = 'New BSD License - https://opensource.org/licenses/BSD-3-Clause' __maintainer__ = 'Colour Developers' __email__ = '*****@*****.**' __status__ = 'Production' __all__ = [ 'ARIBSTDB67_CONSTANTS', 'oetf_ARIBSTDB67', 'oetf_reverse_ARIBSTDB67' ] ARIBSTDB67_CONSTANTS = Structure(a=0.17883277, b=0.28466892, c=0.55991073) """ *ARIB STD-B67 (Hybrid Log-Gamma)* constants. ARIBSTDB67_CONSTANTS : Structure """ def oetf_ARIBSTDB67(E, r=0.5, constants=ARIBSTDB67_CONSTANTS): """ Defines *ARIB STD-B67 (Hybrid Log-Gamma)* opto-electrical transfer function (OETF / OECF). Parameters ---------- E : numeric or array_like
def render(**kwargs): """ Renders the current figure while adjusting various settings such as the bounding box, the title or background transparency. Other Parameters ---------------- figure : Figure, optional Figure to apply the render elements onto. axes : Axes, optional Axes to apply the render elements onto. filename : unicode, optional Figure will be saved using given ``filename`` argument. standalone : bool, optional Whether to show the figure and call :func:`plt.show` definition. aspect : unicode, optional Matplotlib axes aspect. axes_visible : bool, optional Whether the axes are visible. Default is *True*. bounding_box : array_like, optional Array defining current axes limits such `bounding_box = (x min, x max, y min, y max)`. tight_layout : bool, optional Whether to invoke the :func:`plt.tight_layout` definition. legend : bool, optional Whether to display the legend. Default is *False*. legend_columns : int, optional Number of columns in the legend. Default is *1*. transparent_background : bool, optional Whether to turn off the background patch. Default is *False*. title : unicode, optional Figure title. wrap_title : unicode, optional Whether to wrap the figure title, the default is to wrap at a number of characters equal to the width of the figure multiplied by 10. x_label : unicode, optional *X* axis label. y_label : unicode, optional *Y* axis label. x_ticker : bool, optional Whether to display the *X* axis ticker. Default is *True*. y_ticker : bool, optional Whether to display the *Y* axis ticker. Default is *True*. Returns ------- tuple Current figure and axes. """ figure = kwargs.get('figure') if figure is None: figure = plt.gcf() axes = kwargs.get('axes') if axes is None: axes = plt.gca() settings = Structure( **{ 'filename': None, 'standalone': True, 'aspect': None, 'axes_visible': True, 'bounding_box': None, 'tight_layout': True, 'legend': False, 'legend_columns': 1, 'transparent_background': True, 'title': None, 'wrap_title': True, 'x_label': None, 'y_label': None, 'x_ticker': True, 'y_ticker': True, }) settings.update(kwargs) if settings.aspect: axes.set_aspect(settings.aspect) if not settings.axes_visible: axes.set_axis_off() if settings.bounding_box: axes.set_xlim(settings.bounding_box[0], settings.bounding_box[1]) axes.set_ylim(settings.bounding_box[2], settings.bounding_box[3]) if settings.title: title = settings.title if settings.wrap_title: title = wrap_label(settings.title, int(plt.rcParams['figure.figsize'][0] * 10)) axes.set_title(title) if settings.x_label: axes.set_xlabel(settings.x_label) if settings.y_label: axes.set_ylabel(settings.y_label) if not settings.x_ticker: axes.set_xticks([]) if not settings.y_ticker: axes.set_yticks([]) if settings.legend: axes.legend(ncol=settings.legend_columns) if settings.tight_layout: figure.tight_layout() if settings.transparent_background: figure.patch.set_alpha(0) if settings.standalone: if settings.filename is not None: figure.savefig(settings.filename) else: plt.show() return figure, axes
__author__ = 'Colour Developers' __copyright__ = 'Copyright (C) 2013-2019 - Colour Developers' __license__ = 'New BSD License - http://opensource.org/licenses/BSD-3-Clause' __maintainer__ = 'Colour Developers' __email__ = '*****@*****.**' __status__ = 'Production' __all__ = [ 'JZAZBZ_CONSTANTS', 'JZAZBZ_XYZ_TO_LMS_MATRIX', 'JZAZBZ_LMS_TO_XYZ_MATRIX', 'JZAZBZ_LMS_P_TO_IZAZBZ_MATRIX', 'JZAZBZ_IZAZBZ_TO_LMS_P_MATRIX', 'XYZ_to_JzAzBz', 'JzAzBz_to_XYZ' ] JZAZBZ_CONSTANTS = Structure(b=1.15, g=0.66, d=-0.56, d_0=1.6295499532821566 * 10**-11) JZAZBZ_CONSTANTS.update(ST2084_CONSTANTS) JZAZBZ_CONSTANTS.m_2 = 1.7 * 2523 / 2**5 """ Constants for :math:`J_zA_zB_z` colourspace and its variant of the perceptual quantizer (PQ) from Dolby Laboratories. Notes ----- - The :math:`m2` constant, i.e. the power factor has been re-optimized during the development of the :math:`J_zA_zB_z` colourspace. JZAZBZ_CONSTANTS : Structure """
def nadir_grid(limits=None, segments=10, labels=None, axes=None, **kwargs): """ Returns a grid on *xy* plane made of quad geometric elements and its associated faces and edges colours. Ticks and labels are added to the given axes accordingly to the extended grid settings. Parameters ---------- limits : array_like, optional Extended grid limits. segments : int, optional Edge segments count for the extended grid. labels : array_like, optional Axis labels. axes : matplotlib.axes.Axes, optional Axes to add the grid. \**kwargs : dict, optional **{'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 ------- tuple Grid quads, faces colours, edges colours. Examples -------- >>> c = 'Rec. 709' >>> RGB_scatter_plot(c) # doctest: +SKIP True """ if limits is None: limits = np.array([[-1, 1], [-1, 1]]) if labels is None: labels = ('x', 'y') extent = np.max(np.abs(limits[..., 1] - limits[..., 0])) settings = Structure( **{'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')}) settings.update(**kwargs) # Outer grid. quads_g = grid(origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments, width_segments=segments) RGB_g = np.ones((quads_g.shape[0], quads_g.shape[-1])) RGB_gf = RGB_g * settings.grid_face_colours RGB_gf = np.hstack((RGB_gf, np.full((RGB_gf.shape[0], 1), settings.grid_face_alpha, np.float_))) RGB_ge = RGB_g * settings.grid_edge_colours RGB_ge = np.hstack((RGB_ge, np.full((RGB_ge.shape[0], 1), settings.grid_edge_alpha, np.float_))) # Inner grid. quads_gs = grid(origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments * 2, width_segments=segments * 2) RGB_gs = np.ones((quads_gs.shape[0], quads_gs.shape[-1])) RGB_gsf = RGB_gs * 0 RGB_gsf = np.hstack((RGB_gsf, np.full((RGB_gsf.shape[0], 1, np.float_), 0))) RGB_gse = np.clip(RGB_gs * settings.grid_edge_colours * 1.5, 0, 1) RGB_gse = np.hstack((RGB_gse, np.full((RGB_gse.shape[0], 1), settings.grid_edge_alpha / 2, np.float_))) # Axis. thickness = extent / 1000 quad_x = grid(origin=(limits[0, 0], -thickness / 2), width=extent, height=thickness) RGB_x = np.ones((quad_x.shape[0], quad_x.shape[-1] + 1)) RGB_x = RGB_x * settings.x_axis_colour quad_y = grid(origin=(-thickness / 2, limits[1, 0]), width=thickness, height=extent) RGB_y = np.ones((quad_y.shape[0], quad_y.shape[-1] + 1)) RGB_y = RGB_y * settings.y_axis_colour # Ticks. x_s = 1 if '+x' in settings.ticks_and_label_location else -1 y_s = 1 if '+y' in settings.ticks_and_label_location else -1 for i, axis in enumerate('xy'): h_a = 'center' if axis == 'x' else 'left' if x_s == 1 else 'right' v_a = 'center' ticks = list(sorted(set(quads_g[..., 0, i]))) ticks += [ticks[-1] + ticks[-1] - ticks[-2]] for tick in ticks: x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 25) if i else tick) y = (tick if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 25)) tick = int(tick) if float(tick).is_integer() else tick c = settings['{0}_ticks_colour'.format(axis)] axes.text(x, y, 0, tick, 'x', horizontalalignment=h_a, verticalalignment=v_a, color=c, clip_on=True) # Labels. for i, axis in enumerate('xy'): h_a = 'center' if axis == 'x' else 'left' if x_s == 1 else 'right' v_a = 'center' x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 10) if i else 0) y = (0 if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 10)) c = settings['{0}_label_colour'.format(axis)] axes.text(x, y, 0, labels[i], 'x', horizontalalignment=h_a, verticalalignment=v_a, color=c, size=20, clip_on=True) quads = np.vstack((quads_g, quads_gs, quad_x, quad_y)) RGB_f = np.vstack((RGB_gf, RGB_gsf, RGB_x, RGB_y)) RGB_e = np.vstack((RGB_ge, RGB_gse, RGB_x, RGB_y)) return quads, RGB_f, RGB_e
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_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)
def plot_RGB_colourspaces_gamuts(colourspaces=None, reference_colourspace='CIE xyY', segments=8, show_grid=True, grid_segments=10, show_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 xy', 'CIE Lab', 'CIE LCHab', 'CIE Luv', 'CIE Luv uv', 'CIE LCHuv', 'CIE UCS', 'CIE UCS uv', 'CIE UVW', 'DIN 99', 'Hunter Lab', 'Hunter Rdab', 'IPT', 'JzAzBz', 'OSA UCS', 'hdr-CIELAB', 'hdr-IPT'}**, Reference colourspace to plot the gamuts into. segments : int, optional Edge segments count for each *RGB* colourspace cubes. show_grid : bool, optional Whether to show a grid at the bottom of the *RGB* colourspace cubes. grid_segments : bool, optional Edge segments count for the grid. show_spectral_locus : bool, optional Whether to show the spectral locus. spectral_locus_colour : array_like, optional Spectral locus colour. cmfs : unicode, optional Standard observer colour matching functions used for spectral locus. Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.volume.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 ------- tuple Current figure and axes. Examples -------- >>> plot_RGB_colourspaces_gamuts(['ITU-R BT.709', 'ACEScg', 'S-Gamut']) ... # doctest: +SKIP .. image:: ../_static/Plotting_Plot_RGB_Colourspaces_Gamuts.png :align: center :alt: plot_RGB_colourspaces_gamuts """ if colourspaces is None: colourspaces = ('ITU-R BT.709', 'ACEScg') colourspaces = filter_RGB_colourspaces(colourspaces).values() count_c = len(colourspaces) title = '{0} - {1} Reference Colourspace'.format( ', '.join([colourspace.name for colourspace in colourspaces]), reference_colourspace, ) settings = Structure( **{ 'face_colours': [None] * count_c, 'edge_colours': [None] * count_c, 'face_alpha': [1] * count_c, 'edge_alpha': [1] * count_c, 'title': title, }) settings.update(kwargs) figure = plt.figure() axes = figure.add_subplot(111, projection='3d') illuminant = COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint points = np.zeros((4, 3)) if show_spectral_locus: cmfs = first_item(filter_cmfs(cmfs).values()) 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) axes.plot( points[..., 0], points[..., 1], points[..., 2], color=c, zorder=1) axes.plot( (points[-1][0], points[0][0]), (points[-1][1], points[0][1]), (points[-1][2], points[0][2]), color=c, zorder=1) quads, RGB_f, RGB_e = [], [], [] for i, colourspace in enumerate(colourspaces): 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], DEFAULT_FLOAT_DTYPE) ])) 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], DEFAULT_FLOAT_DTYPE) ])) quads = as_float_array(quads) quads[np.isnan(quads)] = 0 if quads.size != 0: for i, axis in enumerate('xyz'): min_a = min(np.min(quads[..., i]), np.min(points[..., i])) max_a = max(np.max(quads[..., i]), np.max(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 show_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({ 'axes': axes, 'axes_visible': False, 'camera_aspect': 'equal' }) settings.update(kwargs) return render(**settings)
def nadir_grid(limits=None, segments=10, labels=None, axes=None, **kwargs): """ Returns a grid on *xy* plane made of quad geometric elements and its associated faces and edges colours. Ticks and labels are added to the given axes according to the extended grid settings. Parameters ---------- limits : array_like, optional Extended grid limits. segments : int, optional Edge segments count for the extended grid. labels : array_like, optional Axis labels. axes : matplotlib.axes.Axes, optional Axes to add the grid. Other Parameters ---------------- grid_face_colours : array_like, optional Grid face colours array such as `grid_face_colours = (0.25, 0.25, 0.25)`. grid_edge_colours : array_like, optional Grid edge colours array such as `grid_edge_colours = (0.25, 0.25, 0.25)`. grid_face_alpha : numeric, optional Grid face opacity value such as `grid_face_alpha = 0.1`. grid_edge_alpha : numeric, optional Grid edge opacity value such as `grid_edge_alpha = 0.5`. x_axis_colour : array_like, optional *X* axis colour array such as `x_axis_colour = (0.0, 0.0, 0.0, 1.0)`. y_axis_colour : array_like, optional *Y* axis colour array such as `y_axis_colour = (0.0, 0.0, 0.0, 1.0)`. x_ticks_colour : array_like, optional *X* axis ticks colour array such as `x_ticks_colour = (0.0, 0.0, 0.0, 0.85)`. y_ticks_colour : array_like, optional *Y* axis ticks colour array such as `y_ticks_colour = (0.0, 0.0, 0.0, 0.85)`. x_label_colour : array_like, optional *X* axis label colour array such as `x_label_colour = (0.0, 0.0, 0.0, 0.85)`. y_label_colour : array_like, optional *Y* axis label colour array such as `y_label_colour = (0.0, 0.0, 0.0, 0.85)`. ticks_and_label_location : array_like, optional Location of the *X* and *Y* axis ticks and labels such as `ticks_and_label_location = ('-x', '-y')`. Returns ------- tuple Grid quads, faces colours, edges colours. Examples -------- >>> nadir_grid(segments=1) (array([[[-1. , -1. , 0. ], [ 1. , -1. , 0. ], [ 1. , 1. , 0. ], [-1. , 1. , 0. ]], <BLANKLINE> [[-1. , -1. , 0. ], [ 0. , -1. , 0. ], [ 0. , 0. , 0. ], [-1. , 0. , 0. ]], <BLANKLINE> [[-1. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 1. , 0. ], [-1. , 1. , 0. ]], <BLANKLINE> [[ 0. , -1. , 0. ], [ 1. , -1. , 0. ], [ 1. , 0. , 0. ], [ 0. , 0. , 0. ]], <BLANKLINE> [[ 0. , 0. , 0. ], [ 1. , 0. , 0. ], [ 1. , 1. , 0. ], [ 0. , 1. , 0. ]], <BLANKLINE> [[-1. , -0.001, 0. ], [ 1. , -0.001, 0. ], [ 1. , 0.001, 0. ], [-1. , 0.001, 0. ]], <BLANKLINE> [[-0.001, -1. , 0. ], [ 0.001, -1. , 0. ], [ 0.001, 1. , 0. ], [-0.001, 1. , 0. ]]]), array([[ 0.25, 0.25, 0.25, 0.1 ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , 1. ]]), array([[ 0.5 , 0.5 , 0.5 , 0.5 ], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0.75, 0.75, 0.75, 0.25], [ 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , 1. ]])) """ if limits is None: limits = np.array([[-1, 1], [-1, 1]]) if labels is None: labels = ('x', 'y') extent = np.max(np.abs(limits[..., 1] - limits[..., 0])) settings = Structure( **{ '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') }) settings.update(**kwargs) # Outer grid. quads_g = grid( origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments, width_segments=segments) RGB_g = np.ones((quads_g.shape[0], quads_g.shape[-1])) RGB_gf = RGB_g * settings.grid_face_colours RGB_gf = np.hstack([ RGB_gf, np.full((RGB_gf.shape[0], 1), settings.grid_face_alpha, DEFAULT_FLOAT_DTYPE) ]) RGB_ge = RGB_g * settings.grid_edge_colours RGB_ge = np.hstack([ RGB_ge, np.full((RGB_ge.shape[0], 1), settings.grid_edge_alpha, DEFAULT_FLOAT_DTYPE) ]) # Inner grid. quads_gs = grid( origin=(-extent / 2, -extent / 2), width=extent, height=extent, height_segments=segments * 2, width_segments=segments * 2) RGB_gs = np.ones((quads_gs.shape[0], quads_gs.shape[-1])) RGB_gsf = RGB_gs * 0 RGB_gsf = np.hstack( [RGB_gsf, np.full((RGB_gsf.shape[0], 1), 0, DEFAULT_FLOAT_DTYPE)]) RGB_gse = np.clip(RGB_gs * settings.grid_edge_colours * 1.5, 0, 1) RGB_gse = np.hstack( (RGB_gse, np.full((RGB_gse.shape[0], 1), settings.grid_edge_alpha / 2, DEFAULT_FLOAT_DTYPE))) # Axis. thickness = extent / 1000 quad_x = grid( origin=(limits[0, 0], -thickness / 2), width=extent, height=thickness) RGB_x = np.ones((quad_x.shape[0], quad_x.shape[-1] + 1)) RGB_x = RGB_x * settings.x_axis_colour quad_y = grid( origin=(-thickness / 2, limits[1, 0]), width=thickness, height=extent) RGB_y = np.ones((quad_y.shape[0], quad_y.shape[-1] + 1)) RGB_y = RGB_y * settings.y_axis_colour if axes is not None: # Ticks. x_s = 1 if '+x' in settings.ticks_and_label_location else -1 y_s = 1 if '+y' in settings.ticks_and_label_location else -1 for i, axis in enumerate('xy'): h_a = 'center' if axis == 'x' else 'left' if x_s == 1 else 'right' v_a = 'center' ticks = list(sorted(set(quads_g[..., 0, i]))) ticks += [ticks[-1] + ticks[-1] - ticks[-2]] for tick in ticks: x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 25) if i else tick) y = (tick if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 25)) tick = DEFAULT_INT_DTYPE(tick) if DEFAULT_FLOAT_DTYPE( tick).is_integer() else tick c = settings['{0}_ticks_colour'.format(axis)] axes.text( x, y, 0, tick, 'x', horizontalalignment=h_a, verticalalignment=v_a, color=c, clip_on=True) # Labels. for i, axis in enumerate('xy'): h_a = 'center' if axis == 'x' else 'left' if x_s == 1 else 'right' v_a = 'center' x = (limits[1, 1 if x_s == 1 else 0] + (x_s * extent / 10) if i else 0) y = (0 if i else limits[0, 1 if y_s == 1 else 0] + (y_s * extent / 10)) c = settings['{0}_label_colour'.format(axis)] axes.text( x, y, 0, labels[i], 'x', horizontalalignment=h_a, verticalalignment=v_a, color=c, size=20, clip_on=True) quads = np.vstack([quads_g, quads_gs, quad_x, quad_y]) RGB_f = np.vstack([RGB_gf, RGB_gsf, RGB_x, RGB_y]) RGB_e = np.vstack([RGB_ge, RGB_gse, RGB_x, RGB_y]) return quads, RGB_f, RGB_e
def decorate(**kwargs): """ Sets the figure decorations. Parameters ---------- \**kwargs : dict, optional **{'title', 'x_label', 'y_label', 'legend', 'legend_columns', 'legend_location', 'x_ticker', 'y_ticker', 'x_ticker_locator', 'y_ticker_locator', 'grid', 'grid_which', 'grid_axis', 'x_axis_line', 'y_axis_line', 'aspect', 'no_axes'}** Keywords arguments such as ``{'title': unicode (figure title), 'x_label': unicode (X axis label), 'y_label': unicode (Y axis label), 'legend': bool, 'legend_columns': int, 'legend_location': unicode (Matplotlib legend location), 'x_ticker': bool, 'y_ticker': bool, 'x_ticker_locator': Locator, 'y_ticker_locator': Locator, 'grid': bool, 'grid_which': unicode, 'grid_axis': unicode, 'x_axis_line': bool, 'y_axis_line': bool, 'aspect': unicode (Matplotlib axes aspect), 'no_axes': bool}`` Returns ------- Axes Current axes. """ settings = Structure( **{'title': None, 'x_label': None, 'y_label': None, 'legend': False, 'legend_columns': 1, 'legend_location': 'upper right', 'x_ticker': True, 'y_ticker': True, 'x_ticker_locator': matplotlib.ticker.AutoMinorLocator(2), 'y_ticker_locator': matplotlib.ticker.AutoMinorLocator(2), 'grid': False, 'grid_which': 'both', 'grid_axis': 'both', 'x_axis_line': False, 'y_axis_line': False, 'aspect': None, 'no_axes': False}) settings.update(kwargs) axes = matplotlib.pyplot.gca() if settings.title: pylab.title(settings.title) if settings.x_label: pylab.xlabel(settings.x_label) if settings.y_label: pylab.ylabel(settings.y_label) if settings.legend: pylab.legend(loc=settings.legend_location, ncol=settings.legend_columns) if settings.x_ticker: axes.xaxis.set_minor_locator( settings.x_ticker_locator) else: axes.set_xticks([]) if settings.y_ticker: axes.yaxis.set_minor_locator( settings.y_ticker_locator) else: axes.set_yticks([]) if settings.grid: pylab.grid(which=settings.grid_which, axis=settings.grid_axis) if settings.x_axis_line: pylab.axvline(color='black', linestyle='--') if settings.y_axis_line: pylab.axhline(color='black', linestyle='--') if settings.aspect: matplotlib.pyplot.axes().set_aspect(settings.aspect) if settings.no_axes: axes.set_axis_off() return axes
def plot_RGB_scatter(RGB, colourspace, reference_colourspace='CIE xyY', colourspaces=None, segments=8, show_grid=True, grid_segments=10, show_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 xy', 'CIE Lab', 'CIE LCHab', 'CIE Luv', 'CIE Luv uv', 'CIE LCHuv', 'CIE UCS', 'CIE UCS uv', 'CIE UVW', 'DIN 99', 'Hunter Lab', 'Hunter Rdab', 'IPT', 'JzAzBz', 'OSA UCS', 'hdr-CIELAB', 'hdr-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. show_grid : bool, optional Whether to show a grid at the bottom of the *RGB* colourspace cubes. grid_segments : bool, optional Edge segments count for the grid. show_spectral_locus : bool, optional Whether to show the spectral locus. spectral_locus_colour : array_like, optional Spectral locus 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:`colour.plotting.artist`, :func:`colour.plotting.plot_RGB_colourspaces_gamuts`}, Please refer to the documentation of the previously listed definitions. Returns ------- tuple Current figure and axes. Examples -------- >>> RGB = np.random.random((128, 128, 3)) >>> plot_RGB_scatter(RGB, 'ITU-R BT.709') # doctest: +SKIP .. image:: ../_static/Plotting_Plot_RGB_Scatter.png :align: center :alt: plot_RGB_scatter """ colourspace = first_item(filter_RGB_colourspaces(colourspace).values()) 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, }) settings.update(kwargs) settings['standalone'] = False plot_RGB_colourspaces_gamuts( colourspaces=colourspaces, reference_colourspace=reference_colourspace, segments=segments, show_grid=show_grid, grid_segments=grid_segments, show_spectral_locus=show_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 = plt.gca() axes.scatter( points[..., 0], points[..., 1], points[..., 2], color=np.reshape(RGB, (-1, 3)), s=points_size) settings.update({'axes': axes, 'standalone': True}) settings.update(kwargs) return render(**settings)
def decorate(**kwargs): """ Sets the figure decorations. Parameters ---------- \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. """ settings = Structure( **{'title': None, 'x_label': None, 'y_label': None, 'legend': False, 'legend_location': 'upper right', 'x_ticker': False, 'y_ticker': False, 'x_ticker_locator': matplotlib.ticker.AutoMinorLocator(2), 'y_ticker_locator': matplotlib.ticker.AutoMinorLocator(2), 'no_ticks': False, 'no_x_ticks': False, 'no_y_ticks': False, 'grid': False, 'grid_which': 'both', 'grid_axis': 'both', 'x_axis_line': False, 'y_axis_line': False, 'aspect': None}) settings.update(kwargs) if settings.title: pylab.title(settings.title) if settings.x_label: pylab.xlabel(settings.x_label) if settings.y_label: pylab.ylabel(settings.y_label) if settings.legend: pylab.legend(loc=settings.legend_location) if settings.x_ticker: matplotlib.pyplot.gca().xaxis.set_minor_locator( settings.x_ticker_locator) if settings.y_ticker: matplotlib.pyplot.gca().yaxis.set_minor_locator( settings.y_ticker_locator) if settings.no_ticks: matplotlib.pyplot.gca().set_xticks([]) matplotlib.pyplot.gca().set_yticks([]) if settings.no_x_ticks: matplotlib.pyplot.gca().set_xticks([]) if settings.no_y_ticks: matplotlib.pyplot.gca().set_yticks([]) if settings.grid: pylab.grid(which=settings.grid_which, axis=settings.grid_axis) if settings.x_axis_line: pylab.axvline(color='black', linestyle='--') if settings.y_axis_line: pylab.axhline(color='black', linestyle='--') if settings.aspect: matplotlib.pyplot.axes().set_aspect(settings.aspect) return True