Skip to content

ECharts adapter correctness and honest visualization tests (#509, #512) - #526

Merged
kgdunn merged 6 commits into
mainfrom
claude/process-improve-library-issues-hr7xxk-viz
Aug 29, 2026
Merged

ECharts adapter correctness and honest visualization tests (#509, #512)#526
kgdunn merged 6 commits into
mainfrom
claude/process-improve-library-issues-hr7xxk-viz

Conversation

@kgdunn

@kgdunn kgdunn commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #509 and Fixes #512.

  • Visualization tests assert tautologies, and test_themes leaks a theme into every later test in the worker #512 (tests only, no adapter behaviour changed): the four TestPlotlyAnnotationRendering tests asserted only "data" in result, which every Plotly figure dict satisfies. They now assert on the rendered layout["shapes"] (count, x0/x1 vs y0/y1, xref/yref to pin the axis, fillcolor) and layout["annotations"], in the style of TestPlotlyContourStyling; the incomplete-band test compares against a band-free baseline so the skip is actually pinned. test_set_theme_changes_default now restores the plotly.io.templates.default value captured before the test (via monkeypatch) instead of forcing the package default, so the theme no longer leaks into later tests in the same xdist worker. The background-colour test no longer claims all four themes are distinct; it pins all four values (pi_tufte and pi_journal deliberately share white).
  • ECharts adapter: annotations land on the wrong panel, missing data fields silently plot as 0, and short colour lists silently drop marks #509 (ECharts adapter):
    • Annotations attach to a series of their own panel: single-panel and multi-panel paths share one _attach_annotations helper (attaching to the panel's first series), and a panel with annotations but no layers gets an empty, silent carrier series bound to its own axes instead of painting the previous panel via all_series[-1].
    • _paired_data and _wireframe_series use direct row[field] lookups, so a missing or typo'd field raises KeyError, matching the Plotly adapter, instead of silently plotting 0.
    • A ragged or wrongly shaped z_matrix in _heatmap_series raises ValueError naming the layer and expected (len(y_grid), len(x_grid)) shape instead of filling cells with 0.
    • The three non-strict zips are now strict=True, preceded by an explicit length check that raises a clear ValueError naming the layer and style key. Decision: types.py documents style as "extra visual properties" with nothing implying a shorter colour list should cycle, and every in-repo producer (experiments/visualization/plots/significance.py) builds colors/error_y one-per-point from the same data, so a length mismatch indicates a bug and raising (not cycling) is the behaviour that matches the spec and visualization/tools.py.
    • MarkType.area and AnnotationType.label are declared in types.py but implemented in neither adapter; both adapters now raise NotImplementedError with a message naming the member, instead of Plotly silently falling back to scatter and ECharts dropping the label.
  • Callers checked: no in-repo caller uses MarkType.area or AnnotationType.label, and all producers of colors/error_y/grid-style layers (src/process_improve/visualization/charts/, src/process_improve/experiments/visualization/plots/, experiments/_tools/visualize_doe.py) build matched-length lists and rectangular matrices, so no caller adjustments were needed; tests/test_experiments_tools.py confirms.
  • Housekeeping: version 1.73.1 in pyproject.toml and CITATION.cff (date-released 2026-08-29), new ## [1.73.1] - 2026-08-29 changelog section with footer links. The version is set assuming the earlier queued PRs (carrying 1.72.x/1.73.0) merge first; if they land differently this needs only a trivial rebase.

Test plan

  • uv run pytest tests/test_visualization_spec.py tests/test_themes.py tests/test_echarts_multi_panel.py tests/test_visualization.py tests/test_viz_boxplot.py --no-cov -q : 240 passed
  • uv run pytest tests/test_experiments_tools.py --no-cov -q : 39 passed (DOE callers of the adapters unaffected)
  • New regression tests: annotation-only middle panel lands on its own panel; single vs multi panel attach identically; missing field raises KeyError; ragged heatmap raises ValueError; short colors/error_y raise ValueError; MarkType.area / AnnotationType.label raise NotImplementedError in both adapters
  • uv run ruff check . and uv run ruff format --check . both pass
  • uv run mypy src/process_improve: only the pre-existing mcp_server.py:39 FastMCP error

Checklist

  • Version bumped in pyproject.toml (PATCH for fixes/docs/config, MINOR for new features)
  • Tests added or updated where relevant
  • ruff check . passes
  • CHANGELOG.md updated

Generated by Claude Code

claude added 3 commits August 29, 2026 00:28
…e leak

The four TestPlotlyAnnotationRendering tests asserted only that the figure
dict has a "data" key, which is true of every Plotly figure, so they passed
whether or not the annotation rendered at all. They now pin layout.shapes
(count, x0/x1 vs y0/y1, axis refs, fillcolor) and layout.annotations, and
the skipped-band test compares against a band-free baseline.

test_set_theme_changes_default restored the package DEFAULT_THEME instead
of the value in effect before the test, mutating plotly.io.templates.default
for every later test in the worker; it now restores the captured prior value
via monkeypatch. The background-colour test's docstring claimed each theme
has a distinct background while asserting two identical white values; it now
pins all four values without the distinctness claim.

Closes #512.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
…ed members

Annotations now attach to a series of the panel they belong to: the
single-panel and multi-panel paths share one _attach_annotations helper,
and a panel with annotations but no layers gets an empty carrier series
bound to its own axes instead of painting the previous panel (the old
code attached to the cumulative all_series[-1]).

Missing data fields raise KeyError instead of silently plotting 0, in
_paired_data and _wireframe_series, matching the Plotly adapter's direct
row[field] lookups. A ragged z_matrix in _heatmap_series raises ValueError
naming the expected shape instead of filling missing cells with 0.

Per-point style lists (colors, error_y) whose length differs from the data
raise ValueError naming the layer and the style key; the three previously
non-strict zips are now strict=True, matching visualization/tools.py.

MarkType.area and AnnotationType.label are declared in types.py but were
implemented in neither adapter; both adapters now raise NotImplementedError
for them instead of silently falling back to a scatter trace or dropping
the annotation.

Closes #509.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
Version assumes the queued PRs carrying 1.72.x/1.73.0 merge first.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
@codecov

codecov Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.83333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
..._improve/visualization/adapters/echarts_adapter.py 97.61% 0 Missing and 1 partial ⚠️
...s_improve/visualization/adapters/plotly_adapter.py 83.33% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

The typecheck gate is red on main itself: the unpinned mcp extra now
resolves to mcp 2.x, where FastMCP was renamed MCPServer, so mypy fails
on mcp_server.py on every branch. This ports the migrated server and the
mcp>=2.0 floor verbatim from #528; the diff no-ops once #528 merges.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU

kgdunn commented Aug 29, 2026

Copy link
Copy Markdown
Owner Author

Two notes on the red checks:

  1. The typecheck failure is not this PR's: it is red on main's own latest runs. The unpinned mcp extra now resolves to mcp 2.x, where FastMCP was renamed MCPServer, so mypy fails on src/process_improve/mcp_server.py everywhere. The fix is PR MCP server: publish real per-tool JSON Schemas (#506) #528; its migrated mcp_server.py and mcp>=2.0 floor are ported verbatim into this branch so CI can go green in any merge order. The ported files disappear from this diff once MCP server: publish real per-tool JSON Schemas (#506) #528 merges.
  2. The test (3.12, ubuntu-latest, false) failure was tests/test_designs_screening_optimal.py::TestDOptimalDispatch::test_budget_clamped_to_minimum_model_size (assert 3 >= 4), in DOE dispatch code this visualization diff does not touch. It passed 6 consecutive local runs, so it looks like a stochastic search flake; the push carrying the port above re-runs it. If it fails again on this head I will treat it as real and root-cause it.

Generated by Claude Code

claude added 2 commits August 29, 2026 06:28
…e-library-issues-hr7xxk-viz

# Conflicts:
#	CHANGELOG.md
#	CITATION.cff
#	pyproject.toml
…e-library-issues-hr7xxk-viz

# Conflicts:
#	CHANGELOG.md
#	CITATION.cff
#	pyproject.toml
@kgdunn
kgdunn merged commit b978d78 into main Aug 29, 2026
14 checks passed
@kgdunn
kgdunn deleted the claude/process-improve-library-issues-hr7xxk-viz branch August 29, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants