Skip to content

score_plot: let the marker area carry a value (sizes=) - #549

Merged
kgdunn merged 3 commits into
mainfrom
claude/issues-154-156-process-3cu4iq
Sep 7, 2026
Merged

kgdunn merged 3 commits into
mainfrom
claude/issues-154-156-process-3cu4iq

Conversation

@kgdunn

@kgdunn kgdunn commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • A score plot says how extreme an observation is along the components and nothing about how far it sits off them, so a reader needs a second plot for the second question. score_plot(sizes=...) puts that second quantity, typically the SPE, on the marker area, and one plot answers both. It came out of the SBR batch case study, where the two faulty batches are the furthest out in the scores and carry the smallest residuals of the 53, which the sized plot shows at a glance.
  • Area, not diameter, is proportional to the value (Plotly's sizemode="area"), so a marker of twice the area stands for twice the value. One sizeref is computed from the whole series and shared by the plain and the highlighted traces, so a highlighted point keeps its own area rather than being enlarged: two meanings on one channel cannot both be read.
  • settings["size_max"] sets the diameter in pixels of the largest marker (default 26) and size_name names the value in the hover text, so the reader can recover it exactly rather than estimating an area by eye. Both the 2D and the 3D paths take it.
  • Values that cannot be an area are refused rather than drawn: a negative value, a series that does not cover every plotted observation (the offending labels are named), and an all-zero series each raise ValueError.

The parameters are keyword-only and come after fig, so every existing positional call keeps its meaning, and without sizes the markers keep their fixed size and carry no sizemode: the default path is unchanged, which a test pins.

Where it is used. The SBR score plot of the book's batch case studies (kgdunn/pid-book#273, figures kgdunn/figures#91) encodes the batch's squared residual this way, with the legend giving the scale in SPE units. Until this release reaches PyPI the book draws that plot by hand in Plotly; the block collapses to one score_plot(sizes=...) call afterwards.

Test plan

  • uv run ruff check . and uv run ruff format --check . pass
  • uv run mypy src/process_improve passes (163 files)
  • uv run pytest tests/test_multivariate.py tests/test_multivariate_introspection.py: 197 passed, 1 skipped (pre-existing skip)
  • Two new tests: the area encoding (sizemode, the per-point sizes, the sizeref arithmetic, the hover text, and one scale shared with a highlighted trace) and the settings and guards (size_max, and the three refusals)
  • The default path pinned as unchanged: no sizemode, marker size still 7
  • All four gates re-run locally on the merge of main described below, before pushing it

Checklist

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

Merge of main. #548 merged while this PR was open and took 1.81.1, which conflicted here on pyproject.toml, CITATION.cff and CHANGELOG.md. All three are metadata: main does not touch plots.py. Resolved by keeping 1.82.0 (a feature on top of that patch release), keeping both changelog sections with 1.82.0 above 1.81.1, and rebuilding the link footer so [1.82.0] compares against v1.81.1.

Release note. main is at 1.81.1 and untagged. Merging this before cutting the release makes it one release, 1.82.0, which both companion PRs can then target.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LXthGpHLQFfGubBiKFtGAE


Generated by Claude Code

A score plot says how extreme an observation is along the components and
nothing about how far it sits off them, so the reader needs a second plot for
the second question. `sizes=` puts that second quantity, typically the SPE, on
the marker area, and one plot answers both.

Area, not diameter, is proportional to the value, and one scale is shared by
the plain and the highlighted traces, so a highlighted point keeps its own area
instead of being enlarged: two meanings on one channel cannot both be read.
`settings["size_max"]` sets the largest marker and `size_name` names the value
in the hover text, so a reader can recover it exactly. A negative value, a
series that does not cover every observation, or an all-zero series raises
rather than drawing a plot that cannot be read.

The default path is untouched: without `sizes` the markers keep their fixed
size and carry no `sizemode`.

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

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…-process-3cu4iq

# Conflicts:
#	CHANGELOG.md
#	CITATION.cff
#	pyproject.toml
…-process-3cu4iq

# Conflicts:
#	CHANGELOG.md
#	CITATION.cff
#	pyproject.toml
@kgdunn
kgdunn merged commit 2643f1d into main Sep 7, 2026
11 checks passed
@kgdunn
kgdunn deleted the claude/issues-154-156-process-3cu4iq branch September 7, 2026 10:31
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