Skip to content

carto_flow.symbol_cartogram.visualization

Visualization functions for symbol cartograms.

Functions:

  • plot_adjacency

    Visualize the adjacency graph overlaid on the cartogram.

  • plot_adjacency_heatmap

    Render the adjacency matrix as a heatmap for weight and structure inspection.

  • plot_comparison

    Side-by-side comparison of original geometries and symbols.

  • plot_displacement

    Plot displacement arrows from original centroids to symbol centers.

  • plot_symbols

    Plot a symbol cartogram with rich, per-symbol visual styling.

  • plot_tiling

    Visualize the tiling grid underlying a grid-placement cartogram.

plot_adjacency

plot_adjacency(
    result: SymbolCartogram,
    original_gdf: GeoDataFrame | None = None,
    adjacency: NDArray | None = None,
    ax: Axes | None = None,
    edge_color: str | None = None,
    edge_cmap: str = "viridis",
    edge_alpha: float = 0.6,
    edge_width: float = 1.5,
    node_size: float = 20,
    show_symbols: bool = True,
    show_original: bool = False,
    use_original_positions: bool = False,
    colorbar: bool = True,
    colorbar_kwds: dict | None = None,
    **kwargs: Any,
) -> AdjacencyPlotResult

Visualize the adjacency graph overlaid on the cartogram.

Draws edges between adjacent symbol centers. Edge color can be fixed or mapped to adjacency weight via a colormap.

Parameters:

  • result (SymbolCartogram) –

    Symbol cartogram result.

  • original_gdf (GeoDataFrame, default: None ) –

    Original GeoDataFrame for underlay when show_original=True. Also used as the node position source when use_original_positions=True.

  • adjacency (ndarray, default: None ) –

    Adjacency matrix of shape (n, n). If None, uses the matrix stored in the result (result.layout_result.adjacency).

  • ax (Axes, default: None ) –

    Axes to plot on. Created if not provided.

  • edge_color (str, default: None ) –

    Fixed color for all edges. If None, edges are colored by weight using edge_cmap.

  • edge_cmap (str, default: 'viridis' ) –

    Colormap name for edge weights (used when edge_color is None).

  • edge_alpha (float, default: 0.6 ) –

    Edge transparency.

  • edge_width (float, default: 1.5 ) –

    Base edge line width.

  • node_size (float, default: 20 ) –

    Size of node markers at symbol centers.

  • show_symbols (bool, default: True ) –

    Whether to show symbol polygons underneath.

  • show_original (bool, default: False ) –

    Whether to show original geometry boundaries.

  • use_original_positions (bool, default: False ) –

    When True, draw graph nodes at the centroids of the original geometries instead of the cartogram symbol centers. Position lookup order: original_gdf (if provided) → result.layout_result.positionsresult._source_gdf. Raises ValueError when no original positions can be found. Default False.

  • colorbar (bool, default: True ) –

    Whether to attach a colorbar for edge weights when edge_color is None (i.e. edges are colored by weight via edge_cmap). The colorbar range is fixed to [0, 1] (the valid range for all adjacency modes) so it is comparable across datasets. Default True.

  • colorbar_kwds (dict, default: None ) –

    Keyword arguments forwarded to Figure.colorbar(). Common keys: shrink, label, orientation, pad. Defaults to {"shrink": 0.6, "label": "adjacency weight"}.

  • **kwargs (Any, default: {} ) –

    Passed to result.plot() if show_symbols=True.

Returns:

  • AdjacencyPlotResult

    Result with the axes and captured artists.

plot_adjacency_heatmap

plot_adjacency_heatmap(
    source: SymbolCartogram | LayoutResult | NDArray,
    labels: str | Sequence | None = None,
    sort_by: str | Sequence | None = None,
    *,
    ax: Axes | None = None,
    figsize: tuple[float, float] | None = None,
    cmap: str = "YlOrRd",
    vmin: float | None = None,
    vmax: float | None = None,
    show_values: bool = False,
    value_fmt: str = ".2g",
    colorbar: bool = True,
    colorbar_kwds: dict | None = None,
    title: str | None = "Adjacency Matrix",
    source_gdf: GeoDataFrame | None = None,
    tick_fontsize: float | None = None,
) -> AdjacencyHeatmapResult

Render the adjacency matrix as a heatmap for weight and structure inspection.

Parameters:

  • source (SymbolCartogram, LayoutResult, or ndarray) –

    Input containing the adjacency matrix. Accepts:

    • SymbolCartogram – adjacency taken from source.layout_result.adjacency.
    • LayoutResult – adjacency taken from source.adjacency.
    • numpy.ndarray of shape (n, n) – used directly.
  • labels (str, sequence of str, or None, default: None ) –

    Row/column tick labels.

    • None (default) – integer indices 0 … n-1.
    • Column name string – looked up via internal column resolver; requires source to be a SymbolCartogram.
    • Sequence of strings of length n – used directly.
  • sort_by (None, str, or sequence, default: None ) –

    Reorder rows and columns before plotting.

    • None (default) – original order.
    • "label" – alphabetical sort by resolved label strings.
    • Other column name string – ascending sort by that column's values; requires source to be a SymbolCartogram.
    • Sequence of strings – one sort value per region; regions are sorted alphabetically ascending by these values (e.g. ["high", "low", "medium", "high"]).
    • Sequence of ints – explicit permutation of row/column indices.
  • ax (Axes, default: None ) –

    Axes to draw on. Created when not provided.

  • figsize (tuple, default: None ) –

    Figure size when creating a new figure. Defaults to an auto-scaled value based on n (capped between 4 and 16 inches per side).

  • cmap (str, default: 'YlOrRd' ) –

    Colormap name. Default "YlOrRd".

  • vmin (float, default: None ) –

    Colormap data limits. Defaults to the observed min/max of the matrix.

  • vmax (float, default: None ) –

    Colormap data limits. Defaults to the observed min/max of the matrix.

  • show_values (bool, default: False ) –

    Annotate non-zero cells with their formatted value. Default False.

  • value_fmt (str, default: '.2g' ) –

    Python format spec for cell annotations (e.g. ".2g", "d"). Default ".2g".

  • colorbar (bool, default: True ) –

    Attach a colorbar to the axes. Default True.

  • colorbar_kwds (dict, default: None ) –

    Keyword arguments forwarded to Figure.colorbar(). Common keys: shrink, label, orientation, pad. Defaults to {"shrink": 0.8, "label": "weight"}.

  • title (str or None, default: 'Adjacency Matrix' ) –

    Axes title. Default "Adjacency Matrix".

  • source_gdf (GeoDataFrame, default: None ) –

    External GeoDataFrame for column lookups when labels or sort_by is a column name string.

  • tick_fontsize (float, default: None ) –

    Font size for the row and column tick labels. When not provided, the size is auto-scaled based on n (between 5 and 9 pt).

Returns:

  • AdjacencyHeatmapResult

    Result with the axes and captured artists.

Raises:

  • ValueError

    If the adjacency matrix cannot be resolved, if labels/sort_by are column name strings but source is not a SymbolCartogram, or if sequence lengths do not match n.

Examples:

>>> # Basic usage with a SymbolCartogram
>>> plot_adjacency_heatmap(result)
>>> # Label rows/columns from a data column, sorted alphabetically
>>> plot_adjacency_heatmap(result, labels="name", sort_by="label")
>>> # Annotate non-zero cells
>>> plot_adjacency_heatmap(result, show_values=True, value_fmt=".0f")
>>> # Pass a LayoutResult directly
>>> plot_adjacency_heatmap(result.layout_result)
>>> # Pass a raw matrix with explicit labels
>>> import numpy as np
>>> plot_adjacency_heatmap(np.eye(5) * 2, labels=list("ABCDE"))
>>> # Sort by a numeric data column
>>> plot_adjacency_heatmap(result, labels="name", sort_by="population")
>>> # Sort by string category values (alphabetical ascending)
>>> plot_adjacency_heatmap(result, labels="name",
...     sort_by=["high", "low", "medium", "high"])
>>> # Override tick font size
>>> plot_adjacency_heatmap(result, labels="name", tick_fontsize=11)

plot_comparison

plot_comparison(
    original_gdf: GeoDataFrame,
    result: SymbolCartogram,
    column: str | None = None,
    figsize: tuple[float, float] = (14, 6),
    **kwargs: Any,
) -> ComparisonPlotResult

Side-by-side comparison of original geometries and symbols.

Parameters:

  • original_gdf (GeoDataFrame) –

    Original GeoDataFrame.

  • result (SymbolCartogram) –

    Symbol cartogram result.

  • column (str, default: None ) –

    Column for coloring.

  • figsize (tuple, default: (14, 6) ) –

    Figure size.

  • **kwargs (Any, default: {} ) –

    Passed to GeoDataFrame.plot()

Returns:

  • ComparisonPlotResult

    Result with figure, axes, and captured artists.

plot_displacement

plot_displacement(
    result: SymbolCartogram,
    ax: Axes | None = None,
    arrow_scale: float = 1.0,
    arrow_color: str = "red",
    arrow_alpha: float = 0.7,
    show_symbols: bool = True,
    **kwargs: Any,
) -> DisplacementPlotResult

Plot displacement arrows from original centroids to symbol centers.

Parameters:

  • result (SymbolCartogram) –

    Symbol cartogram result.

  • ax (Axes, default: None ) –

    Axes to plot on.

  • arrow_scale (float, default: 1.0 ) –

    Scale factor for arrow width.

  • arrow_color (str, default: 'red' ) –

    Arrow color.

  • arrow_alpha (float, default: 0.7 ) –

    Arrow transparency.

  • show_symbols (bool, default: True ) –

    Whether to show symbols underneath arrows.

  • **kwargs (Any, default: {} ) –

    Passed to result.plot() if show_symbols=True.

Returns:

  • DisplacementPlotResult

    Result with the axes and captured artists.

plot_symbols

plot_symbols(
    result: SymbolCartogram,
    ax: Axes | None = None,
    figsize: tuple[float, float] = (10, 8),
    *,
    source_gdf: GeoDataFrame | None = None,
    facecolor: Any = None,
    cmap: str | dict = "viridis",
    norm: Normalize | None = None,
    vmin: float | None = None,
    vmax: float | None = None,
    alpha: float | str | Sequence | None = 0.9,
    alpha_range: tuple[float, float] = (0.2, 1.0),
    edgecolor: Any = "none",
    edge_cmap: str | dict | None = None,
    linewidth: float | str | Sequence | None = 0.5,
    linewidth_range: tuple[float, float] = (0.5, 3.0),
    hatch: str | Sequence | None = None,
    hatch_map: dict[str, str] | None = None,
    legend: bool = True,
    legend_kwds: dict | None = None,
    edge_legend: bool = True,
    edge_legend_kwds: dict | None = None,
    hatch_legend: bool = True,
    hatch_legend_kwds: dict | None = None,
    linewidth_legend: bool = True,
    linewidth_legend_kwds: dict | None = None,
    alpha_legend: bool = True,
    alpha_legend_kwds: dict | None = None,
    label: str | Sequence | None = None,
    label_color: Any = "black",
    label_cmap: str | dict | None = None,
    label_legend: bool = True,
    label_legend_kwds: dict | None = None,
    label_fontsize: float | str | Sequence | None = 8,
    label_fontsize_range: tuple[float, float] = (6.0, 14.0),
    label_kwargs: dict | None = None,
    zorder: int = 1,
    title: str | None = None,
) -> SymbolsPlotResult

Plot a symbol cartogram with rich, per-symbol visual styling.

Every visual property can be specified in three ways:

  • Globally - a scalar value or color string applied to all symbols.
  • Data-driven - a column name (str) looked up in the cartogram or source data and mapped to the visual channel.
  • Explicitly per-symbol - a list or NumPy array with one value per symbol.

Parameters:

  • result (SymbolCartogram) –

    Cartogram to visualise.

  • ax (Axes, default: None ) –

    Axes to draw on. A new figure is created when not provided.

  • figsize (tuple, default: (10, 8) ) –

    Figure size when creating a new figure.

  • source_gdf (GeoDataFrame, default: None ) –

    External GeoDataFrame used for column lookups (highest priority). Useful when you want to colour by a column not stored on the cartogram itself, e.g. result.plot(source_gdf=my_gdf, facecolor="gdp").

  • facecolor (color, column name, or array-like, default: None ) –

    Symbol fill colour. Accepts:

    • A matplotlib colour string ("steelblue", "#2ca02c").
    • A column name → numeric columns are mapped through cmap / norm; categorical columns are auto-assigned colours from a qualitative palette ("tab10"), overridable by passing a dict to cmap.
    • A 1-D numeric array of length n → mapped through cmap / norm.
    • An (n, 3) or (n, 4) float array of RGB / RGBA values.
    • A list of colour strings or RGBA tuples, one per symbol.

    Defaults to "steelblue" when None.

  • cmap (str or dict, default: 'viridis' ) –

    Colormap for data-driven facecolor. Pass a colormap name string for numeric columns (e.g. "viridis") or a dict of {category: colour} for categorical columns (e.g. {"Europe": "#2ca02c", "Africa": "#d62728"}). Unspecified categories receive auto-assigned "tab10" colours. Default "viridis".

  • norm (matplotlib Normalize, default: None ) –

    Custom normalisation for the colourmap.

  • vmin (float, default: None ) –

    Explicit data range for the colourmap normalisation.

  • vmax (float, default: None ) –

    Explicit data range for the colourmap normalisation.

  • alpha (float, column name, or array-like, default: 0.9 ) –

    Symbol opacity (0 = transparent, 1 = opaque).

    • Scalar float → global opacity.
    • Column name → linearly interpolated into alpha_range.
    • 1-D array of floats → per-symbol opacity.

    Default 0.9.

  • alpha_range ((float, float), default: (0.2, 1.0) ) –

    (min_alpha, max_alpha) used when alpha is a column name. Default (0.2, 1.0).

  • edgecolor (color, column name, or array-like, default: 'none' ) –

    Symbol edge colour. Accepts the same forms as facecolor. Use "none" (default) for no visible border.

  • edge_cmap (str or dict, default: None ) –

    Colormap for edge colour mapping. Accepts the same forms as cmap (string name for numeric, dict for categorical). Falls back to cmap (string only) when None.

  • linewidth (float, column name, or array-like, default: 0.5 ) –

    Edge line width.

    • Scalar float → global width.
    • Column name → linearly interpolated into linewidth_range.
    • 1-D array → per-symbol widths.

    Default 0.5.

  • linewidth_range ((float, float), default: (0.5, 3.0) ) –

    (min_lw, max_lw) used when linewidth is a column name. Default (0.5, 3.0).

  • hatch (str, column name, or sequence, default: None ) –

    Fill hatching.

    • A matplotlib hatch pattern string ("///", "...", etc.) → applied globally.
    • A column name → each unique category is assigned a hatch pattern from _HATCH_DEFAULTS, overridable via hatch_map.
    • A list / array of pattern strings, one per symbol.

    .. note:: Hatching is only visible when edgecolor is not "none". A UserWarning is raised when hatching is requested without a visible edge colour.

  • hatch_map (dict, default: None ) –

    Per-category hatch overrides used when hatch is a column name. Example: {"urban": "///", "rural": "...", "forest": "ooo"}.

  • legend (bool, default: True ) –

    Whether to display a colourbar (numeric column) or patch legend (categorical column) when facecolor is data-driven. Default True.

  • legend_kwds (dict, default: None ) –

    Extra keyword arguments forwarded to Figure.colorbar() (numeric) or Axes.legend() (categorical). Use "title" to set the legend label.

  • edge_legend (bool, default: True ) –

    Whether to display a separate legend for edgecolor when it is data-driven from a different column than facecolor. When both map the same column, only one legend is shown. Default True.

  • edge_legend_kwds (dict, default: None ) –

    Same as legend_kwds but for the edge-colour legend.

  • hatch_legend (bool, default: True ) –

    Whether to display a patch legend showing the hatch-pattern ↔ category mapping when hatch is a data-driven column name. Default True. Has no effect when hatch is a global pattern string or a list.

  • hatch_legend_kwds (dict, default: None ) –

    Standard Axes.legend() keyword arguments for the hatch legend. Additionally accepts a nested "patch_kw" key (dict) for patch appearance (facecolor, edgecolor, linewidth):

    .. code-block:: python

    hatch_legend_kwds={
        "title": "Land use",
        "loc": "lower left",
        "patch_kw": {"facecolor": "lightyellow", "edgecolor": "darkgreen"},
    }
    
  • linewidth_legend (bool, default: True ) –

    Show a discrete line-sample legend when linewidth is data-driven. Displays ~5 representative values as grey lines of increasing thickness. Default True.

  • linewidth_legend_kwds (dict, default: None ) –

    Axes.legend() kwargs for the linewidth legend. Use "title" to override the legend title.

  • label (str, column name, or sequence, default: None ) –

    Per-symbol text labels.

    • A column name → string representation of each value is used.
    • A list / array of strings, one per symbol.
    • None → no labels (default).
  • label_color (color, column name, or array-like, default: 'black' ) –

    Text colour for the labels. Accepts the same forms as facecolor. Default "black".

  • label_cmap (str or dict, default: None ) –

    Colormap for data-driven label_color. Accepts the same forms as cmap. Falls back to cmap (string only) when None.

  • label_fontsize (float, column name, or array-like, default: 8 ) –

    Font size for labels.

    • Scalar float → global size.
    • Column name → linearly interpolated into label_fontsize_range.
    • 1-D array → per-symbol sizes.

    Default 8.

  • label_fontsize_range ((float, float), default: (6.0, 14.0) ) –

    (min, max) font-size range when label_fontsize is a column name. Default (6.0, 14.0).

  • label_kwargs (dict, default: None ) –

    Additional keyword arguments forwarded to Axes.text() for every label (e.g. {"fontweight": "bold", "ha": "left"}).

  • zorder (int, default: 1 ) –

    Matplotlib drawing order for symbol patches. Labels are placed at zorder + 1. Default 1.

  • title (str, default: None ) –

    Axes title.

Returns:

  • Axes

    The axes containing the plot.

Examples:

>>> # Global style
>>> result.plot(facecolor="steelblue", edgecolor="white", linewidth=0.8)
>>> # Data-driven fill → automatic colorbar
>>> result.plot(facecolor="gdp_per_capita", cmap="YlOrRd")
>>> # Data-driven edge colour → second legend auto-added
>>> result.plot(facecolor="steelblue", edgecolor="region")
>>> # Both fill and edge from different columns → two legends
>>> result.plot(facecolor="pop_est", cmap="YlOrRd",
...             edgecolor="region", edge_cmap="Set1")
>>> # Categorical fill with qualitative palette
>>> result.plot(facecolor="continent")
>>> # Categorical fill with partial colour overrides
>>> result.plot(facecolor="continent",
...             cmap={"Europe": "#2ca02c", "Africa": "#d62728"})
>>> # Per-symbol alpha driven by a column
>>> result.plot(facecolor="steelblue",
...             alpha="population", alpha_range=(0.3, 1.0))
>>> # Hatching by category — hatch legend added automatically
>>> result.plot(facecolor="lightgray", edgecolor="black",
...             hatch="land_use",
...             hatch_map={"urban": "///", "rural": "...", "forest": "ooo"})
>>> # Hatch legend with custom patch appearance
>>> result.plot(facecolor="whitesmoke", edgecolor="black",
...             hatch="region",
...             hatch_legend_kwds={"title": "Region",
...                                "patch_kw": {"facecolor": "lightyellow"}})
>>> # Explicit per-symbol array (e.g. random colours)
>>> import numpy as np
>>> result.plot(facecolor=np.random.rand(len(result.symbols), 4), legend=False)
>>> # Labels from a column
>>> result.plot(facecolor="pop_est", label="name")
>>> # Labels with per-symbol colour
>>> result.plot(facecolor="steelblue", label="iso_a3",
...             label_color="region", label_fontsize=7)
>>> # Look up columns from an external GeoDataFrame
>>> result.plot(source_gdf=world_gdf, facecolor="gdp_md_est",
...             label="name", cmap="plasma")

plot_tiling

plot_tiling(
    result: SymbolCartogram,
    ax: Axes | None = None,
    show_symbols: bool = True,
    show_assigned: bool = True,
    show_unassigned: bool = True,
    assigned_color: str = "#d4e6f1",
    unassigned_color: str = "#f5f5f5",
    tile_edgecolor: str = "#999999",
    tile_linewidth: float = 0.5,
    tile_alpha: float = 0.5,
    **kwargs: Any,
) -> TilingPlotResult

Visualize the tiling grid underlying a grid-placement cartogram.

Plots all tile polygons, distinguishing assigned tiles (with a region) from unassigned tiles (empty). Optionally overlays the symbol geometries.

Parameters:

  • result (SymbolCartogram) –

    Symbol cartogram result from grid-based placement.

  • ax (Axes, default: None ) –

    Axes to plot on. Created if not provided.

  • show_symbols (bool, default: True ) –

    Whether to overlay symbol geometries. Default True.

  • show_assigned (bool, default: True ) –

    Whether to show tiles that have a region assigned. Default True.

  • show_unassigned (bool, default: True ) –

    Whether to show unassigned (empty) tiles. Default True.

  • assigned_color (str, default: '#d4e6f1' ) –

    Fill color for tiles that have a region assigned.

  • unassigned_color (str, default: '#f5f5f5' ) –

    Fill color for unassigned (empty) tiles.

  • tile_edgecolor (str, default: '#999999' ) –

    Edge color for tile outlines.

  • tile_linewidth (float, default: 0.5 ) –

    Line width for tile outlines.

  • tile_alpha (float, default: 0.5 ) –

    Fill transparency for tiles.

  • **kwargs (Any, default: {} ) –

    Passed to result.plot() if show_symbols=True.

Returns:

  • TilingPlotResult

    Result with the axes and captured artists.

Raises:

  • ValueError

    If the result is not from grid-based placement.