Grid & Cells¶
A Grid divides the scene into rows and columns of Cell objects. Each cell is a creative unit with image data, position helpers, and the full set of builder methods.
See also
For grid creation patterns, see Scenes and Grids. For cell usage, see Working with Cells.
Grid ¶
Grid(cols: int, rows: int, cell_size: float | None = None, cell_width: float | None = None, cell_height: float | None = None, origin: tuple[float, float] = (0, 0))
A grid of cells that provides structure for placing entities.
Grids divide space into cells, making it easy to create patterns, load image data, and organize entities spatially.
Attributes:
| Name | Type | Description |
|---|---|---|
num_rows |
int
|
Number of rows |
num_columns |
int
|
Number of columns |
cell_width |
float
|
Width of each cell in pixels |
cell_height |
float
|
Height of each cell in pixels |
pixel_width |
float
|
Total width in pixels |
pixel_height |
float
|
Total height in pixels |
Example
Create a grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cols
|
int
|
Number of columns. |
required |
rows
|
int
|
Number of rows. |
required |
cell_size
|
float | None
|
Size for square cells (sets both width and height). |
None
|
cell_width
|
float | None
|
Cell width (overrides cell_size). |
None
|
cell_height
|
float | None
|
Cell height (overrides cell_size). |
None
|
origin
|
tuple[float, float]
|
Top-left corner of the grid in pixels. |
(0, 0)
|
source_image
property
¶
source_image: Image | None
The original source image (if created via from_image), or None.
from_image
classmethod
¶
from_image(image: Image, cols: int | None = None, rows: int | None = None, cell_size: float = 10, cell_ratio: float = 1.0, cell_width: float | None = None, cell_height: float | None = None, origin: tuple[float, float] = (0, 0), load_layers: bool = True) -> Grid
Create a grid sized to match an image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Source image (will be resized to match grid). |
required |
cols
|
int | None
|
Number of columns (calculates rows from aspect ratio). If None and rows is also None, derives both from image dimensions and cell size (fit-grid-to-image mode). |
None
|
rows
|
int | None
|
Number of rows (calculates cols from aspect ratio). |
None
|
cell_size
|
float
|
Base size of each cell in pixels. |
10
|
cell_ratio
|
float
|
Width-to-height ratio (e.g., 2.0 for domino cells). |
1.0
|
cell_width
|
float | None
|
Explicit cell width (overrides cell_size and cell_ratio). |
None
|
cell_height
|
float | None
|
Explicit cell height (overrides cell_size). |
None
|
origin
|
tuple[float, float]
|
Top-left corner of the grid. |
(0, 0)
|
load_layers
|
bool
|
Whether to load image data into cells. |
True
|
Returns:
| Type | Description |
|---|---|
Grid
|
A new Grid with image data loaded into cells. |
row ¶
row(index: int) -> list[Cell]
Get all cells in a specific row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Row index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
list[Cell]
|
List of cells in that row (left to right). |
column ¶
column(index: int) -> list[Cell]
Get all cells in a specific column.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Column index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
list[Cell]
|
List of cells in that column (top to bottom). |
get ¶
get(row: int, col: int) -> Cell | None
Safely access a cell by (row, col) index.
Like dict.get(), returns None instead of raising on
out-of-bounds indices. Use grid[row][col] when you want
IndexError on invalid indices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row
|
int
|
Row index (0-based). |
required |
col
|
int
|
Column index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
Cell | None
|
The Cell at that position, or None if out of bounds. |
cell_at_pixel ¶
cell_at_pixel(x: float, y: float) -> Cell | None
Get the cell containing a pixel position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
float
|
Horizontal pixel position. |
required |
y
|
float
|
Vertical pixel position. |
required |
Returns:
| Type | Description |
|---|---|
Cell | None
|
The Cell at that position, or None if outside grid. |
region ¶
region(row_start: int = 0, row_end: int | None = None, col_start: int = 0, col_end: int | None = None) -> Iterator[Cell]
Iterate over cells in a rectangular region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row_start
|
int
|
Starting row (inclusive, default 0). |
0
|
row_end
|
int | None
|
Ending row (exclusive, default all rows). |
None
|
col_start
|
int
|
Starting column (inclusive, default 0). |
0
|
col_end
|
int | None
|
Ending column (exclusive, default all columns). |
None
|
Yields:
| Type | Description |
|---|---|
Cell
|
Cells in the region (row by row). |
border ¶
border(thickness: int = 1) -> Iterator[Cell]
Iterate over cells on the grid border.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thickness
|
int
|
Border thickness in cells (default 1). |
1
|
Yields:
| Type | Description |
|---|---|
Cell
|
Cells on the border. |
merge ¶
merge(start: tuple[int, int] = (0, 0), end: tuple[int, int] | None = None) -> CellGroup
Merge a rectangular region of cells into a single virtual surface.
The returned CellGroup acts like a single large cell — it has all the same builder methods (add_dot, add_line, add_curve, etc.) and averaged data properties (brightness, color, rgb).
Both corners are inclusive — merge((0, 0), (2, 2)) selects
a 3x3 block (rows 0-2, cols 0-2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
tuple[int, int]
|
Top-left corner as |
(0, 0)
|
end
|
tuple[int, int] | None
|
Bottom-right corner as |
None
|
Returns:
| Type | Description |
|---|---|
CellGroup
|
A CellGroup spanning the selected region. |
merge_row ¶
merge_row(index: int) -> CellGroup
Merge an entire row into a single virtual surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Row index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
CellGroup
|
A CellGroup spanning the full row. |
merge_col ¶
merge_col(index: int) -> CellGroup
Merge an entire column into a single virtual surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
Column index (0-based). |
required |
Returns:
| Type | Description |
|---|---|
CellGroup
|
A CellGroup spanning the full column. |
every ¶
every(n: int, offset: int = 0) -> Iterator[Cell]
Iterate over every Nth cell.
Cells are numbered left-to-right, top-to-bottom.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Select every Nth cell. |
required |
offset
|
int
|
Starting offset (default 0). |
0
|
Yields:
| Type | Description |
|---|---|
Cell
|
Every Nth cell. |
checkerboard ¶
checkerboard(color: str = 'black') -> Iterator[Cell]
Iterate over checkerboard pattern cells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
color
|
str
|
"black" for dark squares, "white" for light squares. |
'black'
|
Yields:
| Type | Description |
|---|---|
Cell
|
Cells in the checkerboard pattern. |
where ¶
diagonal ¶
diagonal(direction: Literal['down', 'up'] = 'down', offset: int = 0) -> Iterator[Cell]
Iterate over cells on a diagonal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
direction
|
Literal['down', 'up']
|
"down" for top-left to bottom-right, "up" for bottom-left to top-right. |
'down'
|
offset
|
int
|
Diagonal offset (0 = main diagonal). |
0
|
Yields:
| Type | Description |
|---|---|
Cell
|
Cells on the diagonal. |
load_layer ¶
Load layer data from an image or layer into cell data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Key to store data under in cell.data. |
required |
source
|
Layer | Image
|
A Layer or Image to sample from. |
required |
mode
|
str
|
How to store values: "value" - Store raw numeric value "normalized" - Store value / 255 (0-1 range) "hex" - Store hex color string (requires Image source) |
'value'
|
Cell ¶
Cell(grid: Grid, row: int, col: int, x: float, y: float, width: float, height: float)
Bases: Surface
A cell within a grid - the fundamental unit for placing art elements.
Cells provide:
- Typed data access: cell.brightness, cell.color instead of dict lookups
- Builder methods: cell.add_dot(), cell.add_line() for easy element creation
(inherited from Surface)
- Position helpers: Named positions like "center", "top_left", etc.
(inherited from Surface)
- Neighbor access: cell.right, cell.below for cross-cell operations
Basic usage
Builder methods
Attributes:
| Name | Type | Description |
|---|---|---|
row |
int
|
Row index (0-based) |
col |
int
|
Column index (0-based) |
brightness |
float
|
Normalized brightness 0.0-1.0 (from loaded image) |
color |
str
|
Hex color string (from loaded image) |
rgb |
tuple[int, int, int]
|
RGB tuple (0-255 each) |
alpha |
float
|
Transparency 0.0-1.0 |
Create a cell (typically called by Grid, not directly).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid
|
Grid
|
The parent grid. |
required |
row
|
int
|
Row index. |
required |
col
|
int
|
Column index. |
required |
x
|
float
|
Top-left corner x in pixels. |
required |
y
|
float
|
Top-left corner y in pixels. |
required |
width
|
float
|
Cell width in pixels. |
required |
height
|
float
|
Cell height in pixels. |
required |
brightness
property
¶
Area-averaged brightness from 0.0 (black) to 1.0 (white).
Derived from the LANCZOS-resampled image (one pixel per cell), so each value represents the weighted average of all source pixels that fall within this cell's region. This smooths harsh transitions — e.g. a cell straddling a black/white border reads ~0.5.
For single-pixel sampling without averaging, use sample_brightness().
Returns 0.5 if no image is loaded.
color
property
¶
Area-averaged hex color from the resampled image (e.g., "#ff5733").
Derived from the LANCZOS-resampled image (one pixel per cell), so it represents the blended color of all source pixels in this cell's region. Borders between contrasting colors will blend.
For single-pixel sampling without averaging, use sample_hex().
Returns "#808080" (gray) if no image is loaded.
rgb
property
¶
Area-averaged RGB color as a tuple of integers (0-255 each).
Derived from the LANCZOS-resampled image (one pixel per cell). Each channel is the weighted average of source pixels in this cell's region.
For single-pixel sampling without averaging, use sample_image().
Returns (128, 128, 128) if no image is loaded.
alpha
property
¶
Area-averaged transparency from 0.0 (transparent) to 1.0 (opaque).
Derived from the LANCZOS-resampled image (one pixel per cell), so it represents the blended alpha of all source pixels in this cell's region.
Returns 1.0 if no alpha data is loaded.
data
property
¶
Raw data dictionary (for custom data or backwards compatibility).
Prefer typed properties (brightness, color, etc.) for standard data.
normalized_position
property
¶
normalized_position: RelCoord
(col, row) normalized to 0.0-1.0 within the grid.
Useful for position-based gradients and effects.
Returns:
| Type | Description |
|---|---|
RelCoord
|
RelCoord(rx, ry) where both are in [0.0, 1.0]. |
above_left
property
¶
above_left: Cell | None
Cell diagonally above-left (northwest), or None if at edge.
above_right
property
¶
above_right: Cell | None
Cell diagonally above-right (northeast), or None if at edge.
below_left
property
¶
below_left: Cell | None
Cell diagonally below-left (southwest), or None if at edge.
below_right
property
¶
below_right: Cell | None
Cell diagonally below-right (southeast), or None if at edge.
neighbors
property
¶
neighbors: dict[str, Cell | None]
All neighbors as a dict (cardinal directions only).
sample_image ¶
Read a single pixel from the original source image (no averaging).
Unlike rgb (which comes from the resampled, area-averaged image),
this reads one pixel at full resolution. This preserves sharp edges
— a cell on a black/white border returns pure black or pure white
depending on where the sample point falls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rx
|
float
|
Horizontal position within cell (0.0 = left edge, 1.0 = right edge). |
0.5
|
ry
|
float
|
Vertical position within cell (0.0 = top edge, 1.0 = bottom edge). |
0.5
|
Returns:
| Type | Description |
|---|---|
tuple[int, int, int]
|
RGB tuple (0-255 each). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the grid was not created from an image. |
sample_brightness ¶
Read brightness of a single pixel from the original source image.
Unlike brightness (which is area-averaged from the resampled image),
this reads one pixel at full resolution. Useful for images with sharp
transitions where averaging would produce unwanted intermediate values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rx
|
float
|
Horizontal position within cell (0.0 = left edge, 1.0 = right edge). |
0.5
|
ry
|
float
|
Vertical position within cell (0.0 = top edge, 1.0 = bottom edge). |
0.5
|
Returns:
| Type | Description |
|---|---|
float
|
Brightness value 0.0 (black) to 1.0 (white). |
sample_hex ¶
Read hex color of a single pixel from the original source image.
Unlike color (which is area-averaged from the resampled image),
this reads one pixel at full resolution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rx
|
float
|
Horizontal position within cell (0.0 = left edge, 1.0 = right edge). |
0.5
|
ry
|
float
|
Vertical position within cell (0.0 = top edge, 1.0 = bottom edge). |
0.5
|
Returns:
| Type | Description |
|---|---|
str
|
Hex color string (e.g., "#ff5733"). |
distance_to ¶
Euclidean pixel distance from this cell's center to another position.
Accepts: Cell (uses center), Coord, or (x, y) tuple. Entity positions work too — just pass entity.anchor("center") or entity.position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
Cell | Entity | Coord | tuple[float, float]
|
A Cell, Coord, or (x, y) tuple. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Distance in pixels. |
Cell extends Surface -- it inherits all 12 builder methods plus has image data, position helpers, and neighbor access.
Neighbor properties return Cells, not positions
cell.left, cell.right, cell.above, cell.below return Cell | None, not position coordinates. Use cell.center, cell.top_left, etc. for positions.
CellGroup ¶
Bases: Surface
A virtual surface spanning multiple grid cells.
CellGroup acts like a single large cell with merged bounds. It inherits all builder methods from Surface (add_dot, add_line, add_curve, etc.) and provides averaged data properties.
Created via grid.merge(), not directly:
```python
group = scene.grid.merge((0, 0), (0, 4))
group.add_fill(color=group.color)
group.add_text("Title", font_size=20)
```
Attributes:
| Name | Type | Description |
|---|---|---|
brightness |
float
|
Average brightness across constituent cells |
color |
str
|
Average color across constituent cells |
rgb |
tuple[int, int, int]
|
Average RGB across constituent cells |
cells |
list[Cell]
|
The constituent Cell objects |
Create a CellGroup from a list of cells.
Typically called by Grid.merge(), not directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cells
|
list[Cell]
|
The cells to merge into this group. |
required |
grid
|
Grid
|
The parent grid. |
required |
A CellGroup is a virtual surface -- it has all the same add_* builder methods as a Cell, and averaged data properties from its constituent cells.