• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

colour-science / colour / 25544858007

08 May 2026 08:12AM UTC coverage: 77.584% (-21.2%) from 98.818%
25544858007

push

github

KelSolaar
Implement support for *Python Array API Standard*.

14022 of 14574 new or added lines in 367 files covered. (96.21%)

10005 existing lines in 360 files now uncovered.

37920 of 48876 relevant lines covered (77.58%)

0.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.4
/colour/plotting/section.py
1
"""
2
Gamut Section Plotting
3
======================
4

5
Define the gamut section plotting objects.
6

7
-   :func:`colour.plotting.section.plot_hull_section_colours`
8
-   :func:`colour.plotting.section.plot_hull_section_contour`
9
-   :func:`colour.plotting.plot_visible_spectrum_section`
10
-   :func:`colour.plotting.plot_RGB_colourspace_section`
11
"""
12

UNCOV
13
from __future__ import annotations
×
14

UNCOV
15
import typing
×
16

UNCOV
17
import numpy as np
×
18

19
if typing.TYPE_CHECKING:
20
    from matplotlib.axes import Axes
21

UNCOV
22
from matplotlib.collections import LineCollection
×
23

24
if typing.TYPE_CHECKING:
25
    from matplotlib.figure import Figure
26

UNCOV
27
from matplotlib.patches import Polygon
×
28

UNCOV
29
from colour.colorimetry import (
×
30
    MultiSpectralDistributions,
31
    SpectralDistribution,
32
    SpectralShape,
33
    reshape_msds,
34
)
UNCOV
35
from colour.geometry import hull_section, primitive_cube
×
UNCOV
36
from colour.graph import colourspace_model_to_reference, convert
×
37

38
if typing.TYPE_CHECKING:
39
    from colour.hints import (
40
        Any,
41
        ArrayLike,
42
        Dict,
43
        Literal,
44
        LiteralColourspaceModel,
45
        LiteralRGBColourspace,
46
        Sequence,
47
        Tuple,
48
    )
49

UNCOV
50
from colour.hints import Real, cast
×
UNCOV
51
from colour.models import (
×
52
    COLOURSPACE_MODELS_AXIS_LABELS,
53
    RGB_Colourspace,
54
    RGB_to_XYZ,
55
)
UNCOV
56
from colour.notation import HEX_to_RGB
×
UNCOV
57
from colour.plotting import (
×
58
    CONSTANTS_COLOUR_STYLE,
59
    XYZ_to_plotting_colourspace,
60
    artist,
61
    colourspace_model_axis_reorder,
62
    filter_cmfs,
63
    filter_illuminants,
64
    filter_RGB_colourspaces,
65
    override_style,
66
    render,
67
)
UNCOV
68
from colour.utilities import (
×
69
    CanonicalMapping,
70
    as_int_array,
71
    first_item,
72
    full,
73
    ones,
74
    optional,
75
    required,
76
    suppress_warnings,
77
    tstack,
78
    validate_method,
79
)
UNCOV
80
from colour.volume import solid_RoschMacAdam
×
81

UNCOV
82
__author__ = "Colour Developers"
×
UNCOV
83
__copyright__ = "Copyright 2013 Colour Developers"
×
UNCOV
84
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
×
UNCOV
85
__maintainer__ = "Colour Developers"
×
UNCOV
86
__email__ = "colour-developers@colour-science.org"
×
UNCOV
87
__status__ = "Production"
×
88

UNCOV
89
__all__ = [
×
90
    "MAPPING_AXIS_TO_PLANE",
91
    "plot_hull_section_colours",
92
    "plot_hull_section_contour",
93
    "plot_visible_spectrum_section",
94
    "plot_RGB_colourspace_section",
95
]
96

UNCOV
97
MAPPING_AXIS_TO_PLANE: CanonicalMapping = CanonicalMapping(
×
98
    {"+x": (1, 2), "+y": (0, 2), "+z": (0, 1)}
99
)
UNCOV
100
MAPPING_AXIS_TO_PLANE.__doc__ = """
×
101
Mapping from axes to their orthogonal planes.
102

103
Maps each positive axis ('+x', '+y', '+z') to the indices of the two
104
dimensions that form the perpendicular plane in 3D space.
105
"""
106

107

UNCOV
108
@required("trimesh")
×
UNCOV
109
@override_style()
×
UNCOV
110
def plot_hull_section_colours(
×
111
    hull: trimesh.Trimesh,  # pyright: ignore  # noqa: F821
112
    model: LiteralColourspaceModel | str = "CIE xyY",
113
    axis: Literal["+z", "+x", "+y"] | str = "+z",
114
    origin: float = 0.5,
115
    normalise: bool = True,
116
    section_colours: ArrayLike | str | None = None,
117
    section_opacity: float = 1,
118
    convert_kwargs: dict | None = None,
119
    samples: int = 256,
120
    **kwargs: Any,
121
) -> Tuple[Figure, Axes]:
122
    """
123
    Plot the section colours of the specified *trimesh* hull along the
124
    specified axis and origin.
125

126
    Parameters
127
    ----------
128
    hull
129
        *Trimesh* hull.
130
    model
131
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute
132
        for the list of supported colourspace models.
133
    axis
134
        Axis the hull section will be normal to.
135
    origin
136
        Coordinate along ``axis`` at which to plot the hull section.
137
    normalise
138
        Whether to normalise ``axis`` to the extent of the hull along it.
139
    section_colours
140
        Colours of the hull section, if ``section_colours`` is set to *RGB*,
141
        the colours will be computed using the corresponding coordinates.
142
    section_opacity
143
        Opacity of the hull section colours.
144
    convert_kwargs
145
        Keyword arguments for the :func:`colour.convert` definition.
146
    samples
147
        Sample count on one axis when computing the hull section colours.
148

149
    Other Parameters
150
    ----------------
151
    kwargs
152
        {:func:`colour.plotting.artist`,
153
        :func:`colour.plotting.render`},
154
        See the documentation of the previously listed definitions.
155

156
    Returns
157
    -------
158
    :class:`tuple`
159
        Current figure and axes.
160

161
    Examples
162
    --------
163
    >>> from colour.models import RGB_COLOURSPACE_sRGB
164
    >>> from colour.utilities import is_trimesh_installed
165
    >>> vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
166
    >>> XYZ_vertices = RGB_to_XYZ(vertices["position"] + 0.5, RGB_COLOURSPACE_sRGB)
167
    >>> if is_trimesh_installed:
168
    ...     from trimesh import Trimesh
169
    ...
170
    ...     hull = Trimesh(XYZ_vertices, faces, process=False)
171
    ...     plot_hull_section_colours(hull, section_colours="RGB")
172
    ...     # doctest: +ELLIPSIS
173
    (<Figure size ... with 1 Axes>, <...Axes...>)
174

175
    .. image:: ../_static/Plotting_Plot_Hull_Section_Colours.png
176
        :align: center
177
        :alt: plot_hull_section_colours
178
    """
179

180
    axis = validate_method(
1✔
181
        axis,
182
        ("+z", "+x", "+y"),
183
        '"{0}" axis is invalid, it must be one of {1}!',
184
    )
185

186
    hull = hull.copy()
1✔
187

188
    settings: Dict[str, Any] = {"uniform": True}
1✔
189
    settings.update(kwargs)
1✔
190

191
    _figure, axes = artist(**settings)
1✔
192

193
    section_colours = optional(
1✔
194
        section_colours, HEX_to_RGB(CONSTANTS_COLOUR_STYLE.colour.average)
195
    )
196

197
    convert_kwargs = optional(convert_kwargs, {})
1✔
198

199
    # Luminance / Lightness reordered along "z" axis.
200
    with suppress_warnings(python_warnings=True):
1✔
201
        ijk_vertices = colourspace_model_axis_reorder(
1✔
202
            convert(hull.vertices, "CIE XYZ", model, **convert_kwargs), model
203
        )
204
        ijk_vertices = np.nan_to_num(ijk_vertices)
1✔
205
        ijk_vertices = colourspace_model_to_reference(ijk_vertices, model)
1✔
206

207
    hull.vertices = ijk_vertices
1✔
208

209
    if axis == "+x":
1✔
210
        index_origin = 0
1✔
211
    elif axis == "+y":
1✔
212
        index_origin = 1
1✔
213
    elif axis == "+z":
1✔
214
        index_origin = 2
1✔
215
    plane = MAPPING_AXIS_TO_PLANE[axis]
1✔
216

217
    section = hull_section(hull, axis, origin, normalise)
1✔
218

219
    padding = 0.1 * np.mean(colourspace_model_to_reference(ones(3), model))
1✔
220
    min_x = np.min(ijk_vertices[..., plane[0]]) - padding
1✔
221
    max_x = np.max(ijk_vertices[..., plane[0]]) + padding
1✔
222
    min_y = np.min(ijk_vertices[..., plane[1]]) - padding
1✔
223
    max_y = np.max(ijk_vertices[..., plane[1]]) + padding
1✔
224
    extent = (min_x, max_x, min_y, max_y)
1✔
225

226
    use_RGB_section_colours = str(section_colours).upper() == "RGB"
1✔
227
    if use_RGB_section_colours:
1✔
228
        ii, jj = np.meshgrid(
1✔
229
            np.linspace(min_x, max_x, samples),
230
            np.linspace(max_y, min_y, samples),
231
        )
232
        ij = tstack([ii, jj])
1✔
233
        ijk_section = full(
1✔
234
            (samples, samples, 3),
235
            cast("Real", np.median(section[..., index_origin])),
236
        )
237
        ijk_section[..., plane] = ij
1✔
238
        ijk_section = ijk_section / colourspace_model_to_reference(ones(3), model)
1✔
239
        XYZ_section = convert(
1✔
240
            colourspace_model_axis_reorder(ijk_section, model, "Inverse"),
241
            model,
242
            "CIE XYZ",
243
            **convert_kwargs,
244
        )
245
        RGB_section = XYZ_to_plotting_colourspace(XYZ_section)
1✔
246
    else:
247
        section_colours = np.hstack([section_colours, section_opacity])
1✔
248

249
    facecolor = "none" if use_RGB_section_colours else section_colours
1✔
250
    polygon = Polygon(
1✔
251
        section[..., plane],
252
        facecolor=facecolor,
253
        edgecolor="none",
254
        zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon,
255
    )
256
    axes.add_patch(polygon)
1✔
257

258
    if use_RGB_section_colours:
1✔
259
        image = axes.imshow(
1✔
260
            np.clip(RGB_section, 0, 1),
261
            interpolation="bilinear",
262
            extent=extent,  # type: ignore
263
            clip_path=None,
264
            alpha=section_opacity,
265
            zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon,
266
        )
267
        image.set_clip_path(polygon)
1✔
268

269
    settings = {
1✔
270
        "axes": axes,
271
        "bounding_box": extent,
272
    }
273
    settings.update(kwargs)
1✔
274

275
    return render(**settings)
1✔
276

277

UNCOV
278
@required("trimesh")
×
UNCOV
279
@override_style()
×
UNCOV
280
def plot_hull_section_contour(
×
281
    hull: trimesh.Trimesh,  # pyright: ignore  # noqa: F821
282
    model: LiteralColourspaceModel | str = "CIE xyY",
283
    axis: Literal["+z", "+x", "+y"] | str = "+z",
284
    origin: float = 0.5,
285
    normalise: bool = True,
286
    contour_colours: ArrayLike | str | None = None,
287
    contour_opacity: float = 1,
288
    convert_kwargs: dict | None = None,
289
    **kwargs: Any,
290
) -> Tuple[Figure, Axes]:
291
    """
292
    Plot the section contour of the specified *trimesh* hull along the
293
    specified axis and origin.
294

295
    Parameters
296
    ----------
297
    hull
298
        *Trimesh* hull.
299
    model
300
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute
301
        for the list of supported colourspace models.
302
    axis
303
        Axis the hull section will be normal to.
304
    origin
305
        Coordinate along ``axis`` at which to plot the hull section.
306
    normalise
307
        Whether to normalise ``axis`` to the extent of the hull along it.
308
    contour_colours
309
        Colours of the hull section contour, if ``contour_colours`` is set
310
        to *RGB*, the colours will be computed using the corresponding
311
        coordinates.
312
    contour_opacity
313
        Opacity of the hull section contour.
314
    convert_kwargs
315
        Keyword arguments for the :func:`colour.convert` definition.
316

317
    Other Parameters
318
    ----------------
319
    kwargs
320
        {:func:`colour.plotting.artist`,
321
        :func:`colour.plotting.render`},
322
        See the documentation of the previously listed definitions.
323

324
    Returns
325
    -------
326
    :class:`tuple`
327
        Current figure and axes.
328

329
    Examples
330
    --------
331
    >>> from colour.models import RGB_COLOURSPACE_sRGB
332
    >>> from colour.utilities import is_trimesh_installed
333
    >>> vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
334
    >>> XYZ_vertices = RGB_to_XYZ(vertices["position"] + 0.5, RGB_COLOURSPACE_sRGB)
335
    >>> if is_trimesh_installed:
336
    ...     from trimesh import Trimesh
337
    ...
338
    ...     hull = Trimesh(XYZ_vertices, faces, process=False)
339
    ...     plot_hull_section_contour(hull, contour_colours="RGB")
340
    ...     # doctest: +ELLIPSIS
341
    (<Figure size ... with 1 Axes>, <...Axes...>)
342

343
    .. image:: ../_static/Plotting_Plot_Hull_Section_Contour.png
344
        :align: center
345
        :alt: plot_hull_section_contour
346
    """
347

348
    hull = hull.copy()
1✔
349

350
    contour_colours = optional(contour_colours, CONSTANTS_COLOUR_STYLE.colour.dark)
1✔
351

352
    settings: Dict[str, Any] = {"uniform": True}
1✔
353
    settings.update(kwargs)
1✔
354

355
    _figure, axes = artist(**settings)
1✔
356

357
    convert_kwargs = optional(convert_kwargs, {})
1✔
358

359
    # Luminance / Lightness is re-ordered along "z-up" axis.
360
    with suppress_warnings(python_warnings=True):
1✔
361
        ijk_vertices = colourspace_model_axis_reorder(
1✔
362
            convert(hull.vertices, "CIE XYZ", model, **convert_kwargs), model
363
        )
364
        ijk_vertices = np.nan_to_num(ijk_vertices)
1✔
365
        ijk_vertices = colourspace_model_to_reference(ijk_vertices, model)
1✔
366

367
    hull.vertices = ijk_vertices
1✔
368

369
    plane = MAPPING_AXIS_TO_PLANE[axis]
1✔
370

371
    padding = 0.1 * np.mean(colourspace_model_to_reference(np.ones(3), model))
1✔
372
    min_x = np.min(ijk_vertices[..., plane[0]]) - padding
1✔
373
    max_x = np.max(ijk_vertices[..., plane[0]]) + padding
1✔
374
    min_y = np.min(ijk_vertices[..., plane[1]]) - padding
1✔
375
    max_y = np.max(ijk_vertices[..., plane[1]]) + padding
1✔
376
    extent = (min_x, max_x, min_y, max_y)
1✔
377

378
    use_RGB_contour_colours = str(contour_colours).upper() == "RGB"
1✔
379
    section = hull_section(hull, axis, origin, normalise)
1✔
380
    if use_RGB_contour_colours:
1✔
381
        ijk_section = section / colourspace_model_to_reference(np.ones(3), model)
1✔
382
        XYZ_section = convert(
1✔
383
            colourspace_model_axis_reorder(ijk_section, model, "Inverse"),
384
            model,
385
            "CIE XYZ",
386
            **convert_kwargs,
387
        )
388
        contour_colours = np.clip(XYZ_to_plotting_colourspace(XYZ_section), 0, 1)
1✔
389

390
    section = np.reshape(section[..., plane], (-1, 1, 2))
1✔
391
    line_collection = LineCollection(
1✔
392
        np.concatenate([section[:-1], section[1:]], axis=1),  # pyright: ignore
393
        colors=contour_colours,
394
        alpha=contour_opacity,
395
        zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line,
396
    )
397
    axes.add_collection(line_collection)
1✔
398

399
    settings = {
1✔
400
        "axes": axes,
401
        "bounding_box": extent,
402
    }
403
    settings.update(kwargs)
1✔
404

405
    return render(**settings)
1✔
406

407

UNCOV
408
@required("trimesh")
×
UNCOV
409
@override_style()
×
UNCOV
410
def plot_visible_spectrum_section(
×
411
    cmfs: (
412
        MultiSpectralDistributions | str | Sequence[MultiSpectralDistributions | str]
413
    ) = "CIE 1931 2 Degree Standard Observer",
414
    illuminant: SpectralDistribution | str = "D65",
415
    model: LiteralColourspaceModel | str = "CIE xyY",
416
    axis: Literal["+z", "+x", "+y"] | str = "+z",
417
    origin: float = 0.5,
418
    normalise: bool = True,
419
    show_section_colours: bool = True,
420
    show_section_contour: bool = True,
421
    **kwargs: Any,
422
) -> Tuple[Figure, Axes]:
423
    """
424
    Plot the visible spectrum volume section colours along the specified axis
425
    and origin.
426

427
    The visible spectrum volume represents the *Rösch-MacAdam* colour solid.
428

429
    Parameters
430
    ----------
431
    cmfs
432
        Standard observer colour matching functions, default to the
433
        *CIE 1931 2 Degree Standard Observer*.  ``cmfs`` can be of any type
434
        or form supported by the :func:`colour.plotting.common.filter_cmfs`
435
        definition.
436
    illuminant
437
        Illuminant spectral distribution, default to *CIE Illuminant D65*.
438
        ``illuminant`` can be of any type or form supported by the
439
        :func:`colour.plotting.common.filter_illuminants` definition.
440
    model
441
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute
442
        for the list of supported colourspace models.
443
    axis
444
        Axis the hull section will be normal to.
445
    origin
446
        Coordinate along ``axis`` at which to plot the hull section.
447
    normalise
448
        Whether to normalise ``axis`` to the extent of the hull along it.
449
    show_section_colours
450
        Whether to show the hull section colours.
451
    show_section_contour
452
        Whether to show the hull section contour.
453

454
    Other Parameters
455
    ----------------
456
    kwargs
457
        {:func:`colour.plotting.artist`,
458
        :func:`colour.plotting.render`,
459
        :func:`colour.plotting.section.plot_hull_section_colours`
460
        :func:`colour.plotting.section.plot_hull_section_contour`},
461
        See the documentation of the previously listed definitions.
462

463
    Returns
464
    -------
465
    :class:`tuple`
466
        Current figure and axes.
467

468
    Examples
469
    --------
470
    >>> from colour.utilities import is_trimesh_installed
471
    >>> if is_trimesh_installed:
472
    ...     plot_visible_spectrum_section(section_colours="RGB", section_opacity=0.15)
473
    ...     # doctest: +ELLIPSIS
474
    (<Figure size ... with 1 Axes>, <...Axes...>)
475

476
    .. image:: ../_static/Plotting_Plot_Visible_Spectrum_Section.png
477
        :align: center
478
        :alt: plot_visible_spectrum_section
479
    """
480

481
    import trimesh.convex  # noqa: PLC0415
1✔
482
    from trimesh import Trimesh  # noqa: PLC0415
1✔
483

484
    settings: Dict[str, Any] = {"uniform": True}
1✔
485
    settings.update(kwargs)
1✔
486

487
    _figure, axes = artist(**settings)
1✔
488

489
    cmfs = cast(
1✔
490
        "MultiSpectralDistributions",
491
        reshape_msds(
492
            first_item(filter_cmfs(cmfs).values()),
493
            SpectralShape(360, 780, 1),
494
            copy=False,
495
        ),
496
    )
497
    illuminant = cast(
1✔
498
        "SpectralDistribution",
499
        first_item(filter_illuminants(illuminant).values()),
500
    )
501

502
    vertices = solid_RoschMacAdam(
1✔
503
        cmfs,
504
        illuminant,
505
        point_order="Pulse Wave Width",
506
        filter_jagged_points=True,
507
    )
508
    mesh = Trimesh(vertices)
1✔
509
    hull = trimesh.convex.convex_hull(mesh)
1✔
510

511
    if show_section_colours:
1✔
512
        settings = {"axes": axes}
1✔
513
        settings.update(kwargs)
1✔
514
        settings["show"] = False
1✔
515

516
        plot_hull_section_colours(hull, model, axis, origin, normalise, **settings)
1✔
517

518
    if show_section_contour:
1✔
519
        settings = {"axes": axes}
1✔
520
        settings.update(kwargs)
1✔
521
        settings["show"] = False
1✔
522

523
        plot_hull_section_contour(hull, model, axis, origin, normalise, **settings)
1✔
524

525
    title = (
1✔
526
        f"Visible Spectrum Section - "
527
        f"{f'{origin * 100}%' if normalise else origin} - "
528
        f"{model} - "
529
        f"{cmfs.display_name}"
530
    )
531

532
    plane = MAPPING_AXIS_TO_PLANE[axis]
1✔
533

534
    labels = np.array(COLOURSPACE_MODELS_AXIS_LABELS[model])[
1✔
535
        as_int_array(colourspace_model_axis_reorder([0, 1, 2], model))
536
    ]
537
    x_label, y_label = labels[plane[0]], labels[plane[1]]
1✔
538

539
    settings.update(
1✔
540
        {
541
            "axes": axes,
542
            "show": True,
543
            "title": title,
544
            "x_label": x_label,
545
            "y_label": y_label,
546
        }
547
    )
548
    settings.update(kwargs)
1✔
549

550
    return render(**settings)
1✔
551

552

UNCOV
553
@required("trimesh")
×
UNCOV
554
@override_style()
×
UNCOV
555
def plot_RGB_colourspace_section(
×
556
    colourspace: (
557
        RGB_Colourspace
558
        | LiteralRGBColourspace
559
        | str
560
        | Sequence[RGB_Colourspace | LiteralRGBColourspace | str]
561
    ),
562
    model: LiteralColourspaceModel | str = "CIE xyY",
563
    axis: Literal["+z", "+x", "+y"] | str = "+z",
564
    origin: float = 0.5,
565
    normalise: bool = True,
566
    size: float = 1.0,
567
    show_section_colours: bool = True,
568
    show_section_contour: bool = True,
569
    segments: int = 64,
570
    **kwargs: Any,
571
) -> Tuple[Figure, Axes]:
572
    """
573
    Plot the specified *RGB* colourspace section colours along the
574
    specified axis and origin.
575

576
    Parameters
577
    ----------
578
    colourspace
579
        *RGB* colourspace of the *RGB* array. ``colourspace`` can be of
580
        any type or form supported by the
581
        :func:`colour.plotting.common.filter_RGB_colourspaces`
582
        definition.
583
    model
584
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS`
585
        attribute for the list of supported colourspace models.
586
    axis
587
        Axis the hull section will be normal to.
588
    origin
589
        Coordinate along ``axis`` at which to plot the hull section.
590
    normalise
591
        Whether to normalise ``axis`` to the extent of the hull along
592
        it.
593
    size:
594
        Size of the underlying *RGB* colourspace cube; used for plotting
595
        HDR related sections.
596
    show_section_colours
597
        Whether to show the hull section colours.
598
    show_section_contour
599
        Whether to show the hull section contour.
600
    segments
601
        Edge segments count for the *RGB* colourspace cube.
602

603
    Other Parameters
604
    ----------------
605
    kwargs
606
        {:func:`colour.plotting.artist`,
607
        :func:`colour.plotting.render`,
608
        :func:`colour.plotting.section.plot_hull_section_colours`
609
        :func:`colour.plotting.section.plot_hull_section_contour`},
610
        See the documentation of the previously listed definitions.
611

612
    Returns
613
    -------
614
    :class:`tuple`
615
        Current figure and axes.
616

617
    Examples
618
    --------
619
    >>> from colour.utilities import is_trimesh_installed
620
    >>> if is_trimesh_installed:
621
    ...     plot_RGB_colourspace_section(
622
    ...         "sRGB", section_colours="RGB", section_opacity=0.15
623
    ...     )
624
    ...     # doctest: +ELLIPSIS
625
    (<Figure size ... with 1 Axes>, <...Axes...>)
626

627
    .. image:: ../_static/Plotting_Plot_RGB_Colourspace_Section.png
628
        :align: center
629
        :alt: plot_RGB_colourspace_section
630
    """
631

632
    from trimesh import Trimesh  # noqa: PLC0415
1✔
633

634
    settings: Dict[str, Any] = {"uniform": True}
1✔
635
    settings.update(kwargs)
1✔
636

637
    _figure, axes = artist(**settings)
1✔
638

639
    colourspace = cast(
1✔
640
        "RGB_Colourspace",
641
        first_item(filter_RGB_colourspaces(colourspace).values()),
642
    )
643

644
    vertices, faces, _outline = primitive_cube(1, 1, 1, segments, segments, segments)
1✔
645
    XYZ_vertices = RGB_to_XYZ((vertices["position"] + 0.5) * size, colourspace)
1✔
646
    hull = Trimesh(XYZ_vertices, faces, process=False)
1✔
647

648
    if show_section_colours:
1✔
649
        settings = {"axes": axes}
1✔
650
        settings.update(kwargs)
1✔
651
        settings["show"] = False
1✔
652

653
        plot_hull_section_colours(hull, model, axis, origin, normalise, **settings)
1✔
654

655
    if show_section_contour:
1✔
656
        settings = {"axes": axes}
1✔
657
        settings.update(kwargs)
1✔
658
        settings["show"] = False
1✔
659

660
        plot_hull_section_contour(hull, model, axis, origin, normalise, **settings)
1✔
661

662
    title = (
1✔
663
        f"{colourspace.name} Section - "
664
        f"{f'{origin * 100}%' if normalise else origin} - "
665
        f"{model}"
666
    )
667

668
    plane = MAPPING_AXIS_TO_PLANE[axis]
1✔
669

670
    labels = np.array(COLOURSPACE_MODELS_AXIS_LABELS[model])[
1✔
671
        as_int_array(colourspace_model_axis_reorder([0, 1, 2], model))
672
    ]
673
    x_label, y_label = labels[plane[0]], labels[plane[1]]
1✔
674

675
    settings.update(
1✔
676
        {
677
            "axes": axes,
678
            "show": True,
679
            "title": title,
680
            "x_label": x_label,
681
            "y_label": y_label,
682
        }
683
    )
684
    settings.update(kwargs)
1✔
685

686
    return render(**settings)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc