From 0eeaf6151f4a2a00368c4ea9b6c6ddd33ff7a2c0 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 15:38:12 -0700 Subject: [PATCH 1/3] Autoscale mesh, image, and distribution entries [mpl compatibility] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pyplot shim materializes its own view before compiling to a core Figure, so `Axes._iter_entry_arrays` has to recognize every entry shape the shim can emit. It probed top-level `x`/`y` plus a small factory table, and three shapes keep their coordinates inside `kwargs` instead: `@mark`/`heatmap` (hist2d, uniform-grid pcolormesh, specgram), `ecdf`, and `box`. Those axes scanned as dataless, so `_build_chart` pinned them to the empty `(0, 1)` view and clipped the geometry — a 30x30 hist2d rendered roughly 3x1 of its bins. The pre-existing `kind == "heatmap"` branch did not cover hist2d: that branch matches imshow's entry shape, which is a plain `heatmap` kind carrying an explicit `extent`. hist2d registers an `@mark` kind with factory `heatmap` and no `extent` at all, so it fell through to the `@mark` factory table, which had no `heatmap` row. Mirror the core rather than re-deriving the geometry: heatmap spans go through `Figure._heatmap_axis_positions`/`_cell_edges`, which is what recovers the original bin edges from the centers hist2d stores, and box spans reuse `marks._distribution_stats` for whiskers and fliers. Matplotlib gives these artists sticky edges, so their limits carry no margin. The engine knows only the zero-baseline anchor, so derive sticky edges for mesh, image, and ECDF entries and, when both ends are pinned, ship a materialized `domain` instead of a `margin` — the two never combine. One-sided rectangle baselines keep the `margin` and stay anchored by the engine. hexbin, contour/contourf, imshow, non-uniform hist2d/pcolormesh, tripcolor, violinplot, errorbar, and step already scanned correctly. --- python/xy/pyplot/_axes.py | 164 ++++++++++++- spec/design/pan-and-zoom-configuration.md | 1 + spec/matplotlib/compat-changelog.md | 23 ++ spec/matplotlib/compat.md | 6 +- spec/matplotlib/shim-todo.md | 2 +- .../pyplot/test_mesh_autoscale_regressions.py | 217 ++++++++++++++++++ 6 files changed, 405 insertions(+), 8 deletions(-) create mode 100644 tests/pyplot/test_mesh_autoscale_regressions.py diff --git a/python/xy/pyplot/_axes.py b/python/xy/pyplot/_axes.py index b7bd761e..d97615f4 100644 --- a/python/xy/pyplot/_axes.py +++ b/python/xy/pyplot/_axes.py @@ -197,6 +197,101 @@ def convert(values: Any) -> Any: entry["args"] = tuple(args) +def _heatmap_span(entry: dict[str, Any], axis: str) -> Optional[np.ndarray]: + """The outer cell edges a ``@mark``/``heatmap`` entry occupies on *axis*. + + ``hist2d``/``pcolormesh``/``specgram`` register their cell **centers** + inside ``kwargs``, so the autoscale scan's generic top-level ``entry[key]`` + probe never sees them. Mirror `Figure._heatmap_axis_positions` plus + `Figure._cell_edges` exactly rather than re-deriving the geometry: absent + centers default to ``arange(n)``, and the drawn span reaches half a cell + beyond the first and last center, which is what recovers the original + ``hist2d`` bin edges from its centers. + """ + from xy._figure import Figure + + args = entry.get("args", ()) + if not args: + return None + z = np.asarray(args[0]) + if z.ndim < 2: + return None + # Both (rows, cols) and RGB(A) (rows, cols, bands) grids index the same way. + count = z.shape[1 if axis == "x" else 0] + centers = entry.get("kwargs", {}).get(axis) + if centers is None: + positions = np.arange(count, dtype=np.float64) + else: + try: + positions = np.asarray(unit_converted_values(centers), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + # String/object centers become first-seen ordinals in the core. + positions = np.arange(np.asarray(centers).size, dtype=np.float64) + if positions.size != count or not np.all(np.isfinite(positions)): + return None + try: + edges = Figure._cell_edges(positions, f"heatmap {axis}") + except ValueError: + # A build with these centers will raise for the same reason; leave the + # decision to the core instead of guessing a span here. + return None + return np.asarray([edges[0], edges[-1]], dtype=np.float64) + + +def _box_spans(entry: dict[str, Any], axis: str) -> Iterator[np.ndarray]: + """The spans a ``@mark``/``box`` entry occupies on *axis*. + + Mirrors `marks.box`: the category axis spans each position +/- half the box + width, and the value axis spans the Tukey whiskers plus, when outliers are + drawn, the flier points beyond them. + """ + from xy.marks import _distribution_stats + + args = entry.get("args", ()) + if not args: + return + kwargs = entry.get("kwargs", {}) + orientation = kwargs.get("orientation", "vertical") + values = args[0] + if ( + isinstance(values, (list, tuple)) + and len(values) + and all(not isinstance(item, str) and np.ndim(item) == 1 for item in values) + ): + groups = [np.asarray(item, dtype=np.float64) for item in values] + else: + array = np.asarray(values, dtype=np.float64) + groups = ( + [array[:, index] for index in range(array.shape[1])] + if array.ndim == 2 + else [array.reshape(-1)] + ) + positions = kwargs.get("x") + ordinals = np.arange(len(groups), dtype=np.float64) + if positions is None: + # marks.box defaults absent positions to arange(len(groups)). + centers = ordinals + else: + try: + centers = np.asarray(unit_converted_values(positions), dtype=np.float64).reshape(-1) + except (TypeError, ValueError): + # String categories become their first-seen ordinal positions. + centers = ordinals + if centers.size != len(groups) or not np.all(np.isfinite(centers)): + centers = ordinals + category_axis = "x" if orientation == "vertical" else "y" + if axis == category_axis: + half = float(kwargs.get("width", 0.6)) / 2.0 + yield centers - half + yield centers + half + return + stats = [_distribution_stats(group) for group in groups] + spans = [np.asarray([stat[3], stat[4]], dtype=np.float64) for stat in stats] + if kwargs.get("show_outliers", True): + spans.extend(np.asarray(stat[5], dtype=np.float64) for stat in stats) + yield from spans + + def _nonlinear_ticks(domain: tuple[float, float], spec: dict[str, Any]) -> np.ndarray: lo, hi = map(float, _scale_values(np.asarray(domain), spec, inverse=True)) if spec["name"] == "logit": @@ -2702,6 +2797,21 @@ def _iter_entry_arrays(self, axis: str) -> Iterator[tuple[np.ndarray, bool]]: coordinates = np.arange(z.shape[1 if axis == "x" else 0], dtype=float) if coordinates is not None: yield np.asarray(coordinates, dtype=np.float64).reshape(-1), True + elif factory == "heatmap": + # NB: distinct from the `kind == "heatmap"` branch below, + # which is imshow's explicit-extent entry shape. + span = _heatmap_span(entry, key) + if span is not None: + yield span, False + elif factory == "ecdf": + if axis == "x": + yield np.asarray(entry["args"][0], dtype=np.float64).reshape(-1), True + else: + # marks.ecdf steps from 0 to cumulative mass 1. + yield np.asarray([0.0, 1.0], dtype=np.float64), False + elif factory == "box": + for span in _box_spans(entry, axis): + yield span, True elif entry.get("kind") == "heatmap" and entry.get("extent") is not None: bounds = entry["extent"] yield np.asarray(bounds[:2] if axis == "x" else bounds[2:], dtype=float), False @@ -2765,11 +2875,48 @@ def _entry_sticky_edges(self, axis: str) -> np.ndarray: finite = values[np.isfinite(values)] if finite.size: edges.append(np.asarray([finite.min(), finite.max()])) + elif entry.get("kind") == "@mark" and entry.get("factory") == "heatmap": + # Matplotlib gives pcolormesh/hist2d/specgram sticky edges: the + # view hugs the outer cell edge with no margin at all. + span = _heatmap_span(entry, axis) + if span is not None: + edges.append(span) + elif entry.get("kind") == "@mark" and entry.get("factory") == "ecdf": + if axis == "y": + # An ECDF is sticky at both 0 and full cumulative mass. + edges.append(np.asarray([0.0, 1.0], dtype=np.float64)) + elif entry.get("kind") == "heatmap" and entry.get("extent") is not None: + # imshow's explicit extent is likewise sticky on both axes. + bounds = entry["extent"] + edges.append(np.asarray(bounds[:2] if axis == "x" else bounds[2:], dtype=float)) if not edges: return np.array([], dtype=np.float64) combined = np.concatenate(edges) return combined[np.isfinite(combined)] + def _fully_sticky_domain(self, axis: str) -> Optional[tuple[float, float]]: + """The raw extent when sticky edges pin *both* ends of *axis*. + + Image- and mesh-like marks (imshow/pcolormesh/hist2d/specgram) hug + their outer cell edge in Matplotlib, and an ECDF hugs 0 and 1. The + core only knows the rectangle zero-baseline anchor, so it would pad + such an axis by the ordinary margin. `_build_chart` materializes this + domain instead of a margin so the renderer cannot widen the view. + + Deliberately requires *both* ends: a one-sided sticky edge is the bar + and histogram baseline, which the core already anchors itself. + """ + if self._axis_is_dataless(axis): + return None + sticky = self._entry_sticky_edges(axis) + if not sticky.size: + return None + lo, hi = self._entry_extent(axis) + tolerance = np.finfo(np.float64).eps * max(1.0, abs(lo), abs(hi)) * 8 + pinned_lo = np.any(np.isclose(sticky, lo, rtol=0.0, atol=tolerance)) + pinned_hi = np.any(np.isclose(sticky, hi, rtol=0.0, atol=tolerance)) + return (lo, hi) if pinned_lo and pinned_hi else None + def _auto_domain(self, axis: str) -> tuple[float, float]: host = self._y2_of or self key = "y2" if axis == "y" and self._y2_of is not None else axis @@ -4737,10 +4884,19 @@ def _build_chart(self, width: int, height: int) -> Any: } x_props = {k: v for k, v in self._axis["x"].items() if v is not None} y_props = {k: v for k, v in self._axis["y"].items() if v is not None} - if not adjusted_aspect and "x" not in self._explicit_domains: - x_props["margin"] = self._effective_margin("x") - if not adjusted_aspect and "y" not in self._explicit_domains: - y_props["margin"] = self._effective_margin("y") + for axis, props in (("x", x_props), ("y", y_props)): + if adjusted_aspect or axis in self._explicit_domains: + continue + # Mesh and image spans are sticky on both ends: materialize the + # domain so the renderer's generic margin padding cannot widen an + # axis Matplotlib pins flush to the outer cell edge. `margin` and + # `domain` never combine (spec/design/pan-and-zoom-configuration.md + # §9), so send exactly one of them. + pinned = None if props.get("domain") is not None else self._fully_sticky_domain(axis) + if pinned is not None: + props["domain"] = pinned + else: + props["margin"] = self._effective_margin(axis) if "x" in empty_view: x_props["domain"] = (0.0, 1.0) if "y" in empty_view: diff --git a/spec/design/pan-and-zoom-configuration.md b/spec/design/pan-and-zoom-configuration.md index 9ed11495..c43cb660 100644 --- a/spec/design/pan-and-zoom-configuration.md +++ b/spec/design/pan-and-zoom-configuration.md @@ -479,6 +479,7 @@ part of the contract, not incidental: | Log axis with an explicit `margin` | The pad is applied in log10 space (`10 ** (log10(lo) - span * margin)`), so it is multiplicative and symmetric on screen. The `lo / 10` floor does not apply: an authored margin is the authority on the low edge. | | Singleton data range (`lo == hi`) with an explicit `margin` | The extent becomes `[lo, lo + 1]` and the margin pads that unit interval — matching mpl's singleton handling. Without a margin the legacy fallback still applies: `±5%` of `abs(lo)`, or `±0.5` at zero. | | Zero-baseline marks (bars, areas) | Unchanged: the padded edge still snaps back to `0` when the data range touches it, so a bar chart's baseline does not float off the spine. | +| Both ends sticky (mesh, image, ECDF cumulative axis) | The axis takes the data range verbatim, as matplotlib's sticky edges do for `imshow`/`pcolormesh`/`hist2d`/`specgram` and for an ECDF's 0/1 axis. The engine has no sticky concept beyond the zero-baseline anchor above, so the pyplot shim resolves this case itself and ships a materialized `domain` in place of `margin` (`Axes._fully_sticky_domain`) — the two never combine. A *one-sided* sticky edge is the zero baseline and stays with `margin`, anchored by the engine. | `margin` is resolved in Python, in f64, by `Figure._range` — only the resulting domain crosses the wire, so it is not a renderer-side concept and needs no diff --git a/spec/matplotlib/compat-changelog.md b/spec/matplotlib/compat-changelog.md index 0a58aa0f..854333e9 100644 --- a/spec/matplotlib/compat-changelog.md +++ b/spec/matplotlib/compat-changelog.md @@ -266,5 +266,28 @@ colorbar domains) fully cleared. `subplots(..., toolbar=...)`, which forwards it to `figure` — overrides rcParams for one figure. +### Mesh and distribution autoscale — 2026-07-24 (Matplotlib 3.11.0 reference) + +- The shim's pre-build autoscale scan (`Axes._iter_entry_arrays`) now + recognizes the `@mark`/`heatmap`, `ecdf`, and `box` entry shapes, which keep + their coordinates inside `kwargs` rather than as top-level `x`/`y`. Those + axes previously scanned as *dataless* and were pinned to the empty `(0, 1)` + view, clipping the geometry: a 30×30 `hist2d` showed roughly 3×1 of its bins. + Affects `hist2d` (uniform bins), `pcolormesh` on a uniform grid, `specgram`, + `ecdf`, and `boxplot`. `hexbin`, `contour`/`contourf`, `imshow`, + non-uniform `hist2d`/`pcolormesh`, `tripcolor`, `violinplot`, `errorbar`, and + `step` already scanned correctly and are unchanged. +- Sticky edges are now derived for mesh, image, and ECDF entries, so + `hist2d`/`pcolormesh`/`specgram`/`imshow` view limits are exactly the outer + cell edges and an ECDF's cumulative axis is exactly `0..1` — matching + Matplotlib, which gives these artists sticky edges and therefore no margin. + An axis with sticky edges on *both* ends ships a materialized `domain` + instead of a `margin`; one-sided rectangle baselines are unchanged and stay + anchored by the engine. +- `boxplot` autoscales its value axis over the Tukey whiskers plus the flier + points when `showfliers` is on, matching Matplotlib on both settings. Known + remaining deviation, unchanged by this entry: with `positions` omitted the + boxes sit on 0-based ordinals rather than Matplotlib's 1-based positions. + Future entries must identify the Matplotlib release/revision, inventory additions or removals, and any compatibility-level changes. diff --git a/spec/matplotlib/compat.md b/spec/matplotlib/compat.md index c11fb4fd..e8df02ce 100644 --- a/spec/matplotlib/compat.md +++ b/spec/matplotlib/compat.md @@ -54,11 +54,11 @@ dependency-free `triangles=` shorthand into Matplotlib's equivalent | `scatter(x, y, s=, c=, cmap=, vmin=, vmax=, alpha=, marker=, edgecolors=, plotnonfinite=)` | `s` (pt², area) maps to pixel diameter; numeric 1-D `c` remains a colormap encoding, while `N×3`/`N×4` face and edge colors, alpha arrays, sizes, and linewidth arrays stay in one collection. Explicit alpha replaces intrinsic RGBA alpha, matching Matplotlib; custom norms/marker paths fail loudly | | `bar`, `barh`, `grouped_bar`, `bar_label` | string categories, stacking bases, per-bar face/edge color-alpha pairs and linewidths, plus iterable/indexable `BarContainer.patches` views whose setters mutate the parent batched trace | | `hist(bins=, range=, density=, cumulative=, weights=, orientation=, stacked=)` | Returns computed counts/edges; bar, step, and stepfilled families render in both vertical and horizontal orientations | -| `hist2d`, `hexbin`, `ecdf` | 2D uniform binning uses the native Rust kernel; hexbin uses Matplotlib's two-offset-grid nearest-center assignment and six-triangle data-space cells, supports `C`, arbitrary scalar reducers, and `mincnt`, and retains only the bounded lattice rather than source points | -| `boxplot`, `violinplot`, `bxp`, `violin`, `errorbar` | Boxplots support notches, bootstrap/user confidence intervals, median overrides (drawn median only; notch CIs stay data-derived like Matplotlib), percentile/custom whiskers, cap widths, `sym`, and component colors/widths/alpha — dashed component linestyles fail loudly. Violins support Scott/Silverman/scalar/callable Gaussian-KDE bandwidths, quantiles, and low/high sides; the default (bw_method omitted) uses the native histogram violin mark, whose shape differs from the explicit KDE path | +| `hist2d`, `hexbin`, `ecdf` | 2D uniform binning uses the native Rust kernel; hexbin uses Matplotlib's two-offset-grid nearest-center assignment and six-triangle data-space cells, supports `C`, arbitrary scalar reducers, and `mincnt`, and retains only the bounded lattice rather than source points. `hist2d` view limits are the outer bin edges with no margin, matching Matplotlib's sticky mesh edges; non-uniform bins delegate to `pcolormesh` and autoscale through the quad-mesh path instead. `ecdf` carries the ordinary margin on the sample axis and is sticky at 0 and 1 on the cumulative axis | +| `boxplot`, `violinplot`, `bxp`, `violin`, `errorbar` | Boxplots support notches, bootstrap/user confidence intervals, median overrides (drawn median only; notch CIs stay data-derived like Matplotlib), percentile/custom whiskers, cap widths, `sym`, and component colors/widths/alpha — dashed component linestyles fail loudly. Violins support Scott/Silverman/scalar/callable Gaussian-KDE bandwidths, quantiles, and low/high sides; the default (bw_method omitted) uses the native histogram violin mark, whose shape differs from the explicit KDE path. `boxplot` autoscales its value axis over the Tukey whiskers plus, when `showfliers` is on, the flier points — matching Matplotlib. Known deviation: with `positions` omitted the boxes sit on 0-based ordinals rather than Matplotlib's 1-based positions, so the category axis is offset by one (`violinplot` already corrects this); the value axis is unaffected | | `fill_between(x, y1, y2, where=, step=)` / `fill_betweenx` | Masks are split into finite contiguous polygons; step geometry is expanded exactly | | `stackplot` | All four baselines are computed by the native stacked-bounds kernel | -| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact and Matplotlib's smoothing mode names all collapse to the shim's single bounded gradient upsampling (a visual approximation, not per-mode kernels) and apply to scalar data only — RGB(A) truecolor arrays render unresampled — while unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion | +| `imshow` / `pcolormesh` (`cmap=`, `vmin=`/`vmax=`, `origin=`) | `imshow` defaults to `rcParams['image.origin']`; nearest stays cell-exact and Matplotlib's smoothing mode names all collapse to the shim's single bounded gradient upsampling (a visual approximation, not per-mode kernels) and apply to scalar data only — RGB(A) truecolor arrays render unresampled — while unsupported stages/transforms fail loudly. Uniform meshes retain the texture fast path; nonuniform and curvilinear grids use native quad-to-triangle expansion. Both hug their outer cell edge with no margin, as Matplotlib's sticky image/mesh edges do | | `step`, `stairs`, `stem`, `eventplot` | Compact step/stem/segment marks; no Python-side vertex expansion | | `contour` / `contourf` / `clabel` | Native marching squares over rectilinear grids; warped grids route through native Delaunay/marching-triangle kernels; automatic labels repeat at bounded, separated positions along each level (line knockout for `inline=True` remains a visual approximation) | | `quiver`, `barbs`, `streamplot` | Native vector endpoint/arrowhead and bounded streamline kernels feeding one instanced segment mark. Barbs are a visual approximation: magnitude maps to a bounded tick count, not WMO 50/10/5 increments. Streamplot always uses the shim's own bounded fixed-step integrator (identical output with or without Matplotlib installed, but paths approximate Matplotlib's adaptive ones); `start_points`, `integration_direction`, array widths/colors and `num_arrows` are honored, and remaining non-default integration options fail loudly | diff --git a/spec/matplotlib/shim-todo.md b/spec/matplotlib/shim-todo.md index dcdf2c03..9dd8af5e 100644 --- a/spec/matplotlib/shim-todo.md +++ b/spec/matplotlib/shim-todo.md @@ -253,7 +253,7 @@ appear frequently in ordinary scripts and notebooks. ### Limits, autoscaling, ticks and axes helpers - [x] `plt.autoscale()`, `Axes.autoscale()`, `autoscale_view()`, and `relim()`. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies explicit bounds, relim, autoscale, and tight autoscale behavior. -- [x] `get/set_xbound`, `get/set_ybound`, x/y margins, and sticky-edge behavior. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies bound setters/getters and margin-aware automatic domains; sticky edges are intentionally out of scope because xy artists do not expose sticky-edge metadata. +- [x] `get/set_xbound`, `get/set_ybound`, x/y margins, and sticky-edge behavior. Evidence: `tests/pyplot/test_axes_helpers.py::test_autoscale_bounds_and_relim_helpers` verifies bound setters/getters and margin-aware automatic domains. Sticky edges are derived from the entry list rather than from artist metadata (`Axes._entry_sticky_edges`): rectangle baselines for bar/histogram/contour, the outer cell edge for mesh and image entries (`imshow`/`pcolormesh`/`hist2d`/`specgram`), and 0/1 for `ecdf`. An axis whose sticky edges pin *both* ends ships a materialized `domain` instead of a `margin` (`Axes._fully_sticky_domain`), which is how a mesh stays flush with its outer cell edge; one-sided baselines still ship a `margin` and are anchored by the engine. Evidence: `tests/pyplot/test_mesh_autoscale_regressions.py`. - [x] `ticklabel_format()`. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies stored style, scientific limits, and offset policy. - [x] `minorticks_on()` and `minorticks_off()` with an explicit minor-tick model. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies explicit minor tick state toggles. - [x] `get_xlabel`, `get_ylabel`, `get_title`, `get_xaxis`, and `get_yaxis`. Evidence: `tests/pyplot/test_axes_helpers.py::test_ticklabel_minor_label_axis_and_legend_helpers` verifies label/title getters and axis proxy identity. diff --git a/tests/pyplot/test_mesh_autoscale_regressions.py b/tests/pyplot/test_mesh_autoscale_regressions.py new file mode 100644 index 00000000..6da91c56 --- /dev/null +++ b/tests/pyplot/test_mesh_autoscale_regressions.py @@ -0,0 +1,217 @@ +"""The pre-build autoscale scan must recognize every factory the shim emits. + +`Axes._iter_entry_arrays` feeds `_axis_is_dataless`, and a populated axes that +scans as dataless gets pinned to the empty ``(0, 1)`` view in `_build_chart` — +clipping the real geometry. Mesh, image, ECDF, and box entries keep their +coordinates inside ``kwargs`` rather than as top-level ``x``/``y``, so each +needs an explicit branch. These lock every one of them in place. +""" + +from __future__ import annotations + +import numpy as np +import pytest + +import xy.pyplot as plt + + +@pytest.fixture(autouse=True) +def _clean(): + plt.close("all") + plt.rcdefaults() + yield + plt.close("all") + plt.rcdefaults() + + +def _rendered(ax, which: str) -> tuple[float, float]: + figure = ax._build_chart(640, 480).figure() + return figure.x_range() if which == "x" else figure.y_range() + + +def _assert_contains(view: tuple[float, float], lo: float, hi: float) -> None: + span = max(abs(lo), abs(hi), 1.0) + tolerance = span * 1e-12 + assert view[0] <= lo + tolerance, f"{view} clips data low edge {lo}" + assert view[1] >= hi - tolerance, f"{view} clips data high edge {hi}" + + +def test_hist2d_view_contains_every_bin() -> None: + """The reported defect: 30x30 bins computed, ~4x3 of them visible.""" + rng = np.random.default_rng(1701) + x, y = rng.multivariate_normal([0, 0], [[1, 1], [1, 2]], 10_000).T + _fig, ax = plt.subplots() + + counts, xedges, yedges, _image = ax.hist2d(x, y, bins=30) + + assert counts.shape == (30, 30) + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + # Matplotlib gives hist2d sticky edges: the view is exactly the bin edges. + assert ax.get_xlim() == pytest.approx((xedges[0], xedges[-1])) + assert ax.get_ylim() == pytest.approx((yedges[0], yedges[-1])) + _assert_contains(_rendered(ax, "x"), xedges[0], xedges[-1]) + _assert_contains(_rendered(ax, "y"), yedges[0], yedges[-1]) + + +def test_hist2d_explicit_range_is_not_pinned_to_the_unit_view() -> None: + rng = np.random.default_rng(0) + _fig, ax = plt.subplots() + + _counts, xedges, yedges, _image = ax.hist2d( + rng.normal(size=500), rng.normal(size=500), bins=10, range=((-3, 3), (-2, 2)) + ) + + assert (xedges[0], xedges[-1]) == pytest.approx((-3.0, 3.0)) + assert ax.get_xlim() == pytest.approx((-3.0, 3.0)) + assert ax.get_ylim() == pytest.approx((-2.0, 2.0)) + _assert_contains(_rendered(ax, "x"), xedges[0], xedges[-1]) + _assert_contains(_rendered(ax, "y"), yedges[0], yedges[-1]) + + +def test_hist2d_irregular_bins_take_the_mesh_path_and_still_autoscale() -> None: + """Non-uniform bins delegate to pcolormesh; both paths must autoscale.""" + rng = np.random.default_rng(0) + xedges = np.array([-4.0, -1.0, 0.0, 1.0, 4.0]) + yedges = np.array([-4.0, 0.0, 1.0, 4.0]) + _fig, ax = plt.subplots() + + ax.hist2d(rng.normal(size=500), rng.normal(size=500), bins=[xedges, yedges]) + + assert not ax._axis_is_dataless("x") + _assert_contains(_rendered(ax, "x"), xedges[0], xedges[-1]) + _assert_contains(_rendered(ax, "y"), yedges[0], yedges[-1]) + + +def test_pcolormesh_uniform_grid_hugs_its_outer_cell_edges() -> None: + z = np.random.default_rng(1).normal(size=(25, 30)) + _fig, ax = plt.subplots() + + ax.pcolormesh(np.linspace(0.0, 5.0, 31), np.linspace(0.0, 5.0, 26), z) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + assert ax.get_xlim() == pytest.approx((0.0, 5.0)) + assert ax.get_ylim() == pytest.approx((0.0, 5.0)) + # Sticky on both ends, so no margin is added to a mesh. + assert _rendered(ax, "x") == pytest.approx((0.0, 5.0)) + assert _rendered(ax, "y") == pytest.approx((0.0, 5.0)) + + +def test_pcolormesh_two_dimensional_coordinates_autoscale() -> None: + grid_x, grid_y = np.meshgrid(np.linspace(0.0, 5.0, 30), np.linspace(0.0, 5.0, 25)) + _fig, ax = plt.subplots() + + ax.pcolormesh(grid_x, grid_y, np.sin(grid_x)[:-1, :-1]) + + assert not ax._axis_is_dataless("x") + _assert_contains(_rendered(ax, "x"), 0.0, 5.0) + _assert_contains(_rendered(ax, "y"), 0.0, 5.0) + + +def test_heatmap_without_coordinates_spans_its_index_cells() -> None: + """Absent centers default to arange(n), so cells span -0.5 .. n-0.5.""" + _fig, ax = plt.subplots() + + ax.pcolormesh(np.arange(12.0).reshape(3, 4)) + + assert not ax._axis_is_dataless("x") + assert ax.get_xlim() == pytest.approx((-0.5, 3.5)) + assert ax.get_ylim() == pytest.approx((-0.5, 2.5)) + + +def test_specgram_axes_are_not_pinned_to_the_unit_view() -> None: + rng = np.random.default_rng(0) + _fig, ax = plt.subplots() + + _power, frequency, time, _image = ax.specgram(rng.normal(size=4096), NFFT=256, Fs=2.0) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + _assert_contains(_rendered(ax, "x"), float(time[0]), float(time[-1])) + _assert_contains(_rendered(ax, "y"), float(frequency[0]), float(frequency[-1])) + + +def test_imshow_explicit_extent_stays_flush_with_the_image_edges() -> None: + _fig, ax = plt.subplots() + + ax.imshow(np.arange(12.0).reshape(3, 4), extent=(0.0, 4.0, 0.0, 3.0), aspect="auto") + + assert ax.get_xlim() == pytest.approx((0.0, 4.0)) + assert ax.get_ylim() == pytest.approx((0.0, 3.0)) + assert _rendered(ax, "x") == pytest.approx((0.0, 4.0)) + assert _rendered(ax, "y") == pytest.approx((0.0, 3.0)) + + +def test_ecdf_spans_its_samples_and_sticks_to_zero_and_one() -> None: + _fig, ax = plt.subplots() + + ax.ecdf(np.array([1.0, 2.0, 3.0, 4.0])) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + # Matplotlib: x carries the ordinary 5% margin, y is sticky at 0 and 1. + assert ax.get_xlim() == pytest.approx((0.85, 4.15)) + assert ax.get_ylim() == pytest.approx((0.0, 1.0)) + _assert_contains(_rendered(ax, "x"), 1.0, 4.0) + assert _rendered(ax, "y") == pytest.approx((0.0, 1.0)) + + +def test_boxplot_value_axis_covers_whiskers_and_fliers() -> None: + rng = np.random.default_rng(0) + left, right = rng.normal(size=2000), rng.normal(size=2000) + _fig, ax = plt.subplots() + + ax.boxplot([left, right]) + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + # Fliers are drawn, so the value axis reaches the extreme observations. + _assert_contains(_rendered(ax, "y"), float(min(left.min(), right.min())), 0.0) + _assert_contains(_rendered(ax, "y"), 0.0, float(max(left.max(), right.max()))) + + +def test_boxplot_without_fliers_tightens_to_the_whiskers() -> None: + rng = np.random.default_rng(0) + values = rng.normal(size=2000) + _fig, ax = plt.subplots() + + ax.boxplot([values], showfliers=False) + + rendered = _rendered(ax, "y") + assert rendered[0] > values.min() + assert rendered[1] < values.max() + assert not ax._axis_is_dataless("y") + + +def test_horizontal_boxplot_swaps_which_axis_carries_the_values() -> None: + rng = np.random.default_rng(0) + values = rng.normal(size=500) + _fig, ax = plt.subplots() + + ax.boxplot([values], orientation="horizontal") + + assert not ax._axis_is_dataless("x") + assert not ax._axis_is_dataless("y") + _assert_contains( + _rendered(ax, "x"), float(np.percentile(values, 25)), float(np.percentile(values, 75)) + ) + + +def test_mesh_entries_do_not_make_bar_baselines_sticky_on_both_ends() -> None: + """Guard the `_fully_sticky_domain` narrowing: bars keep their margin. + + A one-sided sticky edge is the rectangle baseline, which the core anchors + itself; materializing a domain for it would bypass the engine's autorange. + """ + _fig, ax = plt.subplots() + ax.bar([0.0, 1.0, 2.0], [1.0, 3.0, 2.0]) + + chart = ax._build_chart(640, 480) + axes = { + child.which: child + for child in chart.children + if getattr(child, "which", None) in {"x", "y"} + } + assert axes["y"].domain is None + assert axes["y"].margin == pytest.approx(0.05) From 198eb173089144dd46f8e31b0a0fe8e63fdc78a9 Mon Sep 17 00:00:00 2001 From: Sriman Selvakumaran Date: Fri, 24 Jul 2026 15:40:25 -0700 Subject: [PATCH 2/3] Add temporary mesh autoscale comparison asset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TEMPORARY — for PR review only, to be removed before merge. Three-up render of the PDSH 04.05 `plt.hist2d` cell: Matplotlib 3.11.1 reference, xy.pyplot before (30x30 bins computed, view pinned to the dataless 0..1 box so roughly 3x1 of them are visible), and xy.pyplot after. --- .../hist2d-reference-before-after.png | Bin 0 -> 97220 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pr-assets/mesh-autoscale/hist2d-reference-before-after.png diff --git a/pr-assets/mesh-autoscale/hist2d-reference-before-after.png b/pr-assets/mesh-autoscale/hist2d-reference-before-after.png new file mode 100644 index 0000000000000000000000000000000000000000..d2eb67edbaff49262165fb78afb81ebfa5e428da GIT binary patch literal 97220 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 Date: Fri, 24 Jul 2026 15:43:35 -0700 Subject: [PATCH 3/3] Name the exact Matplotlib revision the autoscale parity was measured against The limits in the new changelog entry were compared against Matplotlib 3.11.1, not 3.11.0. --- spec/matplotlib/compat-changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/matplotlib/compat-changelog.md b/spec/matplotlib/compat-changelog.md index 854333e9..c81c5227 100644 --- a/spec/matplotlib/compat-changelog.md +++ b/spec/matplotlib/compat-changelog.md @@ -266,7 +266,7 @@ colorbar domains) fully cleared. `subplots(..., toolbar=...)`, which forwards it to `figure` — overrides rcParams for one figure. -### Mesh and distribution autoscale — 2026-07-24 (Matplotlib 3.11.0 reference) +### Mesh and distribution autoscale — 2026-07-24 (Matplotlib 3.11.1 reference) - The shim's pre-build autoscale scan (`Axes._iter_entry_arrays`) now recognizes the `@mark`/`heatmap`, `ecdf`, and `box` entry shapes, which keep