Skip to content

fix(marks): treat positional literals as coordinate channels - #2

Merged
schochastics merged 1 commit into
mainfrom
fix/positional-constant-encoding
Jul 10, 2026
Merged

fix(marks): treat positional literals as coordinate channels#2
schochastics merged 1 commit into
mainfrom
fix/positional-constant-encoding

Conversation

@schochastics

@schochastics schochastics commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Problem

A lollipop chart built with a segment baseline didn't render its sticks:

vplot(mt) |>
  mark_segment(x = i, y = 0, xend = i, yend = mpg) |>
  mark_point(x = i, y = mpg)

The y = 0 was silently dropped.

Root cause

Two bugs, both confirmed by rendering the SVG:

  1. .split_encodings() classified any bare literal (y = 0) as a constant style param. That's correct for size = 3 / color = "red", but a positional literal is a coordinate: it never landed in the layer's values, so .emit_segment() mapped the segment's start point onto its end point — every stick was zero-length and invisible — and a segment-only plot errored with "Every layer needs an x and y encoding".

  2. .axis_pool() never pooled xend/yend, so segment/edge endpoints didn't extend the axis domain. A segment-only plot trained a degenerate domain and drew its sticks far off-panel.

Fix

  • Keep literals on the positional aesthetics (x, y, xend, yend, xmin, xmax, ymin, ymax) as constant-valued channels, so they recycle per row and feed scale training — matching ggplot2's aes(y = 0) semantics.
  • Pool xend/yend in .axis_pool() so segment endpoints extend the domain like the start coordinate does.

A bare literal on a coordinate channel (e.g. `y = 0` for a segment
baseline) was classified as a constant style param, so it never landed
in the layer's `values` and never trained the position scale. This
collapsed each segment's start point onto its end (zero-length,
invisible) and made a segment-only plot error with "Every layer needs an
x and y encoding".

Keep literals on the positional aesthetics (x, y, xend, yend, xmin,
xmax, ymin, ymax) as constant-valued channels so they recycle per row
and feed scale training, matching ggplot2's `aes(y = 0)` semantics.

Also pool `xend`/`yend` in `.axis_pool()` so segment/edge endpoints
extend the axis domain; previously a segment-only plot trained a
degenerate domain and drew its sticks off-panel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@schochastics
schochastics merged commit 06fb149 into main Jul 10, 2026
2 checks passed
@schochastics
schochastics deleted the fix/positional-constant-encoding branch July 10, 2026 19:54
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.

1 participant