Skip to content

A zoomed bin grid does not match the unzoomed grid when the viewport covers the data #124

Open

Description

@jvdd

Problem

A zoomed binned trace (histogram, histogram2d, geo_histogram2d) bins on a lattice that starts at 0, with bin width span / n (snap_range in flexviz/trace/bin_grid.py). The unzoomed grid starts at the data minimum. So a viewport that covers the same range as the unzoomed grid gives another grid:

  • The grid almost always holds n + 1 bins.
  • The edges move, and discrete data can get an empty bin.

Example: a heatmap with y data 1..7 and y_bins=7. Unzoomed, it has 7 rows, one for each value. A zoom to [1, 7] gives 8 rows on [0.857, 7.714], and the row from 5.14 to 6.0 is empty.

Where users see it

  • A manual zoom to the data range (on main today).
  • The first zoom from the unzoomed view: all edges move, also when the range stays almost the same.
  • A lock on a link group whose members show different ranges (fix(adapters): aggregate linked members at the range a lock pins #116). The lock writes the group viewport for every member, also for the clicked figure, because the validator requires equal viewports in a group. So the clicked heatmap re-bins although its display did not change.

Cause

A zoomed request does not know the data extent of the column. The lattice needs an anchor that does not move under a pan, and 0 is the only anchor that needs no data.

Possible fix

Give zoomed binned requests the data extent of the column. Then do one of these:

  • Start the lattice at the data minimum. Pans stay stable, and a viewport that covers the data gives the unzoomed grid.
  • Treat a viewport that covers the data extent as unzoomed.

Cost and scope

Found in the review of #116.

Activity

  1. jvdd commented on Sep 29, 2026

    @jvdd
    ContributorAuthor

    One more consequence of the 0-anchored lattice, found while fixing #133 (2026-09-29).

    The snapped range covers the viewport, so the first and last bars can stick out past the viewport by up to almost one bar width. Example: 20 bins, viewport 3..103. The bar width is 5, the snapped range is 0..105 with 21 bars. The first bar spans 0..5, and its center 2.5 is off-screen.

    Effects:

    Decision: leave it. If this issue anchors the lattice so the grid aligns with the viewport, the overhang disappears and the source grid follows automatically. The alternative, treating a brush end that touches the plot edge as reaching the bar's outer edge, would filter rows the user cannot see and would disagree with Plotly's highlight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions