Skip to content

Stop citing a normal-vision failure as an argument for shape (#199, #532) - #533

Open
realmarcin wants to merge 1 commit into
mainfrom
palette-normal-vision-532
Open

Stop citing a normal-vision failure as an argument for shape (#199, #532)#533
realmarcin wants to merge 1 commit into
mainfrom
palette-normal-vision-532

Conversation

@realmarcin

Copy link
Copy Markdown
Contributor

The finding

Ran the dataviz rubric's palette validator against the shipped network palette — the one check the rubric says never to eyeball. It fails the normal-vision floor:

[FAIL] Normal-vision floor  #56bbe6 ↔ #57c7ab  ΔE 10.3 (normal) — below 15
[FAIL] Lightness band       #edab12 at L 0.783

Mutualism and Cross-feeding are the two commonest interaction types, and a full-colour reader cannot reliably separate them.

The template already knew that number, and drew the wrong conclusion

Its comment cited ΔE 10.3 as evidence that shape "is not a courtesy to CVD readers, it is what makes two of the commonest types separable at all."

That has it backwards. Shape rescues the CVD case; the rubric is explicit that the normal-vision floor is not excusable by secondary encoding. The number is a defect, not a justification. Corrected in place — that is the whole diff.

Why no colours changed

A half-fix would trade one failure for another, and both obvious swaps do exactly that:

swap clears then fails
#56bbe6 → #2a7fd4 rubric normal-vision floor this repo's all-pairs gate, ΔE 5.5 vs #7f30cf (deutan)
#edab12 → #b8860b lightness band ΔE 1.5 from Commensalism #cf7830 (deutan)

That second one is instructive: the validator never compared that pair, because it checks adjacent entries and those two are not neighbours in the list. The repo's own all-pairs test caught it on the first run.

The two gates disagree, which is the real finding

  • validate_palette.jsOKLab ΔE×100, adjacent pairs
  • tests/test_network_palette.pyCIELAB ΔE76, all pairs, including the greys

Different metric and different pair set. Optimising against either alone produces a change that looks verified and isn't. Neither is wrong; only satisfying both is meaningful.

Searched rather than guessed

  • 775 single candidates clearing the repo's 15.0 all-pairs floor → every one that also passed the OKLab checks was a cyan, re-introducing the blue-blue adjacency the change was meant to remove.
  • ~207k saturated warm pairs for the two warm slots → none passed both; the best failed the normal-vision floor against #a91919.
  • Relaxing chroma finds solutions the validator rejects as reading grey.

Nine mutually separable saturated hues is at or past what the space allows with CVD simulation and two metrics both binding — which is precisely what the rubric means by folding a ninth series into "Other", small multiples, or composite encoding. The fix is structural, not a better hex.

Also confirmed for #199

The brand hero gradient is now on both community_umap.html and community.html, so that open item is done. The remaining one — filters below the plot — is recorded there as a deliberate layout choice.

Checks

  • uv run pytest tests/ — 2375 passed, 16 skipped (test_network_palette.py 9 passed)
  • just lint, just check-docs-current — exit 0

Advances #199. Defect tracked in #532 with the full search recorded.

🤖 Generated with Claude Code

)

Running the dataviz rubric's validator — the one check it says never to eyeball
— the network palette FAILS the normal-vision floor: Mutualism #56bbe6 and
Cross-feeding #57c7ab are ΔE 10.3 apart, below 15, so a full-colour reader
cannot reliably separate the two commonest interaction types.

The template already knew that number. Its comment cited it as evidence that
shape "is what makes two of the commonest types separable at all". That has it
backwards: shape rescues the CVD case, and the rubric is explicit that the
normal-vision floor is NOT excusable by secondary encoding. The number is a
defect, not a justification.

No colours changed, because it is not a one-colour fix and a half-fix would
trade one failure for another. #56bbe6 -> #2a7fd4 clears the rubric and then
fails this repo's own all-pairs gate at ΔE 5.5 against #7f30cf under
deuteranopia. #edab12 -> #b8860b clears the lightness band and lands ΔE 1.5 from
Commensalism — a pair the validator never compared, because it only checks
adjacent entries and those two are not neighbours.

The two gates use different metrics over different pair sets: OKLab ΔE×100
adjacent-pairs against CIELAB ΔE76 all-pairs. Optimising against either alone
produces a change that looks verified and is not. A search over 775 single
candidates and ~207k saturated warm pairs found nothing clearing both without
either re-introducing a blue-blue adjacency or reading grey.

So nine mutually separable saturated hues is at or past what the space allows,
which is what the rubric means by folding a ninth series into "Other". The fix
is structural. The comment now says so, with the measurements, so the next
attempt starts from them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant