bencher.results.manim_cartesian.cartesian_product_scene

Dimensional extrusion animation, drawn as an animated SVG.

Shows how each dimension builds on the last:

point –dim1–> line –dim2–> grid –dim3–> stack –repeat–> extrude –over_time–> film strip –dim4+–> sets of sets …

Each frame is drawn as vector markup; repeated sub-shapes are defined once and reused, and a SMIL <animate> per frame plays them in a loop (see svg_canvas).

Attributes

logger

STACK_DIM

FLASH_WASH_THRESHOLD

CELL_SIZE

CELL_GAP

DIM_PALETTE

CELL_BORDER

BG_COLOR

LABEL_COLOR

DEPTH_DX

DEPTH_DY

GROUP_GAP

GAP

FILM_COLOR

FILM_EDGE

FILM_FRAME_BORDER

FILM_LABEL_COLOR

FILM_PAD

FILM_FRAME_PAD

FILM_FRAME_GAP

FILM_SPROCKET_W

FILM_SPROCKET_H

FILM_SPROCKET_SPACING

FILM_SPROCKET_MARGIN

FILM_LABEL_H

FILM_LABEL_SIZE

Classes

Shape

Recursive shape representation for dimensional extrusion.

Cell

A single leaf square, coloured by palette index.

Group

One or more sub-shapes laid out along direction.

TimelineShape

Film-strip timeline for the over_time dimension.

StrobeShape

Shape with a glowing border and tally-mark counter.

Functions

_fit_scale(shape, target_w, target_h) → float

Scale that fits shape inside target_w x target_h, never enlarging it.

place_shape(canvas, shape, x, y[, alpha, scale]) → None

Draw shape at (x, y) as a shared definition, so identical copies cost one <use>.

_generate_unique_filename(cfg, width, height, fps, ...) → str

Generate a filename that differs whenever the drawing does.

_direction_for(dim_index) → str

Map dimension index to layout direction.

render_animation(cfg[, width, height, fps, ...]) → str

Render the dimensional extrusion animation.

Module Contents

bencher.results.manim_cartesian.cartesian_product_scene.logger
bencher.results.manim_cartesian.cartesian_product_scene.STACK_DIM = 2
bencher.results.manim_cartesian.cartesian_product_scene.FLASH_WASH_THRESHOLD = 0.3
bencher.results.manim_cartesian.cartesian_product_scene.CELL_SIZE = 20
bencher.results.manim_cartesian.cartesian_product_scene.CELL_GAP = 3
bencher.results.manim_cartesian.cartesian_product_scene.DIM_PALETTE = [(150, 190, 240), (240, 160, 155), (150, 220, 160), (245, 225, 140), (220, 170, 235), (245, 200,...
bencher.results.manim_cartesian.cartesian_product_scene.CELL_BORDER = (180, 180, 180)
bencher.results.manim_cartesian.cartesian_product_scene.BG_COLOR = (255, 255, 255)
bencher.results.manim_cartesian.cartesian_product_scene.LABEL_COLOR = (30, 30, 30)
bencher.results.manim_cartesian.cartesian_product_scene.DEPTH_DX = 10
bencher.results.manim_cartesian.cartesian_product_scene.DEPTH_DY = -8
bencher.results.manim_cartesian.cartesian_product_scene.GROUP_GAP = 20
bencher.results.manim_cartesian.cartesian_product_scene.GAP = '...'
bencher.results.manim_cartesian.cartesian_product_scene._fit_scale(shape: Shape, target_w: int, target_h: int) → float

Scale that fits shape inside target_w x target_h, never enlarging it.

bencher.results.manim_cartesian.cartesian_product_scene.place_shape(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, shape: Shape, x: float, y: float, alpha: float = 1.0, scale: float = 1.0) → None

Draw shape at (x, y) as a shared definition, so identical copies cost one <use>.

bencher.results.manim_cartesian.cartesian_product_scene._generate_unique_filename(cfg: bencher.results.manim_cartesian.cartesian_product_cfg.CartesianProductCfg, width: int, height: int, fps: int, step_frames: int) → str

Generate a filename that differs whenever the drawing does.

The names and value counts keep it readable. The digest covers everything that changes the drawing – the count of real (non-gap) values, the timing and the strobe tunables – so two different animations never share a path or the id prefix derived from it. It leaves out the values themselves, which are not drawn and whose repr may hold a memory address.

class bencher.results.manim_cartesian.cartesian_product_scene.Shape(depth: int = 0)

Bases: abc.ABC

Recursive shape representation for dimensional extrusion.

A Shape is either a Cell (one leaf square) or a Group of sub-shapes arranged along an axis. depth tracks nesting level so that higher-dimensional extrusions use wider gaps.

This was one concrete class with children: list[Shape] | None, where None meant leaf (plan 23 P12b). The docstring already said “either … or”, but the encoding did not: Shape(children=[]) was constructible and died inside max() on an empty sequence, is_leaf was a predicate no checker could narrow through, and every self.children read in a non-leaf branch was statically an optional. The two arms are now two classes, so the leaf branches disappear from the group code instead of being re-tested in each method.

depth = 0
property is_leaf: bool
property gap: int

Gap between children.

Depth 0-2 (first two spatial dims forming the basic grid): tight CELL_GAP. Depth 3 (stack direction): uses isometric offset, gap not used. Depth 4+ (sets of stacks, sets of sets): GROUP_GAP scaling with depth.

abstractmethod size() → tuple[int, int]

Return (width, height) in pixels.

abstractmethod draw(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int, alpha: float = 1.0) → None

Draw this shape at position (x, y) on the canvas.

abstractmethod key() → str

Name this shape by what it draws: equal keys draw identical markup.

The SVG writer defines each key once and reuses it, which is what keeps an extrusion of N identical copies at one definition plus N <use> lines.

abstractmethod deep_copy() → Shape
abstractmethod deep_copy_recolored(color_index: int) → Shape

Copy and recolor in a single traversal.

extrude(n: int, direction: str, color_index: int | None = None, fade_span: int | None = None) → Group

Create a new shape by extruding this one n times along direction.

class bencher.results.manim_cartesian.cartesian_product_scene.Cell(color_index: int = 0, depth: int = 0)

Bases: Shape

A single leaf square, coloured by palette index.

color_index = 0
size() → tuple[int, int]

Return (width, height) in pixels.

draw(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int, alpha: float = 1.0) → None

Draw this shape at position (x, y) on the canvas.

key() → str

Name this shape by what it draws: equal keys draw identical markup.

The SVG writer defines each key once and reuses it, which is what keeps an extrusion of N identical copies at one definition plus N <use> lines.

deep_copy() → Cell
deep_copy_recolored(color_index: int) → Cell

Copy and recolor in a single traversal.

class bencher.results.manim_cartesian.cartesian_product_scene.Group(children: list[Shape], direction: str = 'right', depth: int = 0, fade_span: int | None = None)

Bases: Shape

One or more sub-shapes laid out along direction.

children must be non-empty: every layout below indexes or reduces over it, and a group of nothing is not a shape this animation can draw. Rejecting it here is what the old children=[] spelling deferred to a bare max() on an empty sequence, several frames into a render.

children
direction = 'right'
fade_span
_cached_size: tuple[int, int] | None = None
_cached_key: str | None = None
size() → tuple[int, int]

Return (width, height) in pixels. Cached — tree structure is immutable.

draw(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int, alpha: float = 1.0) → None

Draw this shape at position (x, y) on the canvas.

key() → str

Cached like size(): the tree is immutable once built.

deep_copy() → Group
deep_copy_recolored(color_index: int) → Group

Copy and recolor in a single traversal.

bencher.results.manim_cartesian.cartesian_product_scene._direction_for(dim_index: int) → str

Map dimension index to layout direction.

bencher.results.manim_cartesian.cartesian_product_scene.FILM_COLOR = (35, 35, 38)
bencher.results.manim_cartesian.cartesian_product_scene.FILM_EDGE = (25, 25, 28)
bencher.results.manim_cartesian.cartesian_product_scene.FILM_FRAME_BORDER = (90, 90, 95)
bencher.results.manim_cartesian.cartesian_product_scene.FILM_LABEL_COLOR = (100, 100, 100)
bencher.results.manim_cartesian.cartesian_product_scene.FILM_PAD = 6
bencher.results.manim_cartesian.cartesian_product_scene.FILM_FRAME_PAD = 10
bencher.results.manim_cartesian.cartesian_product_scene.FILM_FRAME_GAP = 16
bencher.results.manim_cartesian.cartesian_product_scene.FILM_SPROCKET_W = 8
bencher.results.manim_cartesian.cartesian_product_scene.FILM_SPROCKET_H = 14
bencher.results.manim_cartesian.cartesian_product_scene.FILM_SPROCKET_SPACING = 14
bencher.results.manim_cartesian.cartesian_product_scene.FILM_SPROCKET_MARGIN = 4
bencher.results.manim_cartesian.cartesian_product_scene.FILM_LABEL_H = 18
bencher.results.manim_cartesian.cartesian_product_scene.FILM_LABEL_SIZE = 12
class bencher.results.manim_cartesian.cartesian_product_scene.TimelineShape(inner: Shape, count: int)

Bases: Shape

Film-strip timeline for the over_time dimension.

Each time step is a “frame” in a horizontal film strip with sprocket holes along top and bottom edges — unmistakably film.

The film chrome (sprockets, borders, padding) is always rendered at a fixed pixel size. The inner shape is scaled to fit within a constant frame window so the strip looks the same regardless of content complexity.

FRAME_W = 100
FRAME_H = 80
inner
count
_skip_labels = False
_outer_frame_size() → tuple[int, int]

Size of each frame including padding.

size() → tuple[int, int]

Return (width, height) in pixels.

draw(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int, alpha: float = 1.0) → None

Draw this shape at position (x, y) on the canvas.

static _draw_sprockets(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, strip_x: int, row_y: int, strip_w: int) → None

Draw a row of sprocket holes across the strip width.

The row is one thick dashed line – each dash is a hole – rather than one rectangle per hole: a 30-step strip has hundreds of holes per row.

strip_size() → tuple[int, int]

Size of the film strip excluding the label row below.

draw_without_labels(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int) → None

Draw the film strip without frame labels, preserving previous state.

draw_strip(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: float, y: float, v_scale: float = 1.0) → None

Draw the strip (without labels) at (x, y), uniformly scaled by v_scale.

v_scale is typically chosen to fit the canvas height; whatever runs past the canvas edge is clipped by the SVG viewport.

draw_label_overlay_for_viewport(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, strip_x: int, strip_y: int, strip_h: int, scale: float, canvas_w: int) → None

Draw frame labels at fixed pixel size for frames visible on canvas.

key() → str

Name this shape by what it draws: equal keys draw identical markup.

The SVG writer defines each key once and reuses it, which is what keeps an extrusion of N identical copies at one definition plus N <use> lines.

deep_copy() → TimelineShape
deep_copy_recolored(color_index: int) → TimelineShape

Copy and recolor in a single traversal.

class bencher.results.manim_cartesian.cartesian_product_scene.StrobeShape(inner: Shape, count: int, cfg: bencher.results.manim_cartesian.cartesian_product_cfg.CartesianProductCfg, flash: float = 0.0)

Bases: Shape

Shape with a glowing border and tally-mark counter.

flash (0-1) controls the glow intensity for animation frames. All visual tunables are read from cfg (a CartesianProductCfg).

inner
count
cfg
flash = 0.0
_skip_tally = False
size() → tuple[int, int]

Return (width, height) in pixels.

draw(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int, alpha: float = 1.0) → None

Draw this shape at position (x, y) on the canvas.

_draw_tally(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, mx0: int, my: int, avail_w: int, color: tuple[int, ...], c: bencher.results.manim_cartesian.cartesian_product_cfg.CartesianProductCfg) → None

Proper tally marks (vertical lines, diagonal strike every 5) + xN label.

Tallies grow from the left. The xN number is always on the right. Only draws as many complete groups/marks as fit cleanly; the label alone conveys the count when space is tight.

content_box_size() → tuple[int, int]

Size of border + inner shape, excluding the tally mark row.

draw_without_tally(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, x: int, y: int) → None

Draw the shape without tallies, preserving previous state.

draw_tally_overlay(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, anchor_x: int, anchor_y: int, avail_w: int) → None

Draw tally marks at fixed pixel size on the final frame.

draw_tally_overlay_for_box(canvas: bencher.results.manim_cartesian.svg_canvas.SvgCanvas, box_x: int, box_y: int, box_w: int, box_h: int) → None

Draw fixed-size tally overlay below a rendered box.

Spacing is derived from cfg fields so layout stays consistent when configuration changes.

key() → str

Name this shape by what it draws: equal keys draw identical markup.

The SVG writer defines each key once and reuses it, which is what keeps an extrusion of N identical copies at one definition plus N <use> lines.

deep_copy() → StrobeShape
deep_copy_recolored(color_index: int) → StrobeShape

Copy and recolor in a single traversal.

bencher.results.manim_cartesian.cartesian_product_scene.render_animation(cfg: bencher.results.manim_cartesian.cartesian_product_cfg.CartesianProductCfg, width: int = 400, height: int = 300, fps: int = 15, step_frames: int = 4, output_dir: str = 'cachedir/cartesian') → str

Render the dimensional extrusion animation.

Parameters:
  • cfg (CartesianProductCfg) – Sweep configuration.

  • width (int) – Canvas size in pixels.

  • height (int) – Canvas size in pixels.

  • fps (int) – Frame rate the timings are counted in.

  • step_frames (int) – Frames to show each extrusion step (per sub-copy).

  • output_dir (str) – Directory for the output SVG.

  • Returns

  • -------

  • str – Path to the output animated SVG.