Skip to content

carto_flow.flow_cartogram.algorithm

Core morphing algorithm for cartogram generation.

Low-level cartogram algorithm working directly with shapely geometries.

Functions:

Examples:

>>> from carto_flow.flow_cartogram import morph_geometries, MorphOptions
>>> from shapely.geometry import Polygon
>>>
>>> polygons = [Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])]
>>> values = [100]
>>> options = MorphOptions(n_iter=50)
>>>
>>> result = morph_geometries(polygons, values, options=options)
>>> morphed = result.snapshots.latest().geometry

morph_geometries

morph_geometries(
    geometries,
    values,
    target_density=None,
    landmarks=None,
    coords=None,
    options: MorphOptions | None = None,
) -> Cartogram

Core morphing algorithm working with shapely geometries.

This function implements the fundamental cartogram algorithm that works directly with shapely geometries, making it suitable for users who want to work without dataframes.

Parameters:

  • geometries (List[Geometry]) –

    Shapely geometries to morph

  • values (ndarray) –

    Data values driving the morphing (e.g., population sizes)

  • target_density (float, default: None ) –

    Target density for refinement mode. If None, computed as the mean density from values and areas of geometries.

  • landmarks (Any, default: None ) –

    Optional landmarks geometries for tracking reference points

  • coords (array - like, default: None ) –

    User-defined coordinates, e.g. for displacement field computation, in various formats: - (N, 2) array for point coordinates - (X, Y) tuple for meshgrid coordinates - (M, N, 2) array for mesh format Format is automatically detected from the coordinate structure.

  • options (MorphOptions, default: None ) –

    Algorithm options (dt, n_iter, density_smooth, etc.)

Returns:

  • result ( Cartogram ) –

    Complete cartogram result containing: - snapshots: History of CartogramSnapshot objects with algorithm state - status: MorphStatus enum (CONVERGED, STALLED, COMPLETED, RUNNING, ORIGINAL) - niterations: Number of iterations completed - duration: Computation time in seconds - options: MorphOptions used for computation - internals: History of internal state (if save_internals=True) - grid: Grid used for computation - target_density: Target equilibrium density

    Access final results via result.latest or result.snapshots.latest(): - .geometry: List of morphed geometries - .landmarks: Morphed landmarks (if provided) - .coords: Displaced coordinates (if coords provided) - .errors: MorphErrors with log and percentage error metrics - .density: Current density values

Examples:

>>> from carto_flow.flow_cartogram import morph_geometries, MorphOptions
>>> from shapely.geometry import Polygon
>>>
>>> # Simple morphing
>>> polygons = [Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])]
>>> values = [100]
>>> options = MorphOptions(n_iter=50)
>>>
>>> # Get complete result object
>>> result = morph_geometries(polygons, values, options=options)
>>> morphed = result.snapshots.latest().geometry
>>> print(f"Status: {result.status}")
>>> print(f"Converged in {result.niterations} iterations")
>>> # Compute displacement field
>>> # Create regular grid of coordinates for displacement field
>>> x = np.linspace(0, 100, 50)
>>> y = np.linspace(0, 80, 40)
>>> X, Y = np.meshgrid(x, y)
>>> coords = np.column_stack([X.ravel(), Y.ravel()])
>>>
>>> # Run morphing with displacement field computation (auto-detects format)
>>> result = morph_geometries(
...     polygons, values,
...     coords=coords,
...     options=options
... )
>>>
>>> # Access displaced coordinates (same format as input)
>>> final = result.snapshots.latest()
>>> displaced_coords = final.coords
>>>
>>> # Refine with displaced coordinates (format auto-detected)
>>> refined_result = morph_geometries(
...     final.geometry, values,
...     coords=final.coords,
...     options=options
... )