Skip to content

chore(palette): fix semantic anchors for 12 matplotlib impls#7777

Merged
MarkusNeusinger merged 2 commits into
mainfrom
chore/imprint-matplotlib-followup
May 27, 2026
Merged

chore(palette): fix semantic anchors for 12 matplotlib impls#7777
MarkusNeusinger merged 2 commits into
mainfrom
chore/imprint-matplotlib-followup

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Summary

Follow-up to #7776. The positional Okabe-Ito → imprint swap broke charts where the old hex carried semantic meaning (red = bad, green = good, amber = warning), not just categorical separation. Slot 1 became lavender, which silently turned "bearish" / "negative" / "critical" / "decrease" markers into purple.

Reaches for imprint semantic anchors (red #AE3030, amber #DDCC77, green #009E73) on the 12 matplotlib impls where the variable name or comment made the semantic intent explicit. Categorical, non-semantic uses of #C475FD (lavender) are left alone.

Files touched

File Fix
gauge-basic ZONE_BAD → red, ZONE_WARN → amber
dashboard-metrics-tiles STATUS_COLORS warning → amber, critical → red
kagi-basic COLOR_YIN (bearish) → red
point-and-figure-basic O_COLOR (falling) → red
horizon-basic neg_base (negative) → red
bar-diverging negative bars + legend → red
renko-basic BEARISH → red
slope-basic COLOR_DEC → red
waterfall-basic DECREASE_COLOR → red
shap-waterfall COLOR_POS (positive SHAP) → red (against blue)
indicator-macd NEGATIVE_COLOR → red; SIGNAL → ochre (re-establishes contrast vs the red NEGATIVE bars)
indicator-ema GOLDEN_COLOR → green, DEATH_COLOR → red; short/long EMA → blue/ochre categorical

Also addresses three nits on the helper scripts from the same review round:

  • migrate_to_imprint.py — docstring for _rename_palette_constant no longer overstates the conservatism of the plain-regex rename
  • migrate_render_and_upload.py — module docstring matches the actual target-discovery flow (working tree or --from-commit), drops a stale reference to a never-implemented .migration-list.json
  • migrate_render_and_upload.py — pre-flight now also checks gsutil version, not just gcloud auth list

What this PR doesn't do

Comment rot in the other ~125 untouched matplotlib impls (e.g. comments still saying "Okabe-Ito vermillion" next to imprint hex codes) is deferred — those refresh naturally on the next daily-regen cycle.

The image regeneration for all matplotlib impls (the 137 from #7776 + the 12 fixed here) hasn't run yet against GCS. That happens locally via scripts/migrate_render_and_upload.py --from-commit <merge-sha> --library matplotlib immediately after this PR merges.

Test plan

  • ruff check . + ruff format --check . green (matches CI)
  • CI green (lint + tests + frontend-tests)
  • Copilot triage
  • After merge: local Stage B for all 137+12 matplotlib impls → GCS production overwrite
  • Spot-check gauge-basic, dashboard-metrics-tiles, kagi-basic on anyplot.ai

🤖 Generated with Claude Code

… follow-up)

The positional Okabe-Ito → imprint swap in #7776 broke charts where
specific hex codes carried *semantic* meaning (red = bad, green = good,
amber = warning) rather than serving as arbitrary categorical slots.
Slot 1 (#D55E00 vermillion) ended up as #C475FD lavender, which silently
turned "bearish" / "negative" / "critical" indicators into purple.

Apply imprint semantic anchors (#AE3030 red, #DDCC77 amber, #009E73 green)
where the surrounding code clearly assigned meaning:

- gauge-basic                 ZONE_BAD/WARN swapped to red/amber
- dashboard-metrics-tiles     STATUS_COLORS warning/critical swapped
- kagi-basic                  COLOR_YIN (bearish) → red
- point-and-figure-basic      O_COLOR (falling) → red
- horizon-basic               neg_base (negative) → red
- bar-diverging               negative bars + legend → red
- renko-basic                 BEARISH → red
- slope-basic                 COLOR_DEC → red
- waterfall-basic             DECREASE_COLOR → red
- shap-waterfall              COLOR_POS (positive SHAP) → red (against blue)
- indicator-macd              NEGATIVE_COLOR → red; SIGNAL line → ochre
                              (red+lavender clashed; ochre re-establishes
                              categorical contrast against MACD blue)
- indicator-ema               GOLDEN_COLOR (bullish cross) → green
                              DEATH_COLOR (bearish cross) → red
                              short/long EMA → blue/ochre categorical

Also addresses three Copilot review nits on the helper scripts:

- migrate_to_imprint.py        docstring for _rename_palette_constant
                               no longer overstates the conservatism of
                               the plain-regex rename
- migrate_render_and_upload.py module docstring matches the actual
                               target-discovery flow (working tree or
                               --from-commit), drops a stale reference
                               to a never-implemented .migration-list.json
- migrate_render_and_upload.py pre-flight now also checks `gsutil version`
                               (not just `gcloud auth list`)

Cosmetic comment cleanups in the same files (Okabe-Ito → imprint) are
included where the line was already touched. The broader comment-rot
sweep across the other ~125 untouched matplotlib impls is deferred —
those will refresh naturally on the next daily-regen cycle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 27, 2026 20:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR follows up on the imprint palette migration by restoring semantic color meaning in selected matplotlib implementations and tightening migration helper script documentation/checks.

Changes:

  • Replaces lavender slot-1 colors with semantic imprint anchors for bad/warning/negative/decrease roles in 12 matplotlib plot scripts.
  • Updates EMA/MACD categorical line colors to preserve contrast while applying semantic crossover/histogram colors.
  • Clarifies migration helper docs and adds --from-commit target discovery plus a gsutil pre-flight check.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
scripts/migrate_to_imprint.py Clarifies palette constant rename behavior in the docstring.
scripts/migrate_render_and_upload.py Updates target discovery docs, adds gsutil preflight, and supports --from-commit.
plots/waterfall-basic/implementations/python/matplotlib.py Uses semantic red for decreases.
plots/slope-basic/implementations/python/matplotlib.py Uses semantic red for decreases.
plots/shap-waterfall/implementations/python/matplotlib.py Uses red/blue diverging anchors for SHAP direction.
plots/renko-basic/implementations/python/matplotlib.py Uses semantic red for bearish movement.
plots/point-and-figure-basic/implementations/python/matplotlib.py Uses semantic red for falling O marks.
plots/kagi-basic/implementations/python/matplotlib.py Uses semantic red for bearish yin lines.
plots/indicator-macd/implementations/python/matplotlib.py Restores red negative bars and adjusts signal-line contrast.
plots/indicator-ema/implementations/python/matplotlib.py Reassigns EMA line colors and semantic crossover marker colors.
plots/horizon-basic/implementations/python/matplotlib.py Uses semantic red for negative bands.
plots/gauge-basic/implementations/python/matplotlib.py Uses red/amber/green semantic traffic-light anchors.
plots/dashboard-metrics-tiles/implementations/python/matplotlib.py Uses green/amber/red semantic status colors.
plots/bar-diverging/implementations/python/matplotlib.py Uses semantic red for negative bars and legend entry.

Comment on lines +22 to +25
# imprint semantic anchors (red / amber / green traffic-light)
ZONE_BAD = "#AE3030" # matte red — semantic bad
ZONE_WARN = "#DDCC77" # amber — semantic warning
ZONE_GOOD = "#009E73" # brand green — semantic good
@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…ollow-up #2)

Copilot reviewer flagged three additional matplotlib impls where the
positional Okabe-Ito → imprint swap produced a semantic mismatch but
the variable name (UP/DOWN, COLOR_DOWN, "overbought") wasn't obvious
enough in my first sweep:

- candlestick-volume   DOWN_COLOR (down days)        #C475FD → #AE3030
- ohlc-bar             COLOR_DOWN (down bars)        #C475FD → #AE3030
- indicator-rsi        overbought zone shade         #C475FD → #AE3030

All three are the same pattern: lavender ended up signalling "down" /
"overbought" because slot-1 of the old palette was an orange-red, and
the positional swap doesn't know about semantic intent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MarkusNeusinger MarkusNeusinger merged commit c99e7c5 into main May 27, 2026
7 checks passed
@MarkusNeusinger MarkusNeusinger deleted the chore/imprint-matplotlib-followup branch May 27, 2026 20:26
MarkusNeusinger added a commit that referenced this pull request May 27, 2026
## Summary

Two small follow-ups uncovered while running Stage B of the imprint
migration locally on the 137 matplotlib impls (PRs #7776 / #7777).

**1. `scripts/migrate_render_and_upload.py` — savefig fallback**

A handful of impls call `plt.savefig(os.path.join(script_dir, ...))`
instead of plain `plt.savefig("plot-{theme}.png")`, so the PNG lands
next to the impl file instead of inside `.regen-preview/{library}/`.
Stage B now moves stray PNGs into the preview dir before checking for
completeness — keeps the script compatible with these impls without
rewriting them.

Affected on the matplotlib pass: `area-cumulative-flow`, `bar-spine`,
`histogram-stepwise`, `indicator-macd`, `line-stepwise`,
`linked-views-selection`. Likely a few more across other Python
libraries once we run those.

**2. `pyproject.toml` — add cartopy / wordcloud / matplotlib-venn to
`plotting` extra**

Three matplotlib add-ons that some specs depend on (`map-projections` →
cartopy, `wordcloud-basic` → wordcloud, `venn-basic` → matplotlib-venn).
Without them, `uv sync --extra plotting` produces a venv that can't
render those three. CI paths are unaffected — the per-library
`lib-matplotlib` extra is intentionally minimal.

## Result on the 137 matplotlib impls

After both fixes + a `--resume` rerun: **137 / 137 ✓** in GCS
production. Without them the first run was 128 / 137 (the 9 failures
above).

## Test plan

- [x] `ruff check .` + `ruff format --check .` green (matches CI)
- [ ] CI green (lint + tests + frontend-tests)
- [ ] Copilot triage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MarkusNeusinger added a commit that referenced this pull request May 27, 2026
## Summary

- Positional hex replacement across **138 seaborn impls** that already
ship light+dark renders, moving them from Okabe-Ito + variant-D to the
canonical **imprint** palette in
[core/palette.py](https://github.com/MarkusNeusinger/anyplot/blob/main/core/palette.py).
Mirrors #7776 for matplotlib.
- Includes proactive **semantic-anchor fixes for 11 seaborn impls**
where slot-1 (now lavender) carried explicit meaning (red =
bad/loss/bearish, amber = warning, green = good). Same pattern as #7777
but applied preemptively before Copilot's first review.
- Picks up the `uv.lock` entries for cartopy / wordcloud /
matplotlib-venn that were missing from #7778.
- Adds `.migration-progress.json` to `.gitignore` (local-only Stage-B
state file).

## Scope filter

Per metadata YAML, only impls with **both** `preview_url_light` and
`preview_url_dark` set are migrated. Single-theme impls are left to the
regular daily-regen rotation. Specs without an existing seaborn impl
don't get a new one.

| Library | Migrated | Already imprint | Skip (single-theme) |
|---|---:|---:|---:|
| seaborn | **138** | 86 | 96 |

## Semantic fixes (proactive, 11 files)

| File | Fix |
|---|---|
| bar-diverging | `LOSS_COLOR` → red |
| candlestick-volume | `SECONDARY` (bear) → red |
| dashboard-metrics-tiles | warning → amber, critical → red |
| gauge-basic | `ZONE_LOW`/`MED` → red/amber traffic-light |
| indicator-macd | `HIST_NEGATIVE` → red, `SIGNAL` → ochre |
| kagi-basic | `color_yin` → red |
| point-and-figure-basic | `BEAR_COLOR` → red |
| renko-basic | `BEARISH` → red |
| shap-waterfall | `COLOR_POS` → red (vs blue NEG) |
| slope-basic | `COLOR_DECREASE` → red |
| waterfall-basic | `ACCENT_RED` → red (was lavender despite the name) |

## What this PR doesn't do

Image regen for the 138 seaborn impls hasn't run yet against GCS. That
happens locally via `scripts/migrate_render_and_upload.py --from-commit
<merge-sha> --library seaborn` immediately after this PR merges.

## Test plan

- [x] `ruff check .` + `ruff format --check .` green
- [x] Idempotency check (second Stage-A run on a sample spec = 0
changes)
- [ ] CI green (lint + tests + frontend-tests)
- [ ] Copilot triage (should be minimal — semantic bugs pre-fixed)
- [ ] After merge: local Stage B for all 138 seaborn impls → GCS
production overwrite
- [ ] Spot-check gauge-basic, dashboard-metrics-tiles,
candlestick-volume on anyplot.ai

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <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.

2 participants