def colour_rendering_index_bars_plot(spd, **kwargs): """ Plots the *colour rendering index* of given illuminant or light source. Parameters ---------- spd : SpectralPowerDistribution Illuminant or light source to plot the *colour rendering index*. \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> from colour import ILLUMINANTS_RELATIVE_SPDS >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2') >>> colour_rendering_index_bars_plot(illuminant) # doctest: +SKIP True """ if colour_quality_bars_plot( colour_rendering_index( spd, additional_data=True), standalone=False): settings = { 'title': 'Colour Rendering Index - {0}'.format(spd.title)} decorate(**settings) return display(**settings)
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs): """ Plots the *colour rendering index* of given illuminants or light sources spectral power distributions. Parameters ---------- spds : array_like Array of illuminants or light sources spectral power distributions to plot the *colour rendering index*. \**kwargs : dict, optional Keywords arguments. Returns ------- Figure Current figure or None. Examples -------- >>> from colour import ( ... ILLUMINANTS_RELATIVE_SPDS, ... LIGHT_SOURCES_RELATIVE_SPDS) >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2') >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P') >>> multi_spd_colour_rendering_index_bars_plot( # doctest: +SKIP ... [illuminant, light_source]) """ settings = {} settings.update(kwargs) settings.update({'standalone': False}) specifications = [ colour_rendering_index(spd, additional_data=True) for spd in spds ] # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `colour_quality_bars_plot` expects # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition # agnostic from the colour quality data, we update the test spd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i, c_d in enumerate(colorimetry_data[0]): colorimetry_data[0][i] = TCS_ColorimetryData( c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW) colour_quality_bars_plot(specifications, **settings) settings = { 'title': 'Colour Rendering Index - {0}'.format(', '.join( [spd.title for spd in spds])) } settings.update(kwargs) decorate(**settings) return display(**settings)
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs): """ Plots the *colour rendering index* of given illuminants or light sources spectral power distributions. Parameters ---------- spds : array_like Array of illuminants or light sources spectral power distributions to plot the *colour rendering index*. \**kwargs : dict, optional Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> from colour import ( ... ILLUMINANTS_RELATIVE_SPDS, ... LIGHT_SOURCES_RELATIVE_SPDS) >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2') >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS.get('Kinoton 75P') >>> multi_spd_colour_rendering_index_bars_plot( # doctest: +SKIP ... [illuminant, light_source]) True """ settings = {} settings.update(kwargs) settings.update({'standalone': False}) specifications = [colour_rendering_index(spd, additional_data=True) for spd in spds] # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `colour_quality_bars_plot` expects # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition # agnostic from the colour quality data, we update the test spd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i, c_d in enumerate(colorimetry_data[0]): colorimetry_data[0][i] = TCS_ColorimetryData(c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW) colour_quality_bars_plot(specifications, **settings) settings = {'title': 'Colour Rendering Index - {0}'.format(', '.join( [spd.title for spd in spds]))} settings.update(kwargs) decorate(**settings) return display(**settings)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS.get('F2')), 64.149547892010048, places=7) self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS.get('A')), 99.996736287811871, places=7) self.assertAlmostEqual(colour_rendering_index( SpectralPowerDistribution('Sample', SAMPLE_SPD_DATA)), 70.802983235772103, places=7)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_SDS['FL2']), 64.151520202968015, places=7) self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_SDS['A']), 99.996732643006169, places=7) self.assertAlmostEqual( colour_rendering_index(SpectralDistribution(SAMPLE_SD_DATA)), 70.813839034481575, places=7)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS.get('F2')), 64.1507331494, places=7) self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS.get('A')), 99.9978916846, places=7) self.assertAlmostEqual(colour_rendering_index( SpectralPowerDistribution('Sample', SAMPLE_SPD_DATA)), 70.805836753503698, places=7)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS['F2']), 64.151520202968015, places=7) self.assertAlmostEqual(colour_rendering_index( ILLUMINANTS_RELATIVE_SPDS['A']), 99.996732643006169, places=7) self.assertAlmostEqual(colour_rendering_index( SpectralPowerDistribution(SAMPLE_SPD_DATA)), 70.805386570659394, places=7)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_RELATIVE_SPDS.get('F2')), 64.149547892010048, places=7) self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_RELATIVE_SPDS.get('A')), 99.996736287811871, places=7) self.assertAlmostEqual( colour_rendering_index(SpectralPowerDistribution( 'Sample', SAMPLE_SPD_DATA)), 70.802983235772103, places=7)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_RELATIVE_SPDS.get('F2')), 64.1507331494, places=7) self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_RELATIVE_SPDS.get('A')), 99.9978916846, places=7) self.assertAlmostEqual( colour_rendering_index(SpectralPowerDistribution( 'Sample', SAMPLE_SPD_DATA)), 70.805836753503698, places=7)
def plot_multi_sds_colour_rendering_indexes_bars( sds: Union[ Sequence[Union[SpectralDistribution, MultiSpectralDistributions]], MultiSpectralDistributions, ], **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: """ Plot the *Colour Rendering Index* (CRI) of given illuminants or light sources spectral distributions. Parameters ---------- sds Spectral distributions or multi-spectral distributions to plot. `sds` can be a single :class:`colour.MultiSpectralDistributions` class instance, a list of :class:`colour.MultiSpectralDistributions` class instances or a list of :class:`colour.SpectralDistribution` class instances. Other Parameters ---------------- kwargs {:func:`colour.plotting.artist`, :func:`colour.plotting.quality.plot_colour_quality_bars`, :func:`colour.plotting.render`}, See the documentation of the previously listed definitions. Returns ------- :class:`tuple` Current figure and axes. Examples -------- >>> from colour import (SDS_ILLUMINANTS, ... SDS_LIGHT_SOURCES) >>> illuminant = SDS_ILLUMINANTS['FL2'] >>> light_source = SDS_LIGHT_SOURCES['Kinoton 75P'] >>> plot_multi_sds_colour_rendering_indexes_bars( ... [illuminant, light_source]) # doctest: +ELLIPSIS (<Figure size ... with 1 Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_\ Plot_Multi_SDS_Colour_Rendering_Indexes_Bars.png :align: center :alt: plot_multi_sds_colour_rendering_indexes_bars """ sds_converted = sds_and_msds_to_sds(sds) settings: Dict[str, Any] = dict(kwargs) settings.update({"standalone": False}) specifications = cast( List[ColourRendering_Specification_CRI], [ colour_rendering_index(sd, additional_data=True) for sd in sds_converted ], ) # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `plot_colour_quality_bars` expects # [0, 1] domain. As we want to keep `plot_colour_quality_bars` definition # agnostic from the colour quality data, we update the test sd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i in range(len(colorimetry_data[0])): colorimetry_data[0][i].XYZ /= 100 _figure, axes = plot_colour_quality_bars(specifications, **settings) title = ( f"Colour Rendering Index - " f"{', '.join([sd.strict_name for sd in sds_converted])}" ) settings = {"axes": axes, "title": title} settings.update(kwargs) return render(**settings)
def multi_spd_colour_rendering_index_bars_plot(spds, **kwargs): """ Plots the *Colour Rendering Index* (CRI) of given illuminants or light sources spectral power distributions. Parameters ---------- spds : array_like Array of illuminants or light sources spectral power distributions to plot the *Colour Rendering Index* (CRI). Other Parameters ---------------- \**kwargs : dict, optional {:func:`boundaries`, :func:`canvas`, :func:`decorate`, :func:`display`}, Please refer to the documentation of the previously listed definitions. labels : bool, optional {:func:`colour_quality_bars_plot`}, Add labels above bars. hatching : bool or None, optional {:func:`colour_quality_bars_plot`}, Use hatching for the bars. hatching_repeat : int, optional {:func:`colour_quality_bars_plot`}, Hatching pattern repeat. Returns ------- Figure Current figure or None. Examples -------- >>> from colour import ( ... ILLUMINANTS_RELATIVE_SPDS, ... LIGHT_SOURCES_RELATIVE_SPDS) >>> illuminant = ILLUMINANTS_RELATIVE_SPDS['F2'] >>> light_source = LIGHT_SOURCES_RELATIVE_SPDS['Kinoton 75P'] >>> multi_spd_colour_rendering_index_bars_plot( # doctest: +SKIP ... [illuminant, light_source]) """ settings = {} settings.update(kwargs) settings.update({'standalone': False}) specifications = [ colour_rendering_index(spd, additional_data=True) for spd in spds ] # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `colour_quality_bars_plot` expects # [0, 1] domain. As we want to keep `colour_quality_bars_plot` definition # agnostic from the colour quality data, we update the test spd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i, c_d in enumerate(colorimetry_data[0]): colorimetry_data[0][i] = TCS_ColorimetryData( c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW) colour_quality_bars_plot(specifications, **settings) settings = { 'title': 'Colour Rendering Index - {0}'.format(', '.join( [spd.title for spd in spds])) } settings.update(kwargs) decorate(**settings) return display(**settings)
def plot_multi_sds_colour_rendering_indexes_bars(sds, **kwargs): """ Plots the *Colour Rendering Index* (CRI) of given illuminants or light sources spectral distributions. Parameters ---------- sds : array_like or MultiSpectralDistributions Spectral distributions or multi-spectral distributions to plot. `sds` can be a single :class:`colour.MultiSpectralDistributions` class instance, a list of :class:`colour.MultiSpectralDistributions` class instances or a list of :class:`colour.SpectralDistribution` class instances. Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.quality.plot_colour_quality_bars`, :func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definitions. labels : bool, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Add labels above bars. hatching : bool or None, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Use hatching for the bars. hatching_repeat : int, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Hatching pattern repeat. Returns ------- tuple Current figure and axes. Examples -------- >>> from colour import (ILLUMINANTS_SDS, ... LIGHT_SOURCES_SDS) >>> illuminant = ILLUMINANTS_SDS['FL2'] >>> light_source = LIGHT_SOURCES_SDS['Kinoton 75P'] >>> plot_multi_sds_colour_rendering_indexes_bars( ... [illuminant, light_source]) # doctest: +ELLIPSIS (<Figure size ... with 1 Axes>, \ <matplotlib.axes._subplots.AxesSubplot object at 0x...>) .. image:: ../_static/Plotting_\ Plot_Multi_SDS_Colour_Rendering_Indexes_Bars.png :align: center :alt: plot_multi_sds_colour_rendering_indexes_bars """ sds = sds_and_multi_sds_to_sds(sds) settings = dict(kwargs) settings.update({'standalone': False}) specifications = [ colour_rendering_index(sd, additional_data=True) for sd in sds ] # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `plot_colour_quality_bars` expects # [0, 1] domain. As we want to keep `plot_colour_quality_bars` definition # agnostic from the colour quality data, we update the test sd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i, c_d in enumerate(colorimetry_data[0]): colorimetry_data[0][i] = TCS_ColorimetryData( c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW) _figure, axes = plot_colour_quality_bars(specifications, **settings) title = 'Colour Rendering Index - {0}'.format(', '.join( [sd.strict_name for sd in sds])) settings = {'axes': axes, 'title': title} settings.update(kwargs) return render(**settings)
def colour_rendering_index_bars_plot(illuminant, **kwargs): """ Plots the *colour rendering index* of given illuminant. Parameters ---------- illuminant : SpectralPowerDistribution Illuminant to plot the *colour rendering index*. \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> from colour import ILLUMINANTS_RELATIVE_SPDS >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2') >>> colour_rendering_index_bars_plot(illuminant) # doctest: +SKIP True """ figure, axis = matplotlib.pyplot.subplots() cri, colour_rendering_indexes, additional_data = \ colour_rendering_index(illuminant, additional_data=True) colours = ([[1] * 3] + [normalise(XYZ_to_sRGB(x.XYZ / 100)) for x in additional_data[0]]) x, y = tuple(zip(*sorted(colour_rendering_indexes.items(), key=lambda x: x[0]))) x, y = np.array([0] + list(x)), np.array( [cri] + list(y)) positive = True if np.sign(min(y)) in (0, 1) else False width = 0.5 bars = pylab.bar(x, y, color=colours, width=width) y_ticks_steps = 10 pylab.yticks(range(0 if positive else -100, 100 + y_ticks_steps, y_ticks_steps)) pylab.xticks(x + width / 2, ['Ra'] + ['R{0}'.format(index) for index in x[1:]]) def label_bars(bars): """ Add labels above given bars. """ for bar in bars: y = bar.get_y() height = bar.get_height() value = height if np.sign(y) in (0, 1) else -height axis.text(bar.get_x() + bar.get_width() / 2, 0.025 * height + height + y, '{0:.1f}'.format(value), ha='center', va='bottom') label_bars(bars) settings = { 'title': 'Colour Rendering Index - {0}'.format(illuminant.name), 'grid': True, 'x_tighten': True, 'y_tighten': True, 'limits': [-width, 14 + width * 2, -10 if positive else -110, 110]} settings.update(kwargs) bounding_box(**settings) aspect(**settings) return display(**settings)
def _full_report(spec, source, date, manufacturer, model, notes=None): figure = plt.figure(figsize=(8.27, 11.69)) figure.text(0.5, 0.97, 'TM-30-18 Color Rendition Report', ha='center', size='x-large') figure.text(0.250, 0.935, 'Source: ', ha='right', size='large', weight='bold') figure.text(0.250, 0.935, source, size='large') figure.text(0.250, 0.907, 'Date: ', ha='right', size='large', weight='bold') figure.text(0.250, 0.907, date, size='large') figure.text(0.700, 0.935, 'Manufacturer: ', ha='right', size='large', weight='bold') figure.text(0.700, 0.935, manufacturer, ha='left', size='large') figure.text(0.700, 0.907, 'Model: ', ha='right', size='large', weight='bold') figure.text(0.700, 0.907, model, size='large') ax = figure.add_axes((0.057, 0.767, 0.385, 0.112)) plot_spectra_TM_30_18(ax, spec) ax = figure.add_axes((0.036, 0.385, 0.428, 0.333)) plot_color_vector_graphic(ax, spec) ax = figure.add_axes((0.554, 0.736, 0.409, 0.141)) plot_local_chroma_shifts(ax, spec) ax = figure.add_axes((0.554, 0.576, 0.409, 0.141)) plot_local_hue_shifts(ax, spec) ax = figure.add_axes((0.554, 0.401, 0.409, 0.141)) plot_local_color_fidelities(ax, spec) ax = figure.add_axes((0.094, 0.195, 0.870, 0.161)) plot_colour_fidelity_indexes(ax, spec) if notes: figure.text(0.139, 0.114, 'Notes: ', ha='right', size='large', weight='bold') figure.text(0.139, 0.114, notes, size='large') XYZ = sd_to_XYZ(spec.sd_test) xy = XYZ_to_xy(XYZ) Luv = XYZ_to_Luv(XYZ, xy) up, vp = Luv_to_uv(Luv, xy) figure.text(0.712, 0.111, '$x$ {:.4f}'.format(xy[0]), ha='center') figure.text(0.712, 0.091, '$y$ {:.4f}'.format(xy[1]), ha='center') figure.text(0.712, 0.071, '$u\'$ {:.4f}'.format(up), ha='center') figure.text(0.712, 0.051, '$v\'$ {:.4f}'.format(vp), ha='center') rect = plt.Rectangle((0.814, 0.035), 0.144, 0.096, color='black', fill=False) figure.add_artist(rect) CRI_spec = colour_rendering_index(spec.sd_test, additional_data=True) figure.text(0.886, 0.111, 'CIE 13.31-1995', ha='center') figure.text(0.886, 0.091, '(CRI)', ha='center') figure.text(0.886, 0.071, '$R_a$ {:.0f}'.format(CRI_spec.Q_a), ha='center', weight='bold') figure.text(0.886, 0.051, '$R_9$ {:.0f}'.format(CRI_spec.Q_as[8].Q_a), ha='center', weight='bold') figure.text(0.500, 0.010, 'Created with Colour ' + colour.__version__, ha='center')
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual(colour_rendering_index(SDS_ILLUMINANTS['FL1']), 75.852827992149358, places=7) self.assertAlmostEqual(colour_rendering_index(SDS_ILLUMINANTS['FL2']), 64.233724121664778, places=7) self.assertAlmostEqual(colour_rendering_index(SDS_ILLUMINANTS['A']), 99.996230290506887, places=7) self.assertAlmostEqual(colour_rendering_index( SpectralDistribution(DATA_SAMPLE)), 70.815265381660197, places=7) specification_r = ColourRendering_Specification_CRI( name='FL1', Q_a=75.852827992149358, Q_as={ 1: TCS_ColourQualityScaleData(name='TCS01', Q_a=69.196992839933557), 2: TCS_ColourQualityScaleData(name='TCS02', Q_a=83.650754065677816), 3: TCS_ColourQualityScaleData(name='TCS03', Q_a=92.136090764490675), 4: TCS_ColourQualityScaleData(name='TCS04', Q_a=72.665649420972784), 5: TCS_ColourQualityScaleData(name='TCS05', Q_a=73.890734513517486), 6: TCS_ColourQualityScaleData(name='TCS06', Q_a=79.619188860052745), 7: TCS_ColourQualityScaleData(name='TCS07', Q_a=82.272569853644669), 8: TCS_ColourQualityScaleData(name='TCS08', Q_a=53.390643618905109), 9: TCS_ColourQualityScaleData(name='TCS09', Q_a=-47.284477750225903), 10: TCS_ColourQualityScaleData(name='TCS10', Q_a=61.568336431199967), 11: TCS_ColourQualityScaleData(name='TCS11', Q_a=67.522241168172485), 12: TCS_ColourQualityScaleData(name='TCS12', Q_a=74.890093866757994), 13: TCS_ColourQualityScaleData(name='TCS13', Q_a=72.771930354944615), 14: TCS_ColourQualityScaleData(name='TCS14', Q_a=94.884867470552663) }, colorimetry_data=([ TCS_ColorimetryData( name='TCS01', XYZ=np.array([31.19561134, 29.74560797, 23.44190201]), uv=np.array([0.22782766, 0.32585700]), UVW=np.array([25.43090825, 8.72673714, 60.46061819])), TCS_ColorimetryData( name='TCS02', XYZ=np.array([26.70829694, 29.25797165, 13.98804447]), uv=np.array([0.21049132, 0.34587843]), UVW=np.array([11.90704877, 24.68727835, 60.03499882])), TCS_ColorimetryData( name='TCS03', XYZ=np.array([24.20150315, 31.45341032, 9.19170689]), uv=np.array([0.18489328, 0.36044399]), UVW=np.array([-8.11343024, 37.47469142, 61.91555021])), TCS_ColorimetryData( name='TCS04', XYZ=np.array([20.74577359, 29.44046997, 19.40749007]), uv=np.array([0.15940652, 0.33932233]), UVW=np.array([-27.55686536, 19.30727375, 60.19483706])), TCS_ColorimetryData( name='TCS05', XYZ=np.array([25.09405566, 30.60912259, 37.93634878]), uv=np.array([0.16784200, 0.30709443]), UVW=np.array([-21.30541564, -6.63859760, 61.20303996])), TCS_ColorimetryData( name='TCS06', XYZ=np.array([27.43598853, 28.84467787, 55.15209308]), uv=np.array([0.17543246, 0.27665994]), UVW=np.array([-14.91500194, -30.51166823, 59.67054901])), TCS_ColorimetryData( name='TCS07', XYZ=np.array([31.30354023, 28.49931283, 51.55875721]), uv=np.array([0.20410821, 0.27873574]), UVW=np.array([6.88826195, -28.65430811, 59.36332055])), TCS_ColorimetryData( name='TCS08', XYZ=np.array([33.81156122, 29.92921717, 44.07459562]), uv=np.array([0.21992203, 0.29200489]), UVW=np.array([19.29699368, -18.57115711, 60.61967045])), TCS_ColorimetryData( name='TCS09', XYZ=np.array([14.75210654, 9.07663825, 4.24056478]), uv=np.array([0.36063567, 0.33283649]), UVW=np.array([74.85972274, 8.59043120, 35.14928413])), TCS_ColorimetryData( name='TCS10', XYZ=np.array([53.37923227, 60.57123196, 10.90035400]), uv=np.array([0.21466565, 0.36538264]), UVW=np.array([20.48612095, 54.66177264, 81.18130740])), TCS_ColorimetryData( name='TCS11', XYZ=np.array([12.25313424, 19.77564573, 14.04738059]), uv=np.array([0.13962494, 0.33801637]), UVW=np.array([-36.00690822, 15.29571595, 50.60573931])), TCS_ColorimetryData( name='TCS12', XYZ=np.array([5.77964943, 5.69096075, 24.73530409]), uv=np.array([0.13981616, 0.20650602]), UVW=np.array([-19.30689974, -39.58762581, 27.63428055])), TCS_ColorimetryData( name='TCS13', XYZ=np.array([56.62340157, 57.50304691, 39.13768236]), uv=np.array([0.21850039, 0.33284220]), UVW=np.array([23.93135946, 18.85365757, 79.49473722])), TCS_ColorimetryData( name='TCS14', XYZ=np.array([9.42270977, 12.06929274, 5.06066928]), uv=np.array([0.18328188, 0.35214117]), UVW=np.array([-6.11563143, 19.91896684, 40.34566797])) ], [ TCS_ColorimetryData( name='TCS01', XYZ=np.array([33.04774537, 29.80902109, 24.23929188]), uv=np.array([0.23908620, 0.32348313]), UVW=np.array([32.11891091, 8.39794012, 60.51562388])), TCS_ColorimetryData( name='TCS02', XYZ=np.array([27.53677515, 28.90913487, 14.75211494]), uv=np.array([0.21792745, 0.34318256]), UVW=np.array([15.27177183, 23.58438306, 59.72761646])), TCS_ColorimetryData( name='TCS03', XYZ=np.array([23.95706051, 30.44569936, 9.79977770]), uv=np.array([0.18788308, 0.35815528]), UVW=np.array([-8.23665275, 35.99767796, 61.06361523])), TCS_ColorimetryData( name='TCS04', XYZ=np.array([20.43647757, 29.46748627, 21.03631859]), uv=np.array([0.15554126, 0.33641389]), UVW=np.array([-33.44111710, 18.47940853, 60.21844268])), TCS_ColorimetryData( name='TCS05', XYZ=np.array([24.95511680, 30.81953457, 39.91407614]), uv=np.array([0.16445149, 0.30464603]), UVW=np.array([-26.97713986, -6.51317420, 61.38182431])), TCS_ColorimetryData( name='TCS06', XYZ=np.array([28.14601546, 29.75632189, 57.16886797]), uv=np.array([0.17427942, 0.27637560]), UVW=np.array([-18.85053083, -28.64005452, 60.46991712])), TCS_ColorimetryData( name='TCS07', XYZ=np.array([33.29720901, 29.36938555, 52.53803430]), uv=np.array([0.21092469, 0.27906521]), UVW=np.array([9.90110830, -26.37778265, 60.13265766])), TCS_ColorimetryData( name='TCS08', XYZ=np.array([37.64974363, 31.35401774, 44.84930911]), uv=np.array([0.23439240, 0.29279655]), UVW=np.array([29.04479043, -16.08583648, 61.83233828])), TCS_ColorimetryData( name='TCS09', XYZ=np.array([20.69443384, 11.28822434, 4.28723010]), uv=np.array([0.40801431, 0.33384028]), UVW=np.array([106.56664825, 10.68535426, 39.08093160])), TCS_ColorimetryData( name='TCS10', XYZ=np.array([55.04099876, 59.04719161, 11.86354410]), uv=np.array([0.22549942, 0.36286881]), UVW=np.array([28.45432459, 52.29127793, 80.35085218])), TCS_ColorimetryData( name='TCS11', XYZ=np.array([12.13069359, 20.35272336, 15.17132466]), uv=np.array([0.13369530, 0.33646842]), UVW=np.array([-43.02145539, 15.76573781, 51.25705062])), TCS_ColorimetryData( name='TCS12', XYZ=np.array([6.18799870, 6.41132549, 27.28158667]), uv=np.array([0.13437372, 0.20883497]), UVW=np.array([-24.45285903, -39.79705961, 29.44325151])), TCS_ColorimetryData( name='TCS13', XYZ=np.array([58.97935503, 57.14777525, 40.83450223]), uv=np.array([0.22712769, 0.33011150]), UVW=np.array([29.75912462, 17.83690656, 79.29560174])), TCS_ColorimetryData( name='TCS14', XYZ=np.array([9.34469915, 11.70922060, 5.33442353]), uv=np.array([0.18597686, 0.34955284]), UVW=np.array([-6.34991066, 18.99712303, 39.76962229])) ])) specification_t = colour_rendering_index(SDS_ILLUMINANTS['FL1'], additional_data=True) np.testing.assert_almost_equal( [ data.Q_a for _index, data in sorted(specification_r.Q_as.items()) ], [ data.Q_a for _index, data in sorted(specification_t.Q_as.items()) ], decimal=7, )
def colour_rendering_index_bars_plot(illuminant, **kwargs): """ Plots the *colour rendering index* of given illuminant. Parameters ---------- illuminant : SpectralPowerDistribution Illuminant to plot the *colour rendering index*. \*\*kwargs : \*\* Keywords arguments. Returns ------- bool Definition success. Examples -------- >>> from colour import ILLUMINANTS_RELATIVE_SPDS >>> illuminant = ILLUMINANTS_RELATIVE_SPDS.get('F2') >>> colour_rendering_index_bars_plot(illuminant) # doctest: +SKIP True """ figure, axis = matplotlib.pyplot.subplots() cri, colour_rendering_indexes, additional_data = \ colour_rendering_index(illuminant, additional_data=True) colours = ( [[1] * 3] + [normalise(XYZ_to_sRGB(x.XYZ / 100)) for x in additional_data[0]]) x, y = tuple( zip(*sorted(colour_rendering_indexes.items(), key=lambda x: x[0]))) x, y = np.array([0] + list(x)), np.array([cri] + list(y)) positive = True if np.sign(min(y)) in (0, 1) else False width = 0.5 bars = pylab.bar(x, y, color=colours, width=width) y_ticks_steps = 10 pylab.yticks( range(0 if positive else -100, 100 + y_ticks_steps, y_ticks_steps)) pylab.xticks(x + width / 2, ['Ra'] + ['R{0}'.format(index) for index in x[1:]]) def label_bars(bars): """ Add labels above given bars. """ for bar in bars: y = bar.get_y() height = bar.get_height() value = height if np.sign(y) in (0, 1) else -height axis.text(bar.get_x() + bar.get_width() / 2, 0.025 * height + height + y, '{0:.1f}'.format(value), ha='center', va='bottom') label_bars(bars) settings = { 'title': 'Colour Rendering Index - {0}'.format(illuminant.name), 'grid': True, 'x_tighten': True, 'y_tighten': True, 'limits': [-width, 14 + width * 2, -10 if positive else -110, 110] } settings.update(kwargs) bounding_box(**settings) aspect(**settings) return display(**settings)
def plot_multi_sds_colour_rendering_indexes_bars(sds, **kwargs): """ Plots the *Colour Rendering Index* (CRI) of given illuminants or light sources spectral distributions. Parameters ---------- sds : array_like Array of illuminants or light sources spectral distributions to plot the *Colour Rendering Index* (CRI). Other Parameters ---------------- \\**kwargs : dict, optional {:func:`colour.plotting.artist`, :func:`colour.plotting.quality.plot_colour_quality_bars`, :func:`colour.plotting.render`}, Please refer to the documentation of the previously listed definitions. labels : bool, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Add labels above bars. hatching : bool or None, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Use hatching for the bars. hatching_repeat : int, optional {:func:`colour.plotting.quality.plot_colour_quality_bars`}, Hatching pattern repeat. Returns ------- tuple Current figure and axes. Examples -------- >>> from colour import (ILLUMINANTS_SDS, ... LIGHT_SOURCES_SDS) >>> illuminant = ILLUMINANTS_SDS['FL2'] >>> light_source = LIGHT_SOURCES_SDS['Kinoton 75P'] >>> plot_multi_sds_colour_rendering_indexes_bars( ... [illuminant, light_source]) # doctest: +SKIP .. image:: ../_static/Plotting_\ Plot_Multi_SDs_Colour_Rendering_Indexes_Bars.png :align: center :alt: plot_multi_sds_colour_rendering_indexes_bars """ settings = dict(kwargs) settings.update({'standalone': False}) specifications = [ colour_rendering_index(sd, additional_data=True) for sd in sds ] # *colour rendering index* colorimetry data tristimulus values are # computed in [0, 100] domain however `plot_colour_quality_bars` expects # [0, 1] domain. As we want to keep `plot_colour_quality_bars` definition # agnostic from the colour quality data, we update the test sd # colorimetry data tristimulus values domain. for specification in specifications: colorimetry_data = specification.colorimetry_data for i, c_d in enumerate(colorimetry_data[0]): colorimetry_data[0][i] = TCS_ColorimetryData( c_d.name, c_d.XYZ / 100, c_d.uv, c_d.UVW) _figure, axes = plot_colour_quality_bars(specifications, **settings) title = 'Colour Rendering Index - {0}'.format(', '.join( [sd.strict_name for sd in sds])) settings = {'axes': axes, 'title': title} settings.update(kwargs) return render(**settings)
def plot_single_sd_colour_rendition_report_full( sd, source=None, date=None, manufacturer=None, model=None, notes=None, report_size=CONSTANT_REPORT_SIZE_FULL, report_row_height_ratios=CONSTANT_REPORT_ROW_HEIGHT_RATIOS_FULL, report_box_padding=None, **kwargs): """ Generates the full *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution. Parameters ---------- sd : SpectralDistribution or SpectralDistribution_IESTM2714 Spectral distribution of the emission source to generate the report for. source : unicode, optional Emission source name, defaults to `colour.SpectralDistribution_IESTM2714.header.description` or `colour.SpectralDistribution_IESTM2714.name` properties value. date : unicode, optional Emission source measurement date, defaults to `colour.SpectralDistribution_IESTM2714.header.report_date` property value. manufacturer : unicode, optional Emission source manufacturer, defaults to `colour.SpectralDistribution_IESTM2714.header.manufacturer` property value. model : unicode, optional Emission source model, defaults to `colour.SpectralDistribution_IESTM2714.header.catalog_number` property value. notes : unicode, optional Notes pertaining to the emission source, defaults to `colour.SpectralDistribution_IESTM2714.header.comments` property value. report_size : array_like, optional Report size, default to A4 paper size in inches. report_row_height_ratios : array_like, optional Report size row height ratios. report_box_padding : array_like, optional Report box padding, tries to define the padding around the figure and in-between the axes. 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 -------- >>> from colour import SDS_ILLUMINANTS >>> sd = SDS_ILLUMINANTS['FL2'] >>> plot_single_sd_colour_rendition_report_full(sd) ... # doctest: +ELLIPSIS (<Figure size ... with ... Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_\ Plot_Single_SD_Colour_Rendition_Report_Full.png :align: center :alt: plot_single_sd_colour_rendition_report_full """ if six.PY2: runtime_warning( 'The "ANSI/IES TM-30-18 Colour Rendition Report" uses advanced ' '"Matplotlib" layout capabilities only available for Python 3!') return render() if report_box_padding is None: report_box_padding = CONSTANT_REPORT_PADDING_FULL specification = colour_fidelity_index_ANSIIESTM3018(sd, True) sd = (SpectralDistribution_IESTM2714(data=sd, name=sd.name) if not isinstance(sd, SpectralDistribution_IESTM2714) else sd) source = sd.header.description if source is None else source source = sd.name if source is None else source date = sd.header.report_date if date is None else date date = _NOT_APPLICABLE_VALUE if date is None else date manufacturer = (sd.header.manufacturer if manufacturer is None else manufacturer) manufacturer = (_NOT_APPLICABLE_VALUE if manufacturer is None else manufacturer) model = sd.header.catalog_number if model is None else model model = _NOT_APPLICABLE_VALUE if model is None else model notes = sd.header.comments if notes is None else notes notes = _NOT_APPLICABLE_VALUE if notes is None else notes figure = plt.figure(figsize=report_size, constrained_layout=True) settings = kwargs.copy() settings['standalone'] = False settings['tight_layout'] = False gridspec_report = figure.add_gridspec( 5, 1, height_ratios=report_row_height_ratios) # Title Row gridspec_title = gridspec_report[0].subgridspec(1, 1) axes_title = figure.add_subplot(gridspec_title[0]) _plot_report_header(axes_title) # Description Rows & Columns gridspec_description = gridspec_report[1].subgridspec(1, 2) # Source & Date Column axes_source_date = figure.add_subplot(gridspec_description[0]) axes_source_date.set_axis_off() axes_source_date.text(0.25, 2 / 3, 'Source: ', ha='right', va='center', size='medium', weight='bold') axes_source_date.text(0.25, 2 / 3, source, va='center', size='medium') axes_source_date.text(0.25, 1 / 3, 'Date: ', ha='right', va='center', size='medium', weight='bold') axes_source_date.text(0.25, 1 / 3, date, va='center', size='medium') # Manufacturer & Model Column axes_manufacturer_model = figure.add_subplot(gridspec_description[1]) axes_manufacturer_model.set_axis_off() axes_manufacturer_model.text(0.25, 2 / 3, 'Manufacturer: ', ha='right', va='center', size='medium', weight='bold') axes_manufacturer_model.text(0.25, 2 / 3, manufacturer, va='center', size='medium') axes_manufacturer_model.text(0.25, 1 / 3, 'Model: ', ha='right', va='center', size='medium', weight='bold') axes_manufacturer_model.text(0.25, 1 / 3, model, va='center', size='medium') # Main Figures Rows & Columns gridspec_figures = gridspec_report[2].subgridspec( 4, 2, height_ratios=[1, 1, 1, 1.5]) axes_spectra = figure.add_subplot(gridspec_figures[0, 0]) plot_spectra_ANSIIESTM3018(specification, axes=axes_spectra, **settings) axes_vector_graphics = figure.add_subplot(gridspec_figures[1:3, 0]) plot_colour_vector_graphic(specification, axes=axes_vector_graphics, **settings) axes_chroma_shifts = figure.add_subplot(gridspec_figures[0, 1]) plot_local_chroma_shifts(specification, axes=axes_chroma_shifts, **settings) axes_hue_shifts = figure.add_subplot(gridspec_figures[1, 1]) plot_local_hue_shifts(specification, axes=axes_hue_shifts, **settings) axes_colour_fidelities = figure.add_subplot(gridspec_figures[2, 1]) plot_local_colour_fidelities(specification, axes=axes_colour_fidelities, x_ticker=True, **settings) # Colour Fidelity Indexes Row axes_colour_fidelity_indexes = figure.add_subplot(gridspec_figures[3, :]) plot_colour_fidelity_indexes(specification, axes=axes_colour_fidelity_indexes, **settings) # Notes & Chromaticities / CRI Row and Columns gridspec_notes_chromaticities_CRI = gridspec_report[3].subgridspec(1, 2) axes_notes = figure.add_subplot(gridspec_notes_chromaticities_CRI[0]) axes_notes.set_axis_off() axes_notes.text(0.25, 1, 'Notes: ', ha='right', va='center', size='medium', weight='bold') axes_notes.text(0.25, 1, notes, va='center', size='medium') gridspec_chromaticities_CRI = gridspec_notes_chromaticities_CRI[ 1].subgridspec(1, 2) XYZ = sd_to_XYZ(specification.sd_test) xy = XYZ_to_xy(XYZ) Luv = XYZ_to_Luv(XYZ, xy) uv_p = Luv_to_uv(Luv, xy) gridspec_chromaticities = gridspec_chromaticities_CRI[0].subgridspec(1, 1) axes_chromaticities = figure.add_subplot(gridspec_chromaticities[0]) axes_chromaticities.set_axis_off() axes_chromaticities.text(0.5, 4 / 5, '$x$ {:.4f}'.format(xy[0]), ha='center', va='center', size='medium', weight='bold') axes_chromaticities.text(0.5, 3 / 5, '$y$ {:.4f}'.format(xy[1]), ha='center', va='center', size='medium', weight='bold') axes_chromaticities.text(0.5, 2 / 5, '$u\'$ {:.4f}'.format(uv_p[0]), ha='center', va='center', size='medium', weight='bold') axes_chromaticities.text(0.5, 1 / 5, '$v\'$ {:.4f}'.format(uv_p[1]), ha='center', va='center', size='medium', weight='bold') gridspec_CRI = gridspec_chromaticities_CRI[1].subgridspec(1, 1) CRI_spec = colour_rendering_index(specification.sd_test, additional_data=True) axes_CRI = figure.add_subplot(gridspec_CRI[0]) axes_CRI.set_xticks([]) axes_CRI.set_yticks([]) axes_CRI.text(0.5, 4 / 5, 'CIE 13.31-1995', ha='center', va='center', size='medium', weight='bold') axes_CRI.text(0.5, 3 / 5, '(CRI)', ha='center', va='center', size='medium', weight='bold') axes_CRI.text(0.5, 2 / 5, '$R_a$ {:.0f}'.format(CRI_spec.Q_a), ha='center', va='center', size='medium', weight='bold') axes_CRI.text(0.5, 1 / 5, '$R_9$ {:.0f}'.format(CRI_spec.Q_as[8].Q_a), ha='center', va='center', size='medium', weight='bold') gridspec_footer = gridspec_report[4].subgridspec(1, 1) axes_footer = figure.add_subplot(gridspec_footer[0]) _plot_report_footer(axes_footer) figure.set_constrained_layout_pads(**report_box_padding) settings = kwargs.copy() settings['tight_layout'] = False return render(**settings)
def plot_single_sd_colour_rendition_report_full( sd: SpectralDistribution, source: Optional[str] = None, date: Optional[str] = None, manufacturer: Optional[str] = None, model: Optional[str] = None, notes: Optional[str] = None, report_size: Tuple = CONSTANT_REPORT_SIZE_FULL, report_row_height_ratios: Tuple = CONSTANT_REPORT_ROW_HEIGHT_RATIOS_FULL, report_box_padding: Optional[Dict] = None, **kwargs: Any, ) -> Tuple[plt.Figure, plt.Axes]: # noqa: D405,D407,D410,D411 """ Generate the full *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution. Parameters ---------- sd Spectral distribution of the emission source to generate the report for. source Emission source name, defaults to `colour.SpectralDistribution_IESTM2714.header.description` or `colour.SpectralDistribution_IESTM2714.name` properties value. date Emission source measurement date, defaults to `colour.SpectralDistribution_IESTM2714.header.report_date` property value. manufacturer Emission source manufacturer, defaults to `colour.SpectralDistribution_IESTM2714.header.manufacturer` property value. model Emission source model, defaults to `colour.SpectralDistribution_IESTM2714.header.catalog_number` property value. notes Notes pertaining to the emission source, defaults to `colour.SpectralDistribution_IESTM2714.header.comments` property value. report_size Report size, default to A4 paper size in inches. report_row_height_ratios Report size row height ratios. report_box_padding Report box padding, tries to define the padding around the figure and in-between the axes. 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 -------- >>> from colour import SDS_ILLUMINANTS >>> sd = SDS_ILLUMINANTS['FL2'] >>> plot_single_sd_colour_rendition_report_full(sd) ... # doctest: +ELLIPSIS (<Figure size ... with ... Axes>, <...AxesSubplot...>) .. image:: ../_static/Plotting_\ Plot_Single_SD_Colour_Rendition_Report_Full.png :align: center :alt: plot_single_sd_colour_rendition_report_full """ report_box_padding = optional(report_box_padding, CONSTANT_REPORT_PADDING_FULL) specification: ColourQuality_Specification_ANSIIESTM3018 = cast( ColourQuality_Specification_ANSIIESTM3018, colour_fidelity_index_ANSIIESTM3018(sd, True), ) sd = (SpectralDistribution_IESTM2714(data=sd, name=sd.name) if not isinstance(sd, SpectralDistribution_IESTM2714) else sd) NA = _VALUE_NOT_APPLICABLE source = optional(optional(source, sd.header.description), sd.name) date = optional(optional(date, sd.header.report_date), NA) manufacturer = optional(optional(manufacturer, sd.header.manufacturer), NA) model = optional(optional(model, sd.header.catalog_number), NA) notes = optional(optional(notes, sd.header.comments), NA) figure = plt.figure(figsize=report_size, constrained_layout=True) settings: Dict[str, Any] = dict(kwargs) settings["standalone"] = False settings["tight_layout"] = False gridspec_report = figure.add_gridspec( 5, 1, height_ratios=report_row_height_ratios) # Title Row gridspec_title = gridspec_report[0].subgridspec(1, 1) axes_title = figure.add_subplot(gridspec_title[0]) _plot_report_header(axes_title) # Description Rows & Columns gridspec_description = gridspec_report[1].subgridspec(1, 2) # Source & Date Column axes_source_date = figure.add_subplot(gridspec_description[0]) axes_source_date.set_axis_off() axes_source_date.text( 0.25, 2 / 3, "Source: ", ha="right", va="center", size="medium", weight="bold", ) axes_source_date.text(0.25, 2 / 3, source, va="center", size="medium") axes_source_date.text( 0.25, 1 / 3, "Date: ", ha="right", va="center", size="medium", weight="bold", ) axes_source_date.text(0.25, 1 / 3, date, va="center", size="medium") # Manufacturer & Model Column axes_manufacturer_model = figure.add_subplot(gridspec_description[1]) axes_manufacturer_model.set_axis_off() axes_manufacturer_model.text( 0.25, 2 / 3, "Manufacturer: ", ha="right", va="center", size="medium", weight="bold", ) axes_manufacturer_model.text(0.25, 2 / 3, manufacturer, va="center", size="medium") axes_manufacturer_model.text( 0.25, 1 / 3, "Model: ", ha="right", va="center", size="medium", weight="bold", ) axes_manufacturer_model.text(0.25, 1 / 3, model, va="center", size="medium") # Main Figures Rows & Columns gridspec_figures = gridspec_report[2].subgridspec( 4, 2, height_ratios=[1, 1, 1, 1.5]) axes_spectra = figure.add_subplot(gridspec_figures[0, 0]) plot_spectra_ANSIIESTM3018(specification, axes=axes_spectra, **settings) axes_vector_graphics = figure.add_subplot(gridspec_figures[1:3, 0]) plot_colour_vector_graphic(specification, axes=axes_vector_graphics, **settings) axes_chroma_shifts = figure.add_subplot(gridspec_figures[0, 1]) plot_local_chroma_shifts(specification, axes=axes_chroma_shifts, **settings) axes_hue_shifts = figure.add_subplot(gridspec_figures[1, 1]) plot_local_hue_shifts(specification, axes=axes_hue_shifts, **settings) axes_colour_fidelities = figure.add_subplot(gridspec_figures[2, 1]) plot_local_colour_fidelities(specification, axes=axes_colour_fidelities, x_ticker=True, **settings) # Colour Fidelity Indexes Row axes_colour_fidelity_indexes = figure.add_subplot(gridspec_figures[3, :]) plot_colour_fidelity_indexes(specification, axes=axes_colour_fidelity_indexes, **settings) # Notes & Chromaticities / CRI Row and Columns gridspec_notes_chromaticities_CRI = gridspec_report[3].subgridspec(1, 2) axes_notes = figure.add_subplot(gridspec_notes_chromaticities_CRI[0]) axes_notes.set_axis_off() axes_notes.text( 0.25, 1, "Notes: ", ha="right", va="center", size="medium", weight="bold", ) axes_notes.text(0.25, 1, notes, va="center", size="medium") gridspec_chromaticities_CRI = gridspec_notes_chromaticities_CRI[ 1].subgridspec(1, 2) XYZ = sd_to_XYZ(specification.sd_test) xy = XYZ_to_xy(XYZ) Luv = XYZ_to_Luv(XYZ, xy) uv_p = Luv_to_uv(Luv, xy) gridspec_chromaticities = gridspec_chromaticities_CRI[0].subgridspec(1, 1) axes_chromaticities = figure.add_subplot(gridspec_chromaticities[0]) axes_chromaticities.set_axis_off() axes_chromaticities.text( 0.5, 4 / 5, f"$x$ {xy[0]:.4f}", ha="center", va="center", size="medium", weight="bold", ) axes_chromaticities.text( 0.5, 3 / 5, f"$y$ {xy[1]:.4f}", ha="center", va="center", size="medium", weight="bold", ) axes_chromaticities.text( 0.5, 2 / 5, f"$u'$ {uv_p[0]:.4f}", ha="center", va="center", size="medium", weight="bold", ) axes_chromaticities.text( 0.5, 1 / 5, f"$v'$ {uv_p[1]:.4f}", ha="center", va="center", size="medium", weight="bold", ) gridspec_CRI = gridspec_chromaticities_CRI[1].subgridspec(1, 1) CRI_spec: ColourRendering_Specification_CRI = cast( ColourRendering_Specification_CRI, colour_rendering_index(specification.sd_test, additional_data=True), ) axes_CRI = figure.add_subplot(gridspec_CRI[0]) axes_CRI.set_xticks([]) axes_CRI.set_yticks([]) axes_CRI.text( 0.5, 4 / 5, "CIE 13.31-1995", ha="center", va="center", size="medium", weight="bold", ) axes_CRI.text( 0.5, 3 / 5, "(CRI)", ha="center", va="center", size="medium", weight="bold", ) axes_CRI.text( 0.5, 2 / 5, f"$R_a$ {float(CRI_spec.Q_a):.0f}", ha="center", va="center", size="medium", weight="bold", ) axes_CRI.text( 0.5, 1 / 5, f"$R_9$ {float(CRI_spec.Q_as[8].Q_a):.0f}", ha="center", va="center", size="medium", weight="bold", ) gridspec_footer = gridspec_report[4].subgridspec(1, 1) axes_footer = figure.add_subplot(gridspec_footer[0]) _plot_report_footer(axes_footer) figure.set_constrained_layout_pads(**report_box_padding) settings = dict(kwargs) settings["tight_layout"] = False return render(**settings)
def test_colour_rendering_index(self): """ Tests :func:`colour.quality.cri.colour_rendering_index` definition. """ self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_SDS['FL1']), 75.821550491976069, places=7) self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_SDS['FL2']), 64.151520202968015, places=7) self.assertAlmostEqual( colour_rendering_index(ILLUMINANTS_SDS['A']), 99.996732643006169, places=7) self.assertAlmostEqual( colour_rendering_index(SpectralDistribution(SAMPLE_SD_DATA)), 70.813839034481575, places=7) specification_r = CRI_Specification( name='FL1', Q_a=75.821550491976069, Q_as={ 1: TCS_ColourQualityScaleData( name='TCS01', Q_a=69.146993939830651), 2: TCS_ColourQualityScaleData( name='TCS02', Q_a=83.621259237346464), 3: TCS_ColourQualityScaleData( name='TCS03', Q_a=92.103176674726171), 4: TCS_ColourQualityScaleData( name='TCS04', Q_a=72.659091884741599), 5: TCS_ColourQualityScaleData( name='TCS05', Q_a=73.875477056438399), 6: TCS_ColourQualityScaleData( name='TCS06', Q_a=79.561558275578435), 7: TCS_ColourQualityScaleData( name='TCS07', Q_a=82.238690395582836), 8: TCS_ColourQualityScaleData( name='TCS08', Q_a=53.366156471564040), 9: TCS_ColourQualityScaleData( name='TCS09', Q_a=-47.429377845680563), 10: TCS_ColourQualityScaleData( name='TCS10', Q_a=61.459446471229136), 11: TCS_ColourQualityScaleData( name='TCS11', Q_a=67.488681008259860), 12: TCS_ColourQualityScaleData( name='TCS12', Q_a=74.912512331077920), 13: TCS_ColourQualityScaleData( name='TCS13', Q_a=72.752285379884341), 14: TCS_ColourQualityScaleData( name='TCS14', Q_a=94.874668874605561) }, colorimetry_data=([ TCS_ColorimetryData( name='TCS01', XYZ=np.array([31.20331782, 29.74794094, 23.46699878]), uv=np.array([0.22783485, 0.32581236]), UVW=np.array([25.41292946, 8.7380799, 60.46264324])), TCS_ColorimetryData( name='TCS02', XYZ=np.array([26.7148606, 29.25905082, 14.00052658]), uv=np.array([0.21051808, 0.34585016]), UVW=np.array([11.89933381, 24.70828029, 60.03594595])), TCS_ColorimetryData( name='TCS03', XYZ=np.array([24.20882878, 31.45657446, 9.19966949]), uv=np.array([0.18492146, 0.36042609]), UVW=np.array([-8.1256375, 37.50367669, 61.91819636])), TCS_ColorimetryData( name='TCS04', XYZ=np.array([20.75294445, 29.43766611, 19.42067879]), uv=np.array([0.15946018, 0.33928696]), UVW=np.array([-27.55034027, 19.3247759, 60.19238635])), TCS_ColorimetryData( name='TCS05', XYZ=np.array([25.10593837, 30.60666903, 37.97182815]), uv=np.array([0.1678986, 0.30702797]), UVW=np.array([-21.29395798, -6.63937802, 61.20095038])), TCS_ColorimetryData( name='TCS06', XYZ=np.array([27.45144596, 28.84090621, 55.21254008]), uv=np.array([0.17549196, 0.27656177]), UVW=np.array([-14.89855536, -30.53194048, 59.66720711])), TCS_ColorimetryData( name='TCS07', XYZ=np.array([31.31828342, 28.49717267, 51.6262295]), uv=np.array([0.20414276, 0.27863076]), UVW=np.array([6.89004159, -28.68174855, 59.36140901])), TCS_ColorimetryData( name='TCS08', XYZ=np.array([33.82293106, 29.92724727, 44.13391542]), uv=np.array([0.21993884, 0.29190983]), UVW=np.array([19.28664162, -18.59403459, 60.61796747])), TCS_ColorimetryData( name='TCS09', XYZ=np.array([14.74628552, 9.07383027, 4.24660598]), uv=np.array([0.36055908, 0.33279417]), UVW=np.array([74.80963996, 8.5929104, 35.14390587])), TCS_ColorimetryData( name='TCS10', XYZ=np.array([53.38914901, 60.57766887, 10.90608553]), uv=np.array([0.21467884, 0.36537604]), UVW=np.array([20.46081762, 54.70909846, 81.18478519])), TCS_ColorimetryData( name='TCS11', XYZ=np.array([12.25740399, 19.77026703, 14.05795099]), uv=np.array([0.13969138, 0.33796747]), UVW=np.array([-35.99235266, 15.30093833, 50.59960948])), TCS_ColorimetryData( name='TCS12', XYZ=np.array([5.7789513, 5.68760485, 24.7298429]), uv=np.array([0.13985629, 0.20646843]), UVW=np.array([-19.30294902, -39.56090075, 27.62550537])), TCS_ColorimetryData( name='TCS13', XYZ=np.array([56.63907549, 57.50545374, 39.17805]), uv=np.array([0.21852443, 0.33280062]), UVW=np.array([23.92148732, 18.87040227, 79.49608348])), TCS_ColorimetryData( name='TCS14', XYZ=np.array([9.42594992, 12.07064446, 5.06612415]), uv=np.array([0.18330936, 0.35211232]), UVW=np.array([-6.1238664, 19.9332886, 40.34780872])) ], [ TCS_ColorimetryData( name='TCS01', XYZ=np.array([33.04406274, 29.80722965, 24.25677014]), uv=np.array([0.23905009, 0.32345089]), UVW=np.array([32.11150701, 8.4025005, 60.51407102])), TCS_ColorimetryData( name='TCS02', XYZ=np.array([27.53323581, 28.90793444, 14.76248032]), uv=np.array([0.21789532, 0.34316182]), UVW=np.array([15.26809231, 23.59761128, 59.72655443])), TCS_ColorimetryData( name='TCS03', XYZ=np.array([23.95435019, 30.44568852, 9.80615507]), uv=np.array([0.18785584, 0.35814374]), UVW=np.array([-8.23625903, 36.01892099, 61.06360597])), TCS_ColorimetryData( name='TCS04', XYZ=np.array([20.43638681, 29.46870454, 21.05101191]), uv=np.array([0.15552214, 0.33638794]), UVW=np.array([-33.43495759, 18.48941724, 60.21950681])), TCS_ColorimetryData( name='TCS05', XYZ=np.array([24.95728556, 30.82110743, 39.94366077]), uv=np.array([0.16443476, 0.30460412]), UVW=np.array([-26.96894169, -6.51619473, 61.38315768])), TCS_ColorimetryData( name='TCS06', XYZ=np.array([28.15012994, 29.75806707, 57.21213255]), uv=np.array([0.17426171, 0.27632333]), UVW=np.array([-18.84311713, -28.6517426, 60.4714316])), TCS_ColorimetryData( name='TCS07', XYZ=np.array([33.29875981, 29.36956806, 52.57688943]), uv=np.array([0.21089415, 0.27901355]), UVW=np.array([9.89894512, -26.38829247, 60.13281743])), TCS_ColorimetryData( name='TCS08', XYZ=np.array([37.64824851, 31.35309879, 44.88145951]), uv=np.array([0.23435348, 0.29275098]), UVW=np.array([29.03544464, -16.09146766, 61.83156811])), TCS_ColorimetryData( name='TCS09', XYZ=np.array([20.68888349, 11.28578196, 4.29031293]), uv=np.array([0.40797112, 0.33382225]), UVW=np.array([106.54776544, 10.69454868, 39.07688665])), TCS_ColorimetryData( name='TCS10', XYZ=np.array([55.03120276, 59.04411929, 11.87116937]), uv=np.array([0.22546691, 0.36286219]), UVW=np.array([28.44874091, 52.32328834, 80.34916371])), TCS_ColorimetryData( name='TCS11', XYZ=np.array([12.13121967, 20.3541437, 15.18142797]), uv=np.array([0.1336819, 0.33644357]), UVW=np.array([-43.01323833, 15.77519367, 51.25863839])), TCS_ColorimetryData( name='TCS12', XYZ=np.array([6.19245638, 6.41273455, 27.30815071]), uv=np.array([0.13439371, 0.20876154]), UVW=np.array([-24.4374163, -39.8151001, 29.44665364])), TCS_ColorimetryData( name='TCS13', XYZ=np.array([58.97285728, 57.14500933, 40.86401249]), uv=np.array([0.22709381, 0.33008264]), UVW=np.array([29.75220364, 17.84629845, 79.29404816])), TCS_ColorimetryData( name='TCS14', XYZ=np.array([9.34392028, 11.70931454, 5.33816006]), uv=np.array([0.1859504, 0.34953505]), UVW=np.array([-6.3492713, 19.0078073, 39.7697741])) ])) specification_t = colour_rendering_index( ILLUMINANTS_SDS['FL1'], additional_data=True) np.testing.assert_almost_equal( [ data.Q_a for _index, data in sorted(specification_r.Q_as.items()) ], [ data.Q_a for _index, data in sorted(specification_t.Q_as.items()) ], decimal=7, )