Scenes & Grids¶
The Scene is your canvas, and the Grid gives it structure. Together they form the foundation of every PyFreeform artwork.
Creating Scenes¶
From an Image¶
Scene.from_image() loads a photo and divides it into a grid of cells, each sampling the image's colors and brightness.
grid_size controls resolution — how many columns of cells across. More cells = more detail:
Cell Ratio¶
cell_ratio changes cell proportions. A ratio of 2.0 makes cells twice as wide as tall:
From Scratch¶
Scene.with_grid() creates a grid with no image data — use position and math to drive visuals:
from pyfreeform import Scene, Palette
colors = Palette.midnight()
scene = Scene.with_grid(cols=15, rows=15, cell_size=22, background=colors.background)
for cell in scene.grid:
nx, ny = cell.normalized_position
radius = 0.091 + (nx * ny) * 0.364
cell.add_dot(radius=radius, color=colors.primary, opacity=0.5 + nx * 0.5)
Grid Selections¶
The grid offers powerful selection methods for targeting specific cells.
Row & Column¶
for cell in scene.grid.row(3): # All cells in row 3
cell.add_fill(color=colors.primary, opacity=0.4)
for cell in scene.grid.column(6): # All cells in column 6
cell.add_fill(color=colors.accent, opacity=0.4)
Border¶
thicknesscontrols how many rows/columns deep the border extends.
Region¶
for cell in scene.grid.region(2, 6, 3, 9): # (1)!
cell.add_polygon(Polygon.hexagon(size=0.6), fill=colors.primary)
region(row_start, row_end, col_start, col_end)— end is exclusive.
Checkerboard & Diagonal¶
for cell in scene.grid.checkerboard("black"):
cell.add_polygon(Polygon.diamond(size=0.7), fill=colors.primary)
for cell in scene.grid.checkerboard("white"):
cell.add_dot(radius=0.15, color=colors.accent)
Merging Cells¶
Merge a row, column, or rectangular region into a single CellGroup — a virtual surface that spans multiple cells:
title_bar = scene.grid.merge_row(0)
title_bar.add_fill(color=colors.primary, opacity=0.2)
title_bar.add_text("TITLE BAR", at="center", font_size=0.50, color=colors.accent, bold=True)
A CellGroup has all the same add_* methods as a Cell — it's a full Surface.
Other merge methods
grid.merge_col(i)— merge a full columngrid.merge(start, end)— merge any rectangular region. Both args are(row, col)tuples, both inclusive.
What's Next?¶
Now that you can create and navigate grids, learn how to read and use each cell's data: