snnlab.viz.figure_grid
Complete declared API of the figure_grid module, with signatures, data fields, validation and source.
Deterministic geometry in normalized figure coordinates. Row indices run top to bottom and columns left to right. Weighted tracks, gaps and reserved regions define a stable layout shared by stills and animation frames.
The signatures, defaults, fields, docstrings and implementation excerpts below are generated from the Python source. Annotations are shown as declared; unannotated means the source supplies no type annotation. These pages document callable surfaces, including legacy support utilities, without promising backend support for every declaration.
| Symbol | Kind |
|---|---|
| FigureRect | class |
| FigureRegion | class |
| FigureGrid | class |
FigureRect
Source docstring:
A rectangle in normalized figure coordinates.Class decorators: dataclass(frozen=True).
Dataclass constructor parameters. Factory defaults are shown as field declarations; omit these arguments to create fresh values per instance:
FigureRect(x: float, y: float, width: float, height: float)Declared fields, including fields inherited from local data classes:
| Field | Annotation | Default | Meaning |
|---|---|---|---|
x | float | required | Stored member of this data contract; see the class docstring and serialization methods. |
y | float | required | Stored member of this data contract; see the class docstring and serialization methods. |
width | float | required | Stored member of this data contract; see the class docstring and serialization methods. |
height | float | required | Stored member of this data contract; see the class docstring and serialization methods. |
FigureRect.mpl
Decorators: property.
def FigureRect.mpl(self) -> tuple[float, float, float, float]Return annotation: tuple[float, float, float, float].
Return expressions (branch-dependent; names refer to the linked implementation):
(self.x, self.y, self.width, self.height)Implementation
def mpl(self) -> tuple[float, float, float, float]:
return self.x, self.y, self.width, self.heightFigureRect.inset
def FigureRect.inset(self, padding: float | tuple[float, float, float, float]) -> 'FigureRect'Source docstring:
Inset by relative left, bottom, right and top fractions.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
padding | float | tuple[float, float, float, float] | required | Defined by the source contract and implementation below. |
Return annotation: 'FigureRect'.
Return expressions (branch-dependent; names refer to the linked implementation):
FigureRect(self.x + self.width * left, self.y + self.height * bottom, width, height)Explicit exceptions in this implementation; called helpers may raise additional errors:
| Explicit exception expression |
|---|
ValueError('figure-grid padding must be non-negative') |
ValueError('figure-grid padding consumes the region') |
Implementation
def inset(
self,
padding: float | tuple[float, float, float, float],
) -> "FigureRect":
"""Inset by relative left, bottom, right and top fractions."""
if isinstance(padding, (int, float)):
left = bottom = right = top = float(padding)
else:
left, bottom, right, top = padding
if min(left, bottom, right, top) < 0:
raise ValueError("figure-grid padding must be non-negative")
width = self.width * (1 - left - right)
height = self.height * (1 - bottom - top)
if width <= 0 or height <= 0:
raise ValueError("figure-grid padding consumes the region")
return FigureRect(
self.x + self.width * left,
self.y + self.height * bottom,
width,
height,
)Complete class implementation
class FigureRect:
"""A rectangle in normalized figure coordinates."""
x: float
y: float
width: float
height: float
@property
def mpl(self) -> tuple[float, float, float, float]:
return self.x, self.y, self.width, self.height
def inset(
self,
padding: float | tuple[float, float, float, float],
) -> "FigureRect":
"""Inset by relative left, bottom, right and top fractions."""
if isinstance(padding, (int, float)):
left = bottom = right = top = float(padding)
else:
left, bottom, right, top = padding
if min(left, bottom, right, top) < 0:
raise ValueError("figure-grid padding must be non-negative")
width = self.width * (1 - left - right)
height = self.height * (1 - bottom - top)
if width <= 0 or height <= 0:
raise ValueError("figure-grid padding consumes the region")
return FigureRect(
self.x + self.width * left,
self.y + self.height * bottom,
width,
height,
)FigureRegion
Source docstring:
A named rectangular selection of grid tracks.Class decorators: dataclass(frozen=True).
Dataclass constructor parameters. Factory defaults are shown as field declarations; omit these arguments to create fresh values per instance:
FigureRegion(name: str, row: int, column: int, rowspan: int = 1, colspan: int = 1, reserved: bool = False)Declared fields, including fields inherited from local data classes:
| Field | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
row | int | required | Zero-based grid row, counted from top to bottom. |
column | int | required | Zero-based grid column, counted from left to right. |
rowspan | int | 1 | Number of grid rows covered. |
colspan | int | 1 | Number of grid columns covered. |
reserved | bool | False | Stored member of this data contract; see the class docstring and serialization methods. |
Complete class implementation
class FigureRegion:
"""A named rectangular selection of grid tracks."""
name: str
row: int
column: int
rowspan: int = 1
colspan: int = 1
reserved: bool = FalseFigureGrid
Source docstring:
Place named regions on weighted rows and columns.
Rows are numbered from top to bottom; columns from left to right. Gaps and
bounds use normalized figure coordinates. Regions must be rectangular and
may span any number of tracks.Class decorators: dataclass.
Dataclass constructor parameters. Factory defaults are shown as field declarations; omit these arguments to create fresh values per instance:
FigureGrid(rows: int | Sequence[float], columns: int | Sequence[float], bounds: FigureRect | tuple[float, float, float, float] = FigureRect(0.06, 0.06, 0.88, 0.88), row_gap: float | Sequence[float] = 0.03, column_gap: float | Sequence[float] = 0.03, theme: Theme = field(default_factory=Theme))Declared fields, including fields inherited from local data classes:
| Field | Annotation | Default | Meaning |
|---|---|---|---|
rows | int | Sequence[float] | required | Stored member of this data contract; see the class docstring and serialization methods. |
columns | int | Sequence[float] | required | Stored member of this data contract; see the class docstring and serialization methods. |
bounds | FigureRect | tuple[float, float, float, float] | FigureRect(0.06, 0.06, 0.88, 0.88) | Stored member of this data contract; see the class docstring and serialization methods. |
row_gap | float | Sequence[float] | 0.03 | Stored member of this data contract; see the class docstring and serialization methods. |
column_gap | float | Sequence[float] | 0.03 | Stored member of this data contract; see the class docstring and serialization methods. |
theme | Theme | field(default_factory=Theme) | Stored member of this data contract; see the class docstring and serialization methods. |
Constructor/initialization exception expressions:
| Explicit exception expression |
|---|
ValueError('figure-grid bounds must have positive size') |
ValueError('figure-grid column gaps consume the bounds') |
ValueError('figure-grid row gaps consume the bounds') |
FigureGrid.place
def FigureGrid.place(self, name: str, *, row: int, column: int, rowspan: int=1, colspan: int=1) -> FigureRegionSource docstring:
Place one named region, rejecting overlaps and invalid spans.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
row | int | required | Zero-based grid row, counted from top to bottom. |
column | int | required | Zero-based grid column, counted from left to right. |
rowspan | int | 1 | Number of grid rows covered. |
colspan | int | 1 | Number of grid columns covered. |
Return annotation: FigureRegion.
Return expressions (branch-dependent; names refer to the linked implementation):
self._place(FigureRegion(name, row, column, rowspan, colspan, reserved=False))Implementation
def place(
self,
name: str,
*,
row: int,
column: int,
rowspan: int = 1,
colspan: int = 1,
) -> FigureRegion:
"""Place one named region, rejecting overlaps and invalid spans."""
return self._place(
FigureRegion(name, row, column, rowspan, colspan, reserved=False)
)FigureGrid.reserve
def FigureGrid.reserve(self, name: str, *, row: int, column: int, rowspan: int=1, colspan: int=1) -> FigureRegionSource docstring:
Reserve tracks that must not become plotting axes.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
row | int | required | Zero-based grid row, counted from top to bottom. |
column | int | required | Zero-based grid column, counted from left to right. |
rowspan | int | 1 | Number of grid rows covered. |
colspan | int | 1 | Number of grid columns covered. |
Return annotation: FigureRegion.
Return expressions (branch-dependent; names refer to the linked implementation):
self._place(FigureRegion(name, row, column, rowspan, colspan, reserved=True))Implementation
def reserve(
self,
name: str,
*,
row: int,
column: int,
rowspan: int = 1,
colspan: int = 1,
) -> FigureRegion:
"""Reserve tracks that must not become plotting axes."""
return self._place(
FigureRegion(name, row, column, rowspan, colspan, reserved=True)
)FigureGrid.names
Decorators: property.
def FigureGrid.names(self) -> tuple[str, ...]Return annotation: tuple[str, ...].
Return expressions (branch-dependent; names refer to the linked implementation):
tuple(self._regions)Implementation
def names(self) -> tuple[str, ...]:
return tuple(self._regions)FigureGrid.region
def FigureGrid.region(self, name: str) -> FigureRegion| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
Return annotation: FigureRegion.
Return expressions (branch-dependent; names refer to the linked implementation):
self._regions[name]Explicit exceptions in this implementation; called helpers may raise additional errors:
| Explicit exception expression |
|---|
KeyError(f'unknown figure-grid region: {name}') |
Implementation
def region(self, name: str) -> FigureRegion:
try:
return self._regions[name]
except KeyError as error:
raise KeyError(f"unknown figure-grid region: {name}") from errorFigureGrid.rect
def FigureGrid.rect(self, name: str, *, padding: float | tuple[float, float, float, float]=0.0) -> FigureRectSource docstring:
Resolve a named region to normalized figure coordinates.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
padding | float | tuple[float, float, float, float] | 0.0 | Defined by the source contract and implementation below. |
Return annotation: FigureRect.
Return expressions (branch-dependent; names refer to the linked implementation):
FigureRect(x, top - height, width, height).inset(padding)Implementation
def rect(
self,
name: str,
*,
padding: float | tuple[float, float, float, float] = 0.0,
) -> FigureRect:
"""Resolve a named region to normalized figure coordinates."""
region = self.region(name)
widths = self._sizes(self.columns, self.bounds.width, self.column_gap)
heights = self._sizes(self.rows, self.bounds.height, self.row_gap)
x = self.bounds.x + sum(widths[: region.column])
x += sum(self.column_gap[: region.column])
top = self.bounds.y + self.bounds.height
top -= sum(heights[: region.row]) + sum(self.row_gap[: region.row])
width = sum(widths[region.column : region.column + region.colspan])
width += sum(
self.column_gap[
region.column : region.column + region.colspan - 1
]
)
height = sum(heights[region.row : region.row + region.rowspan])
height += sum(self.row_gap[region.row : region.row + region.rowspan - 1])
return FigureRect(x, top - height, width, height).inset(padding)FigureGrid.subgrid
def FigureGrid.subgrid(self, name: str, *, rows: int | Sequence[float], columns: int | Sequence[float], padding: float | tuple[float, float, float, float]=0.0, row_gap: float | Sequence[float]=0.02, column_gap: float | Sequence[float]=0.02) -> 'FigureGrid'Source docstring:
Create a nested grid inside an existing non-reserved region.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
name | str | required | Name used to identify the authored or rendered object. |
rows | int | Sequence[float] | required | Defined by the source contract and implementation below. |
columns | int | Sequence[float] | required | Defined by the source contract and implementation below. |
padding | float | tuple[float, float, float, float] | 0.0 | Defined by the source contract and implementation below. |
row_gap | float | Sequence[float] | 0.02 | Defined by the source contract and implementation below. |
column_gap | float | Sequence[float] | 0.02 | Defined by the source contract and implementation below. |
Return annotation: 'FigureGrid'.
Return expressions (branch-dependent; names refer to the linked implementation):
FigureGrid(rows, columns, bounds=self.rect(name, padding=padding), row_gap=row_gap, column_gap=column_gap, theme=self.theme)Explicit exceptions in this implementation; called helpers may raise additional errors:
| Explicit exception expression |
|---|
ValueError('cannot create a subgrid inside a reserved region') |
Implementation
def subgrid(
self,
name: str,
*,
rows: int | Sequence[float],
columns: int | Sequence[float],
padding: float | tuple[float, float, float, float] = 0.0,
row_gap: float | Sequence[float] = 0.02,
column_gap: float | Sequence[float] = 0.02,
) -> "FigureGrid":
"""Create a nested grid inside an existing non-reserved region."""
region = self.region(name)
if region.reserved:
raise ValueError("cannot create a subgrid inside a reserved region")
return FigureGrid(
rows,
columns,
bounds=self.rect(name, padding=padding),
row_gap=row_gap,
column_gap=column_gap,
theme=self.theme,
)FigureGrid.figure
def FigureGrid.figure(self, *, figsize: tuple[float, float], dpi: int=120) -> AnySource docstring:
Create an opaque figure using the default snnviz house style.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
figsize | tuple[float, float] | required | Defined by the source contract and implementation below. |
dpi | int | 120 | Defined by the source contract and implementation below. |
Return annotation: Any.
Return expressions (branch-dependent; names refer to the linked implementation):
figureImplementation
def figure(
self,
*,
figsize: tuple[float, float],
dpi: int = 120,
) -> Any:
"""Create an opaque figure using the default snnviz house style."""
self.theme.apply()
figure = plt.figure(figsize=figsize, dpi=dpi)
figure.patch.set_facecolor(self.theme.background)
return figureFigureGrid.add_axes
def FigureGrid.add_axes(self, figure: Any, name: str, *, padding: float | tuple[float, float, float, float]=0.0, frame: bool=True, **kwargs: Any) -> AnySource docstring:
Create a Matplotlib axis in one named region.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
figure | Any | required | Defined by the source contract and implementation below. |
name | str | required | Name used to identify the authored or rendered object. |
padding | float | tuple[float, float, float, float] | 0.0 | Defined by the source contract and implementation below. |
frame | bool | True | Defined by the source contract and implementation below. |
**kwargs | Any | variadic | Defined by the source contract and implementation below. |
Return annotation: Any.
Return expressions (branch-dependent; names refer to the linked implementation):
axisExplicit exceptions in this implementation; called helpers may raise additional errors:
| Explicit exception expression |
|---|
ValueError(f'cannot create axes in reserved region {name!r}') |
Implementation
def add_axes(
self,
figure: Any,
name: str,
*,
padding: float | tuple[float, float, float, float] = 0.0,
frame: bool = True,
**kwargs: Any,
) -> Any:
"""Create a Matplotlib axis in one named region."""
region = self.region(name)
if region.reserved:
raise ValueError(f"cannot create axes in reserved region {name!r}")
axis = figure.add_axes(self.rect(name, padding=padding).mpl, **kwargs)
self.style_axis(axis, frame=frame)
return axisFigureGrid.style_axis
def FigureGrid.style_axis(self, axis: Any, *, frame: bool=True) -> None| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
axis | Any | required | Defined by the source contract and implementation below. |
frame | bool | True | Defined by the source contract and implementation below. |
Return annotation: None.
Implementation
def style_axis(self, axis: Any, *, frame: bool = True) -> None:
axis.set_facecolor(self.theme.background)
for spine in axis.spines.values():
spine.set_visible(frame)
spine.set_color(self.theme.ink)
spine.set_linewidth(1.4)
axis.tick_params(
colors=self.theme.ink,
direction="in",
width=1.0,
length=4,
)FigureGrid.draw_region
def FigureGrid.draw_region(self, figure: Any, name: str, *, role: str='ink', fill: str | None=None, linewidth: float=1.4, dashed: bool=False, zorder: float=-10) -> RectangleSource docstring:
Draw the hard-edged house-style boundary of a named region.| Parameter | Annotation | Default | Meaning |
|---|---|---|---|
figure | Any | required | Defined by the source contract and implementation below. |
name | str | required | Name used to identify the authored or rendered object. |
role | str | 'ink' | Defined by the source contract and implementation below. |
fill | str | None | None | Defined by the source contract and implementation below. |
linewidth | float | 1.4 | Defined by the source contract and implementation below. |
dashed | bool | False | Defined by the source contract and implementation below. |
zorder | float | -10 | Defined by the source contract and implementation below. |
Return annotation: Rectangle.
Return expressions (branch-dependent; names refer to the linked implementation):
patchImplementation
def draw_region(
self,
figure: Any,
name: str,
*,
role: str = "ink",
fill: str | None = None,
linewidth: float = 1.4,
dashed: bool = False,
zorder: float = -10,
) -> Rectangle:
"""Draw the hard-edged house-style boundary of a named region."""
colour = self.theme.colour(role)
patch = Rectangle(
self.rect(name).mpl[:2],
self.rect(name).width,
self.rect(name).height,
transform=figure.transFigure,
facecolor=fill or self.theme.background,
edgecolor=colour,
linewidth=linewidth,
linestyle=(0, (5, 4)) if dashed else "solid",
zorder=zorder,
clip_on=False,
)
figure.add_artist(patch)
return patchComplete class implementation
class FigureGrid:
"""Place named regions on weighted rows and columns.
Rows are numbered from top to bottom; columns from left to right. Gaps and
bounds use normalized figure coordinates. Regions must be rectangular and
may span any number of tracks.
"""
rows: int | Sequence[float]
columns: int | Sequence[float]
bounds: FigureRect | tuple[float, float, float, float] = FigureRect(
0.06, 0.06, 0.88, 0.88
)
row_gap: float | Sequence[float] = 0.03
column_gap: float | Sequence[float] = 0.03
theme: Theme = field(default_factory=Theme)
_regions: dict[str, FigureRegion] = field(default_factory=dict, init=False)
def __post_init__(self) -> None:
self.rows = _tracks(self.rows, "rows")
self.columns = _tracks(self.columns, "columns")
self.row_gap = self._gaps(self.row_gap, len(self.rows) - 1, "row")
self.column_gap = self._gaps(
self.column_gap, len(self.columns) - 1, "column"
)
if not isinstance(self.bounds, FigureRect):
self.bounds = FigureRect(*self.bounds)
if self.bounds.width <= 0 or self.bounds.height <= 0:
raise ValueError("figure-grid bounds must have positive size")
if sum(self.column_gap) >= self.bounds.width:
raise ValueError("figure-grid column gaps consume the bounds")
if sum(self.row_gap) >= self.bounds.height:
raise ValueError("figure-grid row gaps consume the bounds")
@staticmethod
def _gaps(
value: float | Sequence[float], count: int, label: str
) -> tuple[float, ...]:
if isinstance(value, (int, float)):
gaps = (float(value),) * count
else:
gaps = tuple(float(item) for item in value)
if len(gaps) != count or any(item < 0 for item in gaps):
raise ValueError(
f"figure-grid {label} gaps must contain {count} non-negative values"
)
return gaps
def place(
self,
name: str,
*,
row: int,
column: int,
rowspan: int = 1,
colspan: int = 1,
) -> FigureRegion:
"""Place one named region, rejecting overlaps and invalid spans."""
return self._place(
FigureRegion(name, row, column, rowspan, colspan, reserved=False)
)
def reserve(
self,
name: str,
*,
row: int,
column: int,
rowspan: int = 1,
colspan: int = 1,
) -> FigureRegion:
"""Reserve tracks that must not become plotting axes."""
return self._place(
FigureRegion(name, row, column, rowspan, colspan, reserved=True)
)
def _place(self, region: FigureRegion) -> FigureRegion:
if not region.name or region.name in self._regions:
raise ValueError("figure-grid region names must be non-empty and unique")
if region.row < 0 or region.column < 0:
raise ValueError("figure-grid row and column must be non-negative")
if region.rowspan <= 0 or region.colspan <= 0:
raise ValueError("figure-grid spans must be positive")
if region.row + region.rowspan > len(self.rows):
raise ValueError(f"figure-grid region {region.name!r} exceeds its rows")
if region.column + region.colspan > len(self.columns):
raise ValueError(f"figure-grid region {region.name!r} exceeds its columns")
cells = self._cells(region)
for existing in self._regions.values():
if cells & self._cells(existing):
raise ValueError(
f"figure-grid region {region.name!r} overlaps {existing.name!r}"
)
self._regions[region.name] = region
return region
@staticmethod
def _cells(region: FigureRegion) -> set[tuple[int, int]]:
return {
(row, column)
for row in range(region.row, region.row + region.rowspan)
for column in range(region.column, region.column + region.colspan)
}
@property
def names(self) -> tuple[str, ...]:
return tuple(self._regions)
def region(self, name: str) -> FigureRegion:
try:
return self._regions[name]
except KeyError as error:
raise KeyError(f"unknown figure-grid region: {name}") from error
def rect(
self,
name: str,
*,
padding: float | tuple[float, float, float, float] = 0.0,
) -> FigureRect:
"""Resolve a named region to normalized figure coordinates."""
region = self.region(name)
widths = self._sizes(self.columns, self.bounds.width, self.column_gap)
heights = self._sizes(self.rows, self.bounds.height, self.row_gap)
x = self.bounds.x + sum(widths[: region.column])
x += sum(self.column_gap[: region.column])
top = self.bounds.y + self.bounds.height
top -= sum(heights[: region.row]) + sum(self.row_gap[: region.row])
width = sum(widths[region.column : region.column + region.colspan])
width += sum(
self.column_gap[
region.column : region.column + region.colspan - 1
]
)
height = sum(heights[region.row : region.row + region.rowspan])
height += sum(self.row_gap[region.row : region.row + region.rowspan - 1])
return FigureRect(x, top - height, width, height).inset(padding)
@staticmethod
def _sizes(
tracks: Sequence[float], extent: float, gaps: Sequence[float]
) -> tuple[float, ...]:
available = extent - sum(gaps)
scale = available / sum(tracks)
return tuple(track * scale for track in tracks)
def subgrid(
self,
name: str,
*,
rows: int | Sequence[float],
columns: int | Sequence[float],
padding: float | tuple[float, float, float, float] = 0.0,
row_gap: float | Sequence[float] = 0.02,
column_gap: float | Sequence[float] = 0.02,
) -> "FigureGrid":
"""Create a nested grid inside an existing non-reserved region."""
region = self.region(name)
if region.reserved:
raise ValueError("cannot create a subgrid inside a reserved region")
return FigureGrid(
rows,
columns,
bounds=self.rect(name, padding=padding),
row_gap=row_gap,
column_gap=column_gap,
theme=self.theme,
)
def figure(
self,
*,
figsize: tuple[float, float],
dpi: int = 120,
) -> Any:
"""Create an opaque figure using the default snnviz house style."""
self.theme.apply()
figure = plt.figure(figsize=figsize, dpi=dpi)
figure.patch.set_facecolor(self.theme.background)
return figure
def add_axes(
self,
figure: Any,
name: str,
*,
padding: float | tuple[float, float, float, float] = 0.0,
frame: bool = True,
**kwargs: Any,
) -> Any:
"""Create a Matplotlib axis in one named region."""
region = self.region(name)
if region.reserved:
raise ValueError(f"cannot create axes in reserved region {name!r}")
axis = figure.add_axes(self.rect(name, padding=padding).mpl, **kwargs)
self.style_axis(axis, frame=frame)
return axis
def style_axis(self, axis: Any, *, frame: bool = True) -> None:
axis.set_facecolor(self.theme.background)
for spine in axis.spines.values():
spine.set_visible(frame)
spine.set_color(self.theme.ink)
spine.set_linewidth(1.4)
axis.tick_params(
colors=self.theme.ink,
direction="in",
width=1.0,
length=4,
)
def draw_region(
self,
figure: Any,
name: str,
*,
role: str = "ink",
fill: str | None = None,
linewidth: float = 1.4,
dashed: bool = False,
zorder: float = -10,
) -> Rectangle:
"""Draw the hard-edged house-style boundary of a named region."""
colour = self.theme.colour(role)
patch = Rectangle(
self.rect(name).mpl[:2],
self.rect(name).width,
self.rect(name).height,
transform=figure.transFigure,
facecolor=fill or self.theme.background,
edgecolor=colour,
linewidth=linewidth,
linestyle=(0, (5, 4)) if dashed else "solid",
zorder=zorder,
clip_on=False,
)
figure.add_artist(patch)
return patch