Summary
viz smart --smarter applies inequality framing (Gini + Lorenz curve) to any additive measure with high Gini — but on a table whose unit is a heterogeneous project, a high Gini is expected and is not an equity finding. The inequality vocabulary reads to the public as unfairness, inviting a serious misread.
Why this matters
- The CPDB unit is "capital project," and projects are radically heterogeneous — a subway extension should cost a thousand times a playground resurfacing. Concentration across heterogeneous units is nearly tautological, so "NYC capital spending is wildly unequal (Gini 0.96)" is true and meaningless.
- Zero-inflation conflates two populations. With 45–60% zeros, the flat run of the Lorenz curve is the zeros — projects with nothing committed/spent yet (a funding-pipeline stage), not "small/poor" projects. Measured inequality is partly a pipeline artifact.
Proposal
- Gate or caveat the Gini/Lorenz framing: prefer it when the row unit is a person/household/geography, and add a caveat when the unit is a heterogeneous entity.
- When zero-share is high, label the flat Lorenz segment as the zero/not-yet-funded stage and/or additionally report Gini on the non-zero subset.
- Consider surfacing the planned → committed → spent pipeline (currently buried in
% zeros title annotations) as a funnel — the actually-actionable governance signal.
Related: the inequality-panel encoding itself is covered separately in the skew-aware-encoding issue.
Reproducing example
viz smart --smarter on the NYC Capital Projects Database (Checkbook NYC-sourced), 12,587 rows:
curl -s "https://data.cityofnewyork.us/resource/fi59-268w.csv?\$select=maprojid,magencyacro,magencyname,description,typecategory,totalplannedcommit,commit_total,spent_total,spent_total_checkbooknyc&\$limit=20000" -o cpdb.csv
qsv viz smart cpdb.csv --smarter --output cpdb_dashboard.html
The money columns are extremely right-skewed and zero-inflated (Gini 0.93–0.96; 45–60% zeros).
Filed from a critical design review of the viz smart dashboard; part of a set (skew-aware encoding, robust stats, redundant-dimension collapse, inequality-framing guard, 3D/density panels).
Status (updated 2026-07-25)
Two of the three asks shipped in #4280 (commit c5589d4). This issue stays open for ask 3 only — do not close it as completed.
Done — asks 1 & 2
Every Lorenz panel now carries a caveat line beneath its title:
| zero share |
subtitle |
| < 30% |
concentration is expected unless rows are comparable units |
| ≥ 30% |
flat run = 60% zeros, not small values · concentration is expected unless rows are comparable units |
Two decisions worth recording, since both were judgement calls:
- The unit caveat is unconditional — there is no gate. There is no row-unit signal anywhere in the stats cache: whether a row is a person, a household, a geography or a heterogeneous capital project is semantics, not a statistic. A name-heuristic proxy would either delete a legitimate equity finding or silently keep a misleading one, so every Lorenz panel carries the caveat instead. No gate, no false negatives.
- No Gini over the non-zero subset. The panel's Gini is the cached coefficient, never recomputed, so it agrees with the box hint / pivotp / scoresql. A subset Gini would break that contract for a second number readers would conflate with the first. The zero-run label conveys the same information without recomputing anything.
The zero share comes from the existing zero_share() helper, and ZERO_SHARE_MIN was hoisted out of box_shape_hint so the caveat and the % zeros box-title hint read one threshold through one helper — they appear on the same dashboard and must not disagree.
Remaining — ask 3: the pipeline funnel
Surfacing planned → committed → spent as a funnel is untouched. It is a larger piece of work than the two above:
- a new
PanelKind plus its render arms (typed subplot grid and inline), and a new data pass
- an unsolved design question: how does
viz smart recognise that a set of measures forms a pipeline? Column-name heuristics, dictionary concept/role, or an explicit flag. This has the same shape as the unit-heterogeneity problem above — it is semantics, not a statistic — so it deserves the same explicit treatment rather than a guessed proxy.
- a monotonicity question: the funnel framing only holds if each stage is a subset of the prior one, which is worth verifying from the data rather than assuming.
Summary
viz smart --smarterapplies inequality framing (Gini + Lorenz curve) to any additive measure with high Gini — but on a table whose unit is a heterogeneous project, a high Gini is expected and is not an equity finding. The inequality vocabulary reads to the public as unfairness, inviting a serious misread.Why this matters
Proposal
% zerostitle annotations) as a funnel — the actually-actionable governance signal.Related: the inequality-panel encoding itself is covered separately in the skew-aware-encoding issue.
Reproducing example
viz smart --smarteron the NYC Capital Projects Database (Checkbook NYC-sourced), 12,587 rows:The money columns are extremely right-skewed and zero-inflated (Gini 0.93–0.96; 45–60% zeros).
Filed from a critical design review of the
viz smartdashboard; part of a set (skew-aware encoding, robust stats, redundant-dimension collapse, inequality-framing guard, 3D/density panels).Status (updated 2026-07-25)
Two of the three asks shipped in #4280 (commit
c5589d4). This issue stays open for ask 3 only — do not close it as completed.Done — asks 1 & 2
Every Lorenz panel now carries a caveat line beneath its title:
concentration is expected unless rows are comparable unitsflat run = 60% zeros, not small values · concentration is expected unless rows are comparable unitsTwo decisions worth recording, since both were judgement calls:
The zero share comes from the existing
zero_share()helper, andZERO_SHARE_MINwas hoisted out ofbox_shape_hintso the caveat and the% zerosbox-title hint read one threshold through one helper — they appear on the same dashboard and must not disagree.Remaining — ask 3: the pipeline funnel
Surfacing planned → committed → spent as a funnel is untouched. It is a larger piece of work than the two above:
PanelKindplus its render arms (typed subplot grid and inline), and a new data passviz smartrecognise that a set of measures forms a pipeline? Column-name heuristics, dictionaryconcept/role, or an explicit flag. This has the same shape as the unit-heterogeneity problem above — it is semantics, not a statistic — so it deserves the same explicit treatment rather than a guessed proxy.