Skip to content

Add size-controlled mesh cartograms (non-contiguous, layer-unrolled, focus+context) for per-element scalar fields #219

Description

@domattioli

Summary

CHILmesh should provide reusable cartogram plotting so a per-element (or per-vertex) scalar field can be read without large elements visually dominating small ones. A geographic, area-weighted tripcolor of a 98,365-element WNAT mesh devotes most of the canvas to coarse open-ocean elements and shrinks the refined coastline — where the signal concentrated — to sub-pixel threads. Three prototype views (QuADMESH#96 / QuADMESH#97) solved this; they are mesh-generic and belong in CHILmesh.

Motivation

The QuADMESH+ Monte-Carlo layer-pass study measured a per-triangle pass-frequency. On WNAT_Hagen the ever-routed elements are 9.9% of the mesh and the always-routed 4.9%, concentrated in the fine coastal band; the plain map renders them invisible. Equalizing visual weight per element exposed real structure — start-dependent "swing" triangles cluster at specific layer-and-angle locations in the deep small layers (L21–L25). The large-element-dominance problem is general to any scalar on any non-uniform mesh.

Prototype to generalize (QuADMESH experiments/mc_layer_pass/)

  • cartogram_noncontig — each element redrawn at equal area about its centroid, geographic position preserved.
  • cartogram_unrolled — skeleton layers unrolled into equal-height bands; each element an equal-width cell ordered by angle. Built from CHILmesh layers + paths_on_outer_vertices.
  • cartogram_hybrid — focus+context: element extent ∝ |value − reference| + ε, reference ∈ {mean, median, mode, max, min}.

Proposed API

fig, ax = mesh.cartogram(values, kind="unrolled"|"noncontig"|"hybrid", reference="mean", cmap="inferno", ax=None) — per-element or per-vertex array, returns Matplotlib handles.

Iteration backlog (presentation + utility)

  • Non-contiguous overlap/gaps: Dorling equal-circle option and/or contiguous Gastner–Newman diffusion cartogram.
  • Unrolled band height: equal-per-layer (current) vs count-weighted vs log-count.
  • Within-band ordering: true OV-path arc-length vs centroid angle; multi-loop layers + islands.
  • Mixed tri/quad element support; diverging colormaps + percentile-clip + colorblind-safe defaults.
  • PolyCollection batching/decimation for 10⁶-element meshes; optional hover interactivity; gallery doc + tests.

Acceptance

API + docstrings (MATLAB-help register), gallery page, unit/smoke tests, and reproduction of the QuADMESH pass-frequency cartograms directly from CHILmesh.

References

QuADMESH PR #96 (branch monte-carlo-quality-analysis), issue #97; prototypes cartogram.py, cartogram_hybrid.py. Gastner & Newman (2004); Dorling (1996).

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: somedayBackground; pick when queue thins.request: researchRequest for an investigation; deliverable is a report.status: brainstormingDesign phase; not yet implementable. Agents do NOT open a PR while in this state.type: featNew capability or skill.

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions