carto_flow.flow_cartogram.grid¶
Grid construction and management utilities for flow-based cartography.
This module provides functions for creating and managing spatial grids used in flow-based cartogram algorithms. It includes utilities for constructing regular grids, multi-resolution grids, and grid information containers.
Classes:
-
Grid–Structured grid information container with lazy computation and caching.
Functions:
-
build_multilevel_grids–Create dyadically scaled grids for multi-resolution cartogram algorithms.
Notes
All grid functions return Grid objects that provide both array-based and property-based access to grid coordinates and metadata. The grids are designed to work seamlessly with FFT-based algorithms and maintain proper aspect ratios for cartographic applications.
Examples:
>>> from carto_flow.flow_cartogram.grid import Grid, build_multilevel_grids
>>> grid = Grid.from_bounds((0, 0, 100, 80), size=200)
>>> print(f"Grid shape: {grid.shape}")
Grid shape: (100, 200)
>>> grids = build_multilevel_grids((0, 0, 100, 80), 256, n_levels=3)
>>> print(f"Number of resolution levels: {len(grids)}")
Number of resolution levels: 3
Grid
¶
Grid(
bounds: tuple[float, float, float, float],
size: int | tuple[int | None, int | None],
margin: float = 0.0,
square: bool = False,
)
Grid class with lazy computation and caching of coordinate arrays.
This class provides flexible grid construction with multiple class methods and lazy computation with caching of coordinate arrays for optimal performance.
Construction Methods (Preferred)
-
From bounds and size: Grid.from_bounds(bounds, size, margin=0.0, square=False)
-
From bounds and spacing: Grid.from_bounds_and_spacing(bounds, spacing, margin=0.0, strict=False)
-
From size and spacing: Grid.from_size_and_spacing(size, spacing)
Parameters (Internal)
xmin : float Minimum x-coordinate of the grid bounds. ymin : float Minimum y-coordinate of the grid bounds. xmax : float Maximum x-coordinate of the grid bounds. ymax : float Maximum y-coordinate of the grid bounds. sx : int Number of grid cells in x-direction (columns). sy : int Number of grid cells in y-direction (rows). dx : float Grid cell width in coordinate units. dy : float Grid cell height in coordinate units.
Properties
bounds : tuple of float Grid bounds as (xmin, ymin, xmax, ymax). size : tuple of int Grid size as (sx, sy). spacing : tuple of float Grid spacing as (dx, dy). shape : tuple of int Grid shape as (sy, sx).
Examples:
>>> from carto_flow.grid import Grid
>>> grid = Grid.from_bounds((0, 0, 10, 5), size=100)
>>> print(f"Grid shape: {grid.shape}")
Grid shape: (50, 100)
>>> print(f"Grid bounds: {grid.bounds}")
Grid bounds: (0.0, 0.0, 10.0, 5.0)
>>> x_coords = grid.x_coords # Computed and cached on first access
>>> X = grid.X # Computed and cached on first access
Notes
Use the class methods (from_bounds, from_bounds_and_spacing, from_size_and_spacing) for construction rather than the direct constructor to ensure parameter consistency. The class uses lazy computation with caching for coordinate arrays. Arrays are computed once on first access and then cached for performance.
Parameters:
-
bounds(tuple of float) –Grid bounds as (xmin, ymin, xmax, ymax).
-
size(int or tuple) –Grid size specification: - int: number of points along longest edge - (sx, sy): exact grid dimensions - (sx, None): sx points in x, computed sy for similar dx/dy - (None, sy): computed sx, sy points in y for similar dx/dy
-
margin(float, default:0.0) –Margin to add around bounds as fraction. Default is 0.0.
-
square(bool, default:False) –If True, adjust bounds to ensure dx == dy. Default is False.
Methods:
-
__repr__–Concise string representation for terminal display.
-
from_bounds–Create a Grid from bounds and size specification.
-
from_bounds_and_spacing–Create a Grid from bounds and spacing specification.
-
from_size_and_spacing–Create a Grid from size and spacing specification.
Attributes:
-
X(ndarray) –2D array of x-coordinates in meshgrid format (computed and cached).
-
Y(ndarray) –2D array of y-coordinates in meshgrid format (computed and cached).
-
bounds(tuple[float, float, float, float]) –Grid bounds as (xmin, ymin, xmax, ymax), including any margin.
-
data_bounds(tuple[float, float, float, float]) –Original data bounds as (xmin, ymin, xmax, ymax), without margin.
-
dx(float) –Grid cell width in coordinate units.
-
dy(float) –Grid cell height in coordinate units.
-
shape(tuple[int, int]) –Grid shape as (sy, sx).
-
size(tuple[int, int]) –Grid size as (sx, sy).
-
spacing(tuple[float, float]) –Grid spacing as (dx, dy).
-
sx(int) –Number of grid cells in x-direction (columns).
-
sy(int) –Number of grid cells in y-direction (rows).
-
x_coords(ndarray) –1D array of x-coordinates for grid columns (computed and cached).
-
x_edges(ndarray) –1D array of x-coordinates for cell edges (computed and cached).
-
xmax(float) –Maximum x-coordinate of the grid bounds.
-
xmin(float) –Minimum x-coordinate of the grid bounds.
-
y_coords(ndarray) –1D array of y-coordinates for grid rows (computed and cached).
-
y_edges(ndarray) –1D array of y-coordinates for cell edges (computed and cached).
-
ymax(float) –Maximum y-coordinate of the grid bounds.
-
ymin(float) –Minimum y-coordinate of the grid bounds.
bounds
property
¶
Grid bounds as (xmin, ymin, xmax, ymax), including any margin.
data_bounds
property
¶
Original data bounds as (xmin, ymin, xmax, ymax), without margin.
x_coords
property
¶
1D array of x-coordinates for grid columns (computed and cached).
y_coords
property
¶
1D array of y-coordinates for grid rows (computed and cached).
from_bounds
classmethod
¶
from_bounds(
bounds: tuple[float, float, float, float],
size: int | tuple[int | None, int | None],
margin: float = 0.0,
square: bool = False,
) -> Grid
Create a Grid from bounds and size specification.
Parameters:
-
bounds(tuple of float) –Grid bounds as (xmin, ymin, xmax, ymax).
-
size(int or tuple) –Grid size specification: - int: number of points along longest edge - (sx, sy): exact grid dimensions - (sx, None): sx points in x, computed sy for similar dx/dy - (None, sy): computed sx, sy points in y for similar dx/dy
-
margin(float, default:0.0) –Margin to add around bounds as fraction. Default is 0.0.
-
square(bool, default:False) –If True, adjust bounds to ensure dx == dy. Default is False.
Returns:
-
Grid–New Grid instance.
Examples:
from_bounds_and_spacing
classmethod
¶
from_bounds_and_spacing(
bounds: tuple[float, float, float, float],
spacing: float | tuple[float, float],
margin: float = 0.0,
strict: bool = False,
) -> Grid
Create a Grid from bounds and spacing specification.
Parameters:
-
bounds(tuple of float) –Grid bounds as (xmin, ymin, xmax, ymax).
-
spacing(float or tuple) –Grid spacing: - float: same spacing in both directions - (dx, dy): different spacing in each direction
-
margin(float, default:0.0) –Margin to add around bounds as fraction. Default is 0.0.
-
strict(bool, default:False) –If True, adjust bounds to ensure exact spacing. Default is False.
Returns:
-
Grid–New Grid instance.
Examples:
from_size_and_spacing
classmethod
¶
from_size_and_spacing(
size: int | tuple[int, int],
spacing: float | tuple[float, float],
center: tuple[float, float] = (0.0, 0.0),
) -> Grid
Create a Grid from size and spacing specification.
Parameters:
-
size(int or tuple) –Grid size: - int: same number of points in both directions - (sx, sy): different size in each direction
-
spacing(float or tuple) –Grid spacing: - float: same spacing in both directions - (dx, dy): different spacing in each direction
-
center(tuple of float, default:(0.0, 0.0)) –Center coordinates of the grid as (center_x, center_y). Default is (0.0, 0.0).
Returns:
-
Grid–New Grid instance with bounds computed around the specified center.
Examples:
build_multilevel_grids
¶
build_multilevel_grids(
bounds: tuple[float, float, float, float],
N: int,
n_levels: int = 3,
margin: float = 0.5,
square: bool = False,
) -> list
Build dyadically scaled FFT-friendly grids for multi-resolution cartography.
Creates a hierarchy of grids with dyadically increasing resolution levels, starting from the lowest resolution and doubling at each level. Each level has dimensions exactly double the previous level, making them ideal for multi-resolution cartogram algorithms and FFT-based computations.
Parameters:
-
bounds(tuple of float) –The bounding box as (xmin, ymin, xmax, ymax) coordinates that define the spatial extent for all resolution levels.
-
N(int) –Number of grid points along the longest bounding box edge at the lowest resolution level (grids[0]).
-
n_levels(int, default:3) –Number of resolution levels to create. Each level doubles the dimensions of the previous level. Default is 3.
-
margin(float, default:0.5) –Margin to add around the bounds as a fraction of the bounding box dimensions before computing grid sizes. Default is 0.5.
Returns:
-
list of Grid–List of Grid objects ordered from lowest to highest resolution:
- grids[0] : Grid Lowest resolution grid with approximately N points along the long axis
- grids[1] : Grid Second resolution level with dimensions doubled from previous
- grids[n_levels-1] : Grid Highest resolution grid with approximately N * 2^(n_levels-1) points
Each Grid object contains coordinate arrays and metadata for its respective resolution level.
Examples:
>>> bounds = (0, 0, 100, 80) # Rectangular bounding box
>>> grids = build_multilevel_grids(bounds, N=64, n_levels=3)
>>> print(f"Number of levels: {len(grids)}")
Number of levels: 3
>>> print(f"Level 0 (lowest res) shape: {grids[0].shape}")
Level 0 (lowest res) shape: (64, 51)
>>> print(f"Level 1 shape: {grids[1].shape}")
Level 1 shape: (128, 102)
>>> print(f"Level 2 (highest res) shape: {grids[2].shape}")
Level 2 (highest res) shape: (256, 204)
Notes
The algorithm ensures FFT-friendly dimensions by:
- Computing base dimensions that maintain aspect ratio at the lowest level
- Finding the best short-axis resolution to minimize aspect distortion
- Creating grids where each level has exactly double the dimensions of the previous
The returned grids are ordered from lowest to highest resolution, making them suitable for algorithms that progressively refine solutions from coarse to fine scales.