Skip to content

feat(plotly): implement bar-drilldown#7508

Open
github-actions[bot] wants to merge 5 commits into
mainfrom
implementation/bar-drilldown/plotly
Open

feat(plotly): implement bar-drilldown#7508
github-actions[bot] wants to merge 5 commits into
mainfrom
implementation/bar-drilldown/plotly

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Implementation: bar-drilldown - python/plotly

Implements the python/plotly version of bar-drilldown.

File: plots/bar-drilldown/implementations/python/plotly.py

Parent Issue: #3783


🤖 impl-generate workflow

github-actions Bot added 2 commits May 20, 2026 11:24
Regen from quality 91. Addressed:
- Changed domain from geographic-regions+revenue to time-based hierarchy
  (2024 year → quarter → month) per cross-library divergence change request
- Added ANYPLOT_THEME env var and full theme-adaptive chrome (PAGE_BG,
  INK, INK_SOFT, GRID, ELEVATED_BG) — previous used hardcoded white/dark
- Fixed title format: pyplots.ai → anyplot.ai, added "python" language token
- Fixed file naming: plot.png/plot.html → plot-{THEME}.png/plot-{THEME}.html
- Fixed canvas size: 1600×900 scale=3 → 800×450 scale=4 (3200×1800 target)
- Replaced Python-blue (#306998) with Okabe-Ito palette (#009E73 first)
- Removed def functions (get_children, get_breadcrumb_path) — CQ-01 fix
- Added sys.path fix to prevent local plotly.py shadowing the package
- Increased grid alpha 0.10 → 0.15 for slightly better visibility (VQ-07)
- Switched include_plotlyjs=True → 'cdn' for lighter HTML output
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 20, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Bar chart on a warm off-white #FAF8F1 background showing four quarterly bars for 2024 Retail Sales. Q1 (green #009E73), Q2 (orange #D55E00), Q3 (blue #0072B2), Q4 (pink #CC79A7) — correct Okabe-Ito order. A dropdown control in the top-left corner reads "▶ 2024 Annual — All Quarters". Value labels ($1.24M, $1.68M, $2.14M, $2.38M) are positioned above each bar in dark ink. X-axis shows quarter names; Y-axis shows "Revenue ($K)" with tick values. A footer annotation reads "Select a level from the dropdown to drill into monthly detail." Title "2024 Retail Sales · bar-drilldown · python · plotly · anyplot.ai" is centered at the top. All text is clearly readable against the light background — PASS.

Dark render (plot-dark.png): Identical layout on a warm near-black #1A1A17 background. Title, axis labels, tick labels, and value labels all render in light cream/off-white text — no dark-on-dark failures observed. The dropdown control uses the elevated dark fill (#242420) with light border and light text. Data colors (green, orange, blue, pink bars) are visually identical to the light render — Okabe-Ito positions 1–4 are theme-independent as required. Subtle light horizontal grid lines visible on Y-axis. All text is readable against the dark background — PASS.

Both paragraphs are required. A review that only describes one render is invalid.

Score: 85/100

Category Score Max
Visual Quality 29 30
Design Excellence 10 20
Spec Compliance 14 15
Data Quality 14 15
Code Quality 9 10
Library Mastery 9 10
Total 85 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (title=16, axis=12, ticks=10, labels=12); INK token threads through textfont so value labels flip correctly in dark theme; proportions well-balanced
  • VQ-02: No Overlap (6/6) — No text overlaps; value labels cleanly above bars; no collisions
  • VQ-03: Element Visibility (6/6) — 4 bars clearly visible with good width and height; bars well-differentiated by color
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito palette is CVD-safe; good luminance contrast between bars and background in both themes
  • VQ-05: Layout & Canvas (3/4) — Good overall layout; however margin.b=110 creates noticeable excess whitespace at the bottom below the instructional annotation; canvas could be used slightly better
  • VQ-06: Axis Labels & Title (2/2) — "Quarter" and "Revenue ($K)" are descriptive with units
  • VQ-07: Palette Compliance (2/2) — First bar #009E73; Okabe-Ito order 1–4 followed; backgrounds #FAF8F1 (light) / #1A1A17 (dark); theme chrome correct in both renders

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) — Clean, well-configured implementation following the style guide, but does not rise above configured defaults: no visual hierarchy emphasising Q4 peak, no subtle polish distinguishing it as a standout design
  • DE-02: Visual Refinement (4/6) — Good refinement: x-axis grid disabled, subtle y-axis grid, bar edges styled with PAGE_BG for definition, L-shaped axis frame. Spines not explicitly removed but plotly's axis-line-only approach achieves similar result
  • DE-03: Data Storytelling (2/6) — Revenue increases Q1→Q4, which is visible from bar heights, but no visual emphasis tells the story: Q4 (holiday peak at $2.38M) is not highlighted, no trend indicator, no callout for the most important insight

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) — Bar/column chart with hierarchical drilldown via animation frames and dropdown; one level at a time; correct chart type
  • SC-02: Required Features (3/4) — Breadcrumbs embedded in axis title ("Path: 2024 > Q3") ✓; animation transitions (400ms) ✓; value labels ✓; back navigation via dropdown ✓. However: (1) click-on-bar drilling replaced by dropdown (technically unavoidable without Dash, acceptable compromise); (2) only Q3 and Q4 have monthly drill-down — Q1 (Jan–Mar) and Q2 (Apr–Jun) are listed in the dropdown but have no dedicated frames, making them non-drillable
  • SC-03: Data Mapping (3/3) — X=quarters/months, Y=revenue in $K; all data visible; axes correctly labelled
  • SC-04: Title & Legend (3/3) — Title "2024 Retail Sales · bar-drilldown · python · plotly · anyplot.ai" matches required format; frame titles for q3/q4 also correct; no legend (single-level series at any time, no legend needed)

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — Shows a 2-level hierarchy (quarters → months) with navigation. However only 2 of 4 quarters (Q3, Q4) have monthly detail — Q1 and Q2 are shown in the dropdown but navigating to them just repeats the annual view, not a true drill-down
  • DQ-02: Realistic Context (5/5) — 2024 Retail Sales with time-based year→quarter→month hierarchy is a real, comprehensible, neutral business scenario
  • DQ-03: Appropriate Scale (4/4) — Values are internally consistent and realistic: Q4 ($2.38M) is the peak (holiday season), November ($940K) is the monthly peak within Q4 (Black Friday), monthly totals sum correctly to quarterly totals

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) — Clean linear structure: imports → theme tokens → data → plot → save; no functions or classes
  • CQ-02: Reproducibility (2/2) — All data hardcoded (no randomness); fully deterministic
  • CQ-03: Clean Imports (2/2) — Only os, sys, plotly.graph_objects imported; sys.path manipulation is a legitimate workaround to prevent the file from shadowing the plotly package
  • CQ-04: Code Elegance (1/2) — Three nearly-identical bar_kwargs_* dicts with repeated keys (textposition, cliponaxis, etc.) could be factored into a shared base dict; # noqa: E402 inline lint-suppression comment present (project rules disallow disable comments)
  • CQ-05: Output & API (1/1) — Saves plot-{THEME}.png and plot-{THEME}.html with correct naming; current plotly API used

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (5/5) — Uses go.Figure with fig.frames, go.Frame, and updatemenus with method="animate" — the idiomatic plotly pattern for animated drilldown; write_html with include_plotlyjs="cdn" is best practice
  • LM-02: Distinctive Features (4/5) — Animation frames + dropdown updatemenus is a genuinely Plotly-distinctive capability (no other static library can do this in a self-contained script); smooth transitions (400ms frame + 250ms ease) are a Plotly strength. Minor deduction: click-on-bar callbacks via Dash would be even more distinctive, but that requires a server runtime beyond scope

Score Caps Applied

  • None — DE-01=4 (>2), so "correct but boring" cap does not apply; CQ-04=1 (>0), no fake-functionality cap

Strengths

  • Correct use of Plotly animation frames + dropdown updatemenus — the idiomatic approach for drilldown in a standalone script
  • Full theme-adaptive chrome: all tokens (INK, INK_SOFT, PAGE_BG, ELEVATED_BG, GRID) applied consistently to dropdown, axis labels, tick labels, value text, and bar edges
  • Smooth transitions (400ms frame, 250ms ease) give the chart a polished interactive feel in the HTML output
  • Okabe-Ito palette in correct order; first series correctly #009E73; frame-level titles follow the required format

Weaknesses

  • Q1 and Q2 have no monthly drill-down frames; clicking them in the dropdown just shows the annual view — add go.Frame(name="q1", ...) and go.Frame(name="q2", ...) with January/February/March and April/May/June monthly breakdowns
  • No visual storytelling emphasis: Q4 is the holiday-season peak ($2.38M) but nothing draws the eye to it — consider a subtle marker annotation (e.g., a small star/arrow annotation) or a slightly distinct bar opacity/pattern for the highest bar
  • Three bar_kwargs_* dicts repeat identical keys; refactor into a shared _base_bar_kwargs dict and merge with per-level overrides using {**_base, ...}
  • # noqa: E402 lint-suppression comment violates project style rules — restructure the import block (move the sys.path manipulation into a helper or use importlib) so the noqa is unnecessary, or at minimum remove the comment and accept the linter warning silently
  • Bottom margin (margin.b=110) creates excess whitespace below the footer annotation — reduce to ~70–80 to tighten the canvas

Issues Found

  1. SC-02 / DQ-01 PARTIAL: Only Q3 and Q4 are drillable — Q1 and Q2 are missing monthly frames
    • Fix: Add go.Frame(name="q1", ...) with Jan/Feb/Mar data ($400K / $430K / $410K approx) and go.Frame(name="q2", ...) with Apr/May/Jun data; add corresponding dropdown buttons
  2. DE-03 LOW: No visual hierarchy; the rising seasonal trend and Q4 peak are not visually emphasized
    • Fix: Add a subtle annotation arrow or label highlighting Q4 as the peak; OR reduce opacity of non-peak bars slightly when in annual view; OR add a short trend annotation ("Q4 peak: holiday season")
  3. CQ-04 MINOR: Repeated bar_kwargs_* dicts + noqa comment
    • Fix: Extract shared keys into a base dict; restructure to avoid needing the noqa

AI Feedback for Next Attempt

Add monthly drill-down frames for Q1 and Q2 (currently missing) to make all four quarters drillable. Then improve data storytelling: highlight Q4 as the holiday-season peak with a subtle annotation or visual emphasis (e.g., a small annotation "Holiday peak ↑" near Q4's label). Refactor the three bar_kwargs_* dicts into a shared base dict with per-level merges to reduce repetition, and remove the # noqa: E402 comment. Reduce margin.b from 110 to ~75 to eliminate excess bottom whitespace.

Verdict: REJECTED

@github-actions github-actions Bot added quality:85 Quality score 85/100 ai-rejected Quality not OK, triggers update labels May 20, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels May 20, 2026
Attempt 1/3 - fixes based on AI review
@github-actions
Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 20, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white background (#FAF8F1). Four Okabe-Ito bars left to right: Q1 green (#009E73), Q2 vermillion (#D55E00), Q3 blue (#0072B2), Q4 pink (#CC79A7). Q1–Q3 are rendered at 75% opacity (subtle muting) while Q4 is at full opacity, drawing the eye to the holiday peak. Value labels ($1.24M, $1.68M, $2.14M, $2.38M) in dark ink above each bar. A ★ Holiday Peak annotation in Q4 pink sits in the upper-right area. Title "2024 Retail Sales · bar-drilldown · python · plotly · anyplot.ai" centered at top in dark text, spanning ~75% of canvas width. Y-axis label "Revenue ($K)", x-axis label "Quarter" — both clearly readable. Tick labels in muted grey. Footer instruction below x-axis. Dropdown button "▶ 2024 Annual — All Quarters ▼" top-left with elevated background. Subtle horizontal grid on y-axis only. All text is readable against the light background — no light-on-light issues.

Dark render (plot-dark.png): Warm near-black background (#1A1A17). All four bar colors are identical to the light render — Q1 #009E73, Q2 #D55E00, Q3 #0072B2, Q4 #CC79A7. Bar value labels render in light cream (#F0EFE8) above each bar. Title, axis labels, and tick labels all flip to light-colored text against the dark surface — clearly readable. Dropdown button uses elevated dark background (#242420) with light text — readable. ★ Holiday Peak annotation in Q4 pink is still visible on the dark surface. Grid lines are subtly visible as light-on-dark. Bar edges (matching #1A1A17) create a clean visual separator between bars. No dark-on-dark failures — chrome adapts correctly across the board.

Both paragraphs are required. A review that only describes one render is invalid.

Score: 89/100

Category Score Max
Visual Quality 30 30
Design Excellence 13 20
Spec Compliance 14 15
Data Quality 15 15
Code Quality 9 10
Library Mastery 8 10
Total 89 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8) — All font sizes explicitly set (title=16, axis=12, ticks=10, bar labels=12). Proportional and readable at full resolution and mobile scale in both themes.
  • VQ-02: No Overlap (6/6) — Bar labels above bars, Holiday Peak annotation clear of value labels, footer below axis. No collisions.
  • VQ-03: Element Visibility (6/6) — Four large bars clearly visible. Opacity differential (0.75 vs 1.0) adds emphasis without obscuring any element.
  • VQ-04: Color Accessibility (2/2) — Okabe-Ito palette is CVD-safe. Good luminance contrast bars-vs-background in both themes.
  • VQ-05: Layout & Canvas (4/4) — Well-proportioned margins (t=80,b=80,l=80,r=40). Dropdown cleanly positioned top-left. Footer adds breathing room.
  • VQ-06: Axis Labels & Title (2/2) — Y-axis "Revenue ($K)" with units. X-axis drill levels embed breadcrumb ("Month · Path: 2024 > Q1").
  • VQ-07: Palette Compliance (2/2) — First series #009E73. Okabe-Ito canonical order. Backgrounds #FAF8F1 / #1A1A17. Chrome flips correctly in both renders.

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — Above well-configured default: opacity differential for storytelling emphasis, Unicode-arrow styled dropdown buttons, bar edges matching background for clean separation. Not quite FiveThirtyEight-level polish but intentional design thought is evident.
  • DE-02: Visual Refinement (4/6) — Y-axis grid only (x hidden), no legend, bar edge separator. Meaningful refinement beyond defaults.
  • DE-03: Data Storytelling (4/6) — Clear focal point: Q4 at full opacity with Holiday Peak annotation versus muted Q1–Q3. Breadcrumb path updates per drill frame. Growing retail trend with holiday peak is immediately readable.

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5) — Column/bar chart with hierarchical drilldown. Two-level hierarchy (annual quarters → monthly detail) implemented via Plotly animation frames.
  • SC-02: Required Features (3/4) — Value labels ✓, animated transitions ✓, breadcrumb navigation ✓, back navigation via dropdown ✓. Minor: drilldown triggered by dropdown rather than direct bar click; color identity not maintained across drill levels (all months reuse OKABE_ITO[:3]).
  • SC-03: Data Mapping (3/3) — X=quarters/months, Y=revenue. All data visible. Axes correctly labeled at each drill level.
  • SC-04: Title & Legend (3/3) — Title follows {Descriptive} · bar-drilldown · python · plotly · anyplot.ai format. No legend (correct — categorical bar chart without series legend needed).

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — All 4 quarters at top level, all 3 months per quarter at detail level. Demonstrates full two-level hierarchy with meaningful variation across categories.
  • DQ-02: Realistic Context (5/5) — 2024 retail sales with quarterly/monthly breakdown. Holiday Q4 peak is realistic. Neutral business scenario.
  • DQ-03: Appropriate Scale (4/4) — Monthly values sum exactly to quarterly totals. November highest month (holiday shopping) is plausible. ~$7.44M annual for a mid-size retailer is factually reasonable.

Code Quality (9/10)

  • CQ-01: KISS Structure (3/3) — Flat imports → data → plot → save. No functions or classes. sys.path manipulation is a standard monorepo best practice.
  • CQ-02: Reproducibility (2/2) — Hardcoded deterministic data; no random seed needed.
  • CQ-03: Clean Imports (2/2) — Only importlib, os, sys — all used.
  • CQ-04: Code Elegance (1/2) — Shared _bar_chrome dict with ** unpacking is clean. However, 5 nearly-identical bar_kwargs_qX dicts and 5 near-identical frames repeat ~60 lines that a short loop/list would eliminate without sacrificing the flat KISS structure.
  • CQ-05: Output & API (1/1) — plot-{THEME}.png and plot-{THEME}.html with correct theme suffix. Current Plotly API.

Library Mastery (8/10)

  • LM-01: Idiomatic Usage (4/5) — go.Figure, go.Bar, go.Frame with updatemenus animate method is the correct Plotly GO pattern for frame-based navigation. Per-frame layout/axis/title updates are idiomatic.
  • LM-02: Distinctive Features (4/5) — Named go.Frame objects with per-frame layout updates + updatemenus animate method is distinctly Plotly — enables smooth animated transitions between hierarchy levels with axis/title/annotation updates per state. Not replicable in static libraries.

Score Caps Applied

  • None — no caps triggered.

Strengths

  • Full theme-adaptive chrome in both renders: backgrounds, text, grid, and dropdown all flip correctly between light (#FAF8F1) and dark (#1A1A17)
  • Opacity storytelling: Q1–Q3 muted at 0.75, Q4 at 1.0 with Holiday Peak annotation — creates a clear visual focal point
  • Frame-based drilldown via go.Frame + updatemenus animate: title and breadcrumb path update per frame, using distinctly Plotly animation API
  • Internally consistent hierarchical data: monthly values sum exactly to quarterly totals across all four quarters
  • All font sizes explicitly set and proportional in both renders

Weaknesses

  • SC-02: Drilldown triggered by dropdown menu rather than direct bar click — spec says "Click on a column to drill into its sub-level breakdown"
  • Color identity not maintained across drill levels: all monthly views reuse OKABE_ITO[:3], so January and April are both green (spec: "maintain consistent color mapping across drill levels when possible")
  • CQ-04: Five nearly-identical bar_kwargs_qX dicts + five frames are verbose; a short loop would eliminate ~60 lines
  • DE-01/DE-02: Could push further — stronger typographic hierarchy between title and axis labels, or more prominent visual cue on the interactive dropdown

Issues Found

  1. SC-02 MINOR: Drilldown uses dropdown, not click-on-bar. True click callbacks without Dash require raw JS — this is a known Plotly limitation in pure Python. The current approach is the idiomatic Plotly alternative.
  2. CQ-04 MINOR: Repeated bar_kwargs_qX / frame definitions — verbose but not a blocking issue.

AI Feedback for Next Attempt

If a repair attempt is triggered: (1) Assign distinct color identities across drill levels — e.g., each quarter's monthly bars retain that quarter's Okabe-Ito color rather than cycling from position 1. (2) Reduce bar_kwargs_q1/q2/q3/q4 repetition using a list/loop. (3) Consider a visual "click to drill" hint on the bars (tooltip or bar annotation) to better signal interactivity.

Verdict: APPROVED

@github-actions github-actions Bot added quality:89 Quality score 89/100 ai-approved Quality OK, ready for merge and removed quality:85 Quality score 85/100 labels May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:89 Quality score 89/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants