Skip to content

carto_flow.proportional_cartogram.shrinking

Geometry shrinking utilities.

This module provides functions for shrinking geometries to create concentric shells with specified area fractions. Uses numerical root finding to achieve precise area targets.

Functions:

  • shrink

    Shrink a geometry to create concentric shells with specified area fractions.

shrink

shrink(
    geom: BaseGeometry,
    fractions: float | Sequence[float],
    simplify: float | None = None,
    mode: Literal["area", "shell"] = "area",
    tol: float = 0.05,
) -> list[BaseGeometry]

Shrink a geometry to create concentric shells with specified area fractions.

This function reduces a geometry's area by creating one or more concentric shells. For N fractions, it creates N parts: 1 innermost core plus N-1 shells expanding outward.

Parameters:

  • geom (BaseGeometry) –

    Input geometry to shrink. Can be Polygon, MultiPolygon, or any geometry that supports buffer operations.

  • fractions (float or Sequence[float]) –

    Target area fractions for each part.

    • Single float: Shrink to one target fraction, returning [core, shell] where core has area fraction and shell has area (1-fraction). Must be in range [0, 1].
    • Sequence of floats: Create N parts. Values represent the area fraction of each part from inside to outside (core first). Values should be non-negative and sum to approximately 1.0. Example: [0.25, 0.25, 0.25, 0.25] creates 1 core + 3 shells, each 25%.
  • simplify (float, default: None ) –

    Simplification tolerance (Visvalingam-Whyatt via shapely.coverage_simplify). Applied before shrinking to reduce numerical artifacts from highly detailed boundaries.

  • mode (('area', 'shell'), default: 'area' ) –

    Interpretation mode for fractions:

    • 'area': Fractions represent direct area ratios
    • 'shell': Fractions represent shell thickness ratios (squared for area)
  • tol (float, default: 0.05 ) –

    Relative tolerance for the root finding algorithm.

Returns:

  • list[BaseGeometry]

    List of geometry parts from innermost to outermost. Each part corresponds positionally to its input fraction (fractions[i] maps to parts[i]), consistent with :func:split.

    • For single float f: returns [core, shell] where core has area foriginal and shell has area (1-f)original.
    • For sequence of N values: returns N geometries [part_0, ..., part_{N-1}] where part_0 is the innermost core and part_{N-1} is the outermost shell.
    • Zero fractions produce empty geometries in the corresponding position.

Raises:

  • ValueError

    If fractions are negative or don't sum to ~1.

  • TypeError

    If geom is not a valid Shapely geometry

Examples:

Single shrink (binary):

>>> from shapely.geometry import Polygon
>>> from carto_flow.proportional_cartogram import shrink
>>>
>>> square = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
>>> parts = shrink(square, 0.5)
>>> len(parts)  # [core, shell]
2
>>> print(f"Core area: {parts[0].area:.1f}")  # 50.0
>>> print(f"Shell area: {parts[1].area:.1f}")  # 50.0

Create concentric shells with equal fractions:

>>> # 4 equal parts: core + 3 shells (25% each)
>>> parts = shrink(square, [0.25, 0.25, 0.25, 0.25])
>>> len(parts)  # 4 parts
4
>>> print(f"Areas: {[round(p.area, 1) for p in parts]}")  # [25.0, 25.0, 25.0, 25.0]

Unequal shells (core first):

>>> # Core 20%, middle shell 30%, outer shell 50%
>>> parts = shrink(square, [0.2, 0.3, 0.5])
>>> print(f"Core area: {parts[0].area:.1f}")  # 20.0

Shell mode for thickness-based shrinking:

>>> parts = shrink(square, [0.5, 0.5], mode='shell')
>>> # Areas will be based on squared fractions