Skip to content

Add zoom-responsive styling for direct scatter points#100

Merged
FarhanAliRaza merged 7 commits into
mainfrom
codex/add-zoom-responsive-size-and-opacity-for-scatter-points
Jul 22, 2026
Merged

Add zoom-responsive styling for direct scatter points#100
FarhanAliRaza merged 7 commits into
mainfrom
codex/add-zoom-responsive-size-and-opacity-for-scatter-points

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Motivation

  • Direct scatter markers are fixed in screen-space size and opacity which makes them either too faint when deeply zoomed or too noisy in overviews.
  • The goal is to make markers interpolate size and opacity on the client during zoom so detail is legible without rebuilding or retransmitting large traces.

Description

  • Added zoom_size_factor, zoom_opacity, and zoom_emphasis parameters to the fluent Figure.scatter API and the Reflex-style components.scatter factory and serialized them into trace style with sensible, fixed-style-compatible defaults.
  • Client-side logic _pointZoomStyle was implemented in js/src/50_chartview.js to compute a logarithmic interpolation (from the initial view) for size and opacity, clamped at the configured zoom_emphasis.
  • The computed sizeFactor and adjusted opacity are applied consistently across rendering paths including the full points shader, the simple points shader, hover emphasis, and the pick/detection path so rendering, hover, and picking stay aligned.
  • Input validation and docs were added in python/xy/marks.py and python/xy/components.py, tests were added/updated to cover serialization and validation, and static JS bundles were rebuilt and committed.

Testing

  • Ran unit tests: PYTHONPATH=python python -m pytest tests/test_scatter.py tests/test_components.py -q, all tests passed (156 passed).
  • Rebuilt and verified JS bundles with node js/build.mjs and make js-check, which succeeded and reported fresh static bundles.
  • Ran style/type/lint checks with PYTHONPATH=python ruff check python/xy/marks.py python/xy/components.py tests/test_scatter.py and git diff --check, both succeeded.

Codex Task

Closes #88

@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 102 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing codex/add-zoom-responsive-size-and-opacity-for-scatter-points (596d3e7) with main (fca544d)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@FarhanAliRaza FarhanAliRaza added valid Issue is validated. This pr actually fixes the issue. Needs Code Review. and removed codex labels Jul 20, 2026

@Alek99 Alek99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review findings:

  • [P2] js/src/50_chartview.js:2261: y-only zoom never activates responsive styling because a finite x zoom of 1 wins the nullish-coalescing chain. Combine the applicable axis zoom factors instead.
  • [P2] js/src/50_chartview.js:2432: hover emphasis uses scalar g.size, not the point's encoded size. Large size-channel points therefore get a smaller hover overlay than the rendered point.
  • [P2] js/src/50_chartview.js:2311: zoom_opacity is applied to the fill but explicit point strokes retain base opacity. Apply the zoom-adjusted opacity to the outline while preserving stroke_opacity.

…sive-size-and-opacity-for-scatter-points

# Conflicts:
#	examples/demo-advance.ipynb
#	js/src/50_chartview.ts
#	python/xy/components.py
#	python/xy/marks.py
#	python/xy/static/index.js
#	python/xy/static/standalone.js
- y-only zoom now activates emphasis: use the deepest of the x/y axis
  zoom factors instead of the first finite one.
- Hover overlay sizes from the point's encoded size on size-channel
  traces, falling back to the scalar size when no CPU copy exists.
- Explicit point strokes follow the zoom opacity ramp, interpolating
  from their stroke_opacity base toward the shared zoom_opacity target.
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds zoom-responsive styling for direct scatter points. The main changes are:

  • Adds configurable zoom size, opacity, and emphasis options to both Python scatter APIs.
  • Applies interpolated styling to full, simple, hover, and picking paths in the client renderer.
  • Uses each trace's own axes when calculating zoom emphasis.
  • Adds validation, serialization tests, and a notebook example.

Confidence Score: 5/5

This looks safe to merge.

The alternate-axis zoom calculation now follows each scatter trace's configured axes. Rendering, hover, and picking preserve those axis identifiers.

No blocking issues were found in the changed code.

T-Rex T-Rex Logs

What T-Rex did

  • Compared baseline videos and screenshots; baseline screenshot hashes are identical, confirming visual parity.
  • Compared the zoomed views; zoomed hashes differ, indicating a rendering change between baseline and post-change.
  • Validated runtime state: before implementation used sizeFactor 1 and opacity 0.18, while the changed implementation used sizeFactor 4 and opacity 0.95.
  • Confirmed no page errors and that WebGL emitted only benign ReadPixels performance warnings.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
js/src/50_chartview.ts Adds zoom-responsive point styling across rendering, hover, and picking, with trace-specific axis selection.
python/xy/marks.py Adds validation and serialization for zoom-responsive scatter options.
python/xy/components.py Exposes and forwards the new scatter options through the component API.
tests/test_scatter.py Adds coverage for fixed defaults, responsive serialization, and invalid values.
examples/demo-advance.ipynb Adds an interactive example of zoom-responsive scatter markers.

Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment thread js/src/50_chartview.ts Outdated
A scatter bound to x2/y2 rendered against those axes but derived its
zoom emphasis from the primary x/y view ranges. Resolve current and
home spans through _axisRange (view0.ranges holds every axis's home
range), so alternate-axis traces respond to their own zoom and ignore
primary-axis zooms.
…sive-size-and-opacity-for-scatter-points

# Conflicts:
#	python/xy/static/index.js
#	python/xy/static/standalone.js
@FarhanAliRaza
FarhanAliRaza merged commit ccea038 into main Jul 22, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

valid Issue is validated. This pr actually fixes the issue. Needs Code Review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add zoom-responsive size and opacity for direct scatter points

2 participants