Skip to content

shapes

sleap_io.rendering.shapes

Marker shape drawing functions for pose rendering.

This module provides functions to draw different marker shapes at keypoint locations using Skia.

Functions:

Name Description
draw_circle_marker

Draw a filled circle marker, optionally with edge.

draw_cross_marker

Draw a cross/plus marker.

draw_diamond_marker

Draw a diamond (rotated square) marker.

draw_square_marker

Draw a filled square marker, optionally with edge.

draw_triangle_marker

Draw a triangle marker (pointing up).

get_marker_func

Get the drawing function for a marker shape.

Attributes:

Name Type Description
MARKER_FUNCS

dict() -> new empty dictionary

TYPE_CHECKING

Returns True when the argument is true, False otherwise.

__annotations__

dict() -> new empty dictionary

__cached__

str(object='') -> str

__doc__

str(object='') -> str

__file__

str(object='') -> str

__name__

str(object='') -> str

__package__

str(object='') -> str

MARKER_FUNCS = {'circle': <function draw_circle_marker at 0x7f08369149a0>, 'square': <function draw_square_marker at 0x7f0836914a40>, 'diamond': <function draw_diamond_marker at 0x7f0836914ae0>, 'triangle': <function draw_triangle_marker at 0x7f0836914b80>, 'cross': <function draw_cross_marker at 0x7f0836914c20>} module-attribute

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

TYPE_CHECKING = False module-attribute

Returns True when the argument is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

__annotations__ = {'MARKER_FUNCS': "dict[MarkerShape, Callable[['skia.Canvas', float, float, float, 'skia.Paint', 'skia.Paint | None'], None]]"} module-attribute

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

__cached__ = '/home/runner/work/sleap-io/sleap-io/sleap_io/rendering/__pycache__/shapes.cpython-313.pyc' module-attribute

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__doc__ = 'Marker shape drawing functions for pose rendering.\n\nThis module provides functions to draw different marker shapes at keypoint\nlocations using Skia.\n' module-attribute

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__file__ = '/home/runner/work/sleap-io/sleap-io/sleap_io/rendering/shapes.py' module-attribute

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__name__ = 'sleap_io.rendering.shapes' module-attribute

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__package__ = 'sleap_io.rendering' module-attribute

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

draw_circle_marker(canvas, x, y, size, fill_paint, edge_paint=None)

Draw a filled circle marker, optionally with edge.

Parameters:

Name Type Description Default
canvas Canvas

Skia canvas to draw on.

required
x float

X coordinate of marker center.

required
y float

Y coordinate of marker center.

required
size float

Marker radius in pixels.

required
fill_paint Paint

Paint for filling the marker.

required
edge_paint Paint | None

Optional paint for drawing marker edge/stroke.

None
Source code in sleap_io/rendering/shapes.py
def draw_circle_marker(
    canvas: "skia.Canvas",
    x: float,
    y: float,
    size: float,
    fill_paint: "skia.Paint",
    edge_paint: "skia.Paint | None" = None,
) -> None:
    """Draw a filled circle marker, optionally with edge.

    Args:
        canvas: Skia canvas to draw on.
        x: X coordinate of marker center.
        y: Y coordinate of marker center.
        size: Marker radius in pixels.
        fill_paint: Paint for filling the marker.
        edge_paint: Optional paint for drawing marker edge/stroke.
    """
    canvas.drawCircle(float(x), float(y), size, fill_paint)
    if edge_paint is not None:
        canvas.drawCircle(float(x), float(y), size, edge_paint)

draw_cross_marker(canvas, x, y, size, fill_paint, edge_paint=None)

Draw a cross/plus marker.

Parameters:

Name Type Description Default
canvas Canvas

Skia canvas to draw on.

required
x float

X coordinate of marker center.

required
y float

Y coordinate of marker center.

required
size float

Half-length of cross arms in pixels.

required
fill_paint Paint

Paint for filling the marker.

required
edge_paint Paint | None

Ignored for cross markers.

None
Source code in sleap_io/rendering/shapes.py
def draw_cross_marker(
    canvas: "skia.Canvas",
    x: float,
    y: float,
    size: float,
    fill_paint: "skia.Paint",
    edge_paint: "skia.Paint | None" = None,
) -> None:
    """Draw a cross/plus marker.

    Args:
        canvas: Skia canvas to draw on.
        x: X coordinate of marker center.
        y: Y coordinate of marker center.
        size: Half-length of cross arms in pixels.
        fill_paint: Paint for filling the marker.
        edge_paint: Ignored for cross markers.
    """
    import skia

    # Use stroke style for cross (extracting color from fill_paint)
    cross_paint = skia.Paint(
        Color=fill_paint.getColor(),
        AntiAlias=True,
        Style=skia.Paint.kStroke_Style,
        StrokeWidth=size * 0.4,
        StrokeCap=skia.Paint.kRound_Cap,
    )
    canvas.drawLine(float(x) - size, float(y), float(x) + size, float(y), cross_paint)
    canvas.drawLine(float(x), float(y) - size, float(x), float(y) + size, cross_paint)

draw_diamond_marker(canvas, x, y, size, fill_paint, edge_paint=None)

Draw a diamond (rotated square) marker.

Parameters:

Name Type Description Default
canvas Canvas

Skia canvas to draw on.

required
x float

X coordinate of marker center.

required
y float

Y coordinate of marker center.

required
size float

Distance from center to vertices in pixels.

required
fill_paint Paint

Paint for filling the marker.

required
edge_paint Paint | None

Optional paint for drawing marker edge/stroke.

None
Source code in sleap_io/rendering/shapes.py
def draw_diamond_marker(
    canvas: "skia.Canvas",
    x: float,
    y: float,
    size: float,
    fill_paint: "skia.Paint",
    edge_paint: "skia.Paint | None" = None,
) -> None:
    """Draw a diamond (rotated square) marker.

    Args:
        canvas: Skia canvas to draw on.
        x: X coordinate of marker center.
        y: Y coordinate of marker center.
        size: Distance from center to vertices in pixels.
        fill_paint: Paint for filling the marker.
        edge_paint: Optional paint for drawing marker edge/stroke.
    """
    import skia

    path = skia.Path()
    path.moveTo(float(x), float(y) - size)  # Top
    path.lineTo(float(x) + size, float(y))  # Right
    path.lineTo(float(x), float(y) + size)  # Bottom
    path.lineTo(float(x) - size, float(y))  # Left
    path.close()
    canvas.drawPath(path, fill_paint)
    if edge_paint is not None:
        canvas.drawPath(path, edge_paint)

draw_square_marker(canvas, x, y, size, fill_paint, edge_paint=None)

Draw a filled square marker, optionally with edge.

Parameters:

Name Type Description Default
canvas Canvas

Skia canvas to draw on.

required
x float

X coordinate of marker center.

required
y float

Y coordinate of marker center.

required
size float

Half-width of square in pixels.

required
fill_paint Paint

Paint for filling the marker.

required
edge_paint Paint | None

Optional paint for drawing marker edge/stroke.

None
Source code in sleap_io/rendering/shapes.py
def draw_square_marker(
    canvas: "skia.Canvas",
    x: float,
    y: float,
    size: float,
    fill_paint: "skia.Paint",
    edge_paint: "skia.Paint | None" = None,
) -> None:
    """Draw a filled square marker, optionally with edge.

    Args:
        canvas: Skia canvas to draw on.
        x: X coordinate of marker center.
        y: Y coordinate of marker center.
        size: Half-width of square in pixels.
        fill_paint: Paint for filling the marker.
        edge_paint: Optional paint for drawing marker edge/stroke.
    """
    import skia

    half = size
    rect = skia.Rect(float(x) - half, float(y) - half, float(x) + half, float(y) + half)
    canvas.drawRect(rect, fill_paint)
    if edge_paint is not None:
        canvas.drawRect(rect, edge_paint)

draw_triangle_marker(canvas, x, y, size, fill_paint, edge_paint=None)

Draw a triangle marker (pointing up).

Parameters:

Name Type Description Default
canvas Canvas

Skia canvas to draw on.

required
x float

X coordinate of marker center.

required
y float

Y coordinate of marker center.

required
size float

Size scale for the triangle in pixels.

required
fill_paint Paint

Paint for filling the marker.

required
edge_paint Paint | None

Optional paint for drawing marker edge/stroke.

None
Source code in sleap_io/rendering/shapes.py
def draw_triangle_marker(
    canvas: "skia.Canvas",
    x: float,
    y: float,
    size: float,
    fill_paint: "skia.Paint",
    edge_paint: "skia.Paint | None" = None,
) -> None:
    """Draw a triangle marker (pointing up).

    Args:
        canvas: Skia canvas to draw on.
        x: X coordinate of marker center.
        y: Y coordinate of marker center.
        size: Size scale for the triangle in pixels.
        fill_paint: Paint for filling the marker.
        edge_paint: Optional paint for drawing marker edge/stroke.
    """
    import skia

    path = skia.Path()
    # Equilateral triangle centered at (x, y)
    h = size * 1.5  # Height
    path.moveTo(float(x), float(y) - h * 0.6)  # Top
    path.lineTo(float(x) + size, float(y) + h * 0.4)  # Bottom right
    path.lineTo(float(x) - size, float(y) + h * 0.4)  # Bottom left
    path.close()
    canvas.drawPath(path, fill_paint)
    if edge_paint is not None:
        canvas.drawPath(path, edge_paint)

get_marker_func(shape)

Get the drawing function for a marker shape.

Parameters:

Name Type Description Default
shape Literal

Marker shape name.

required

Returns:

Type Description
Callable[[Canvas, float, float, float, Paint, Paint | None], None]

Drawing function for the specified shape.

Raises:

Type Description
ValueError

If shape is not recognized.

Source code in sleap_io/rendering/shapes.py
def get_marker_func(
    shape: MarkerShape,
) -> Callable[
    [
        "skia.Canvas",
        float,
        float,
        float,
        "skia.Paint",
        "skia.Paint | None",
    ],
    None,
]:
    """Get the drawing function for a marker shape.

    Args:
        shape: Marker shape name.

    Returns:
        Drawing function for the specified shape.

    Raises:
        ValueError: If shape is not recognized.
    """
    if shape not in MARKER_FUNCS:
        raise ValueError(
            f"Unknown marker shape: {shape}. "
            f"Available shapes: {list(MARKER_FUNCS.keys())}"
        )
    return MARKER_FUNCS[shape]