⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
39e3c49
Auto-detect compatible axis sharing by default
cvanelteren Feb 6, 2026
b1be8d5
Black formatting
cvanelteren Feb 6, 2026
5d04c97
Deduplicate explicit incompatible-share warnings
cvanelteren Feb 6, 2026
c8222a2
Disable ticklabel sharing for non-rectilinear GeoAxes
cvanelteren Feb 6, 2026
3c75f6b
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 6, 2026
475faf7
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 6, 2026
4396e79
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 6, 2026
dae3987
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 6, 2026
8d0b8f9
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 6, 2026
5199f6d
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 7, 2026
af48d5c
Stabilize outside-label panel image comparison tolerance
cvanelteren Feb 8, 2026
b124b2d
Pin panel outside-label test to explicit share mode
cvanelteren Feb 8, 2026
b34868a
Revert "Pin panel outside-label test to explicit share mode"
cvanelteren Feb 8, 2026
eeb9ac6
Revert "Stabilize outside-label panel image comparison tolerance"
cvanelteren Feb 8, 2026
caf91ec
Merge remote-tracking branch 'origin/main' into feat/autoshare-auto-d…
cvanelteren Feb 8, 2026
7d7f0fb
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 9, 2026
ecc0f40
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 9, 2026
16e20d0
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 9, 2026
3d44246
Harden compare-baseline status normalization logic
cvanelteren Feb 9, 2026
72efec9
Avoid set -e traps in selected-nodeid filter loops
cvanelteren Feb 9, 2026
48ad10c
Harden image-compare workflow exit handling
cvanelteren Feb 9, 2026
ccbee2f
Fix workflow YAML parsing in compare step
cvanelteren Feb 9, 2026
73130b5
Pin centered legend image test to explicit share mode
cvanelteren Feb 9, 2026
4fc4e1d
Add shell diagnostics to image comparison step
cvanelteren Feb 9, 2026
1c6a08f
Drop ERR trap from compare-step diagnostics
cvanelteren Feb 9, 2026
1bd3e66
Avoid re-enabling -e in compare step
cvanelteren Feb 9, 2026
dd3476c
Disable bash logout clear_console in compare step
cvanelteren Feb 9, 2026
813dc8d
Neutralize bash_logout safely in compare step
cvanelteren Feb 9, 2026
804b240
Relax centered legend image tolerance for minor shifts
cvanelteren Feb 9, 2026
798980d
Pin hash seed in CI and drop legend tolerance workaround
cvanelteren Feb 9, 2026
7c7e1a1
Remove temporary compare-step shell tracing
cvanelteren Feb 9, 2026
7311337
Merge remote-tracking branch 'origin/main' into HEAD
cvanelteren Feb 9, 2026
1ff58be
Refresh baseline cache key for hash-seed-stable compares
cvanelteren Feb 9, 2026
88dc567
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 10, 2026
ba36416
black
cvanelteren Feb 10, 2026
849b74a
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 10, 2026
c357bb1
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 11, 2026
711e205
Merge branch 'main' into feat/autoshare-auto-detect
cvanelteren Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions docs/subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,9 @@
# `~matplotlib.figure.Figure.supxlabel` and `~matplotlib.figure.Figure.supylabel`,
# these labels are aligned between gridspec edges rather than figure edges.
# #. Supporting five sharing "levels". These values can be passed to `sharex`,
# `sharey`, or `share`, or assigned to :rcraw:`subplots.share`. The levels
# are defined as follows:
# `sharey`, or `share`, or assigned to :rcraw:`subplots.share`.
# UltraPlot supports five explicit sharing levels plus ``'auto'``.
# The levels are defined as follows:
#
# * ``False`` or ``0``: Axis sharing is disabled.
# * ``'labels'``, ``'labs'``, or ``1``: Axis labels are shared, but nothing else.
Expand All @@ -384,6 +385,14 @@
# in the same row or column of the :class:`~ultraplot.gridspec.GridSpec`; a space
# or empty plot will add the labels, but not break the limit sharing. See below
# for a more complex example.
# * ``'limits'``, ``'lims'``, or ``2``: As above, plus share limits/scales/ticks.
# * ``True`` or ``3``: As above, plus hide inner tick labels.
# * ``'all'`` or ``4``: As above, plus share limits across the full subplot grid.
# * ``'auto'`` (default): Start from level ``3`` and only share compatible axes.
# This suppresses warnings for mixed axis families (e.g., cartesian + polar).
#
# Explicit sharing levels still force sharing attempts and may warn when
# incompatible axes are encountered.
#
# The below examples demonstrate the effect of various axis and label sharing
# settings on the appearance of several subplot grids.
Expand Down Expand Up @@ -422,6 +431,20 @@
import ultraplot as uplt
import numpy as np

# The default `share='auto'` keeps incompatible axis families unshared.
fig, axs = uplt.subplots(ncols=2, proj=("cart", "polar"))
x = np.linspace(0, 2 * np.pi, 100)
axs[0].plot(x, np.sin(x))
axs[1].plot(x, np.abs(np.sin(2 * x)))
axs.format(
suptitle="Auto sharing with mixed cartesian and polar axes",
title=("cartesian", "polar"),
)

# %%
import ultraplot as uplt
import numpy as np

state = np.random.RandomState(51423)

# Plots with minimum and maximum sharing settings
Expand Down
42 changes: 30 additions & 12 deletions ultraplot/axes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1702,21 +1702,39 @@ def shared(paxs):
iax._sharey_setup(left)

# External axes sharing, sometimes overrides panel axes sharing
# Share x axes
parent, *children = self._get_share_axes("x")
for child in children:
child._sharex_setup(parent)
# Share y axes
parent, *children = self._get_share_axes("y")
for child in children:
child._sharey_setup(parent)
# Global sharing, use the reference subplot because why not
# Share x axes within compatible groups
axes_x = self._get_share_axes("x")
for group in self.figure._partition_share_axes(axes_x, "x"):
if not group:
continue
parent, *children = group
for child in children:
child._sharex_setup(parent)

# Share y axes within compatible groups
axes_y = self._get_share_axes("y")
for group in self.figure._partition_share_axes(axes_y, "y"):
if not group:
continue
parent, *children = group
for child in children:
child._sharey_setup(parent)

# Global sharing, use the reference subplot where compatible
ref = self.figure._subplot_dict.get(self.figure._refnum, None)
if self is not ref:
if self is not ref and ref is not None:
if self.figure._sharex > 3:
self._sharex_setup(ref, labels=False)
ok, reason = self.figure._share_axes_compatible(ref, self, "x")
if ok:
self._sharex_setup(ref, labels=False)
else:
self.figure._warn_incompatible_share("x", ref, self, reason)
if self.figure._sharey > 3:
self._sharey_setup(ref, labels=False)
ok, reason = self.figure._share_axes_compatible(ref, self, "y")
if ok:
self._sharey_setup(ref, labels=False)
else:
self.figure._warn_incompatible_share("y", ref, self, reason)

def _artist_fully_clipped(self, artist):
"""
Expand Down
18 changes: 18 additions & 0 deletions ultraplot/axes/cartesian.py
Original file line number Diff line number Diff line change
Expand Up @@ -869,13 +869,31 @@ def _apply_log_formatter_on_scale(self, s):
self._update_formatter(s, "log")

def set_xscale(self, value, **kwargs):
fig = getattr(self, "figure", None)
if (
fig is not None
and hasattr(fig, "_is_auto_share_mode")
and fig._is_auto_share_mode("x")
):
self._unshare(which="x")
result = super().set_xscale(value, **kwargs)
self._apply_log_formatter_on_scale("x")
if fig is not None and hasattr(fig, "_refresh_auto_share"):
fig._refresh_auto_share("x")
return result

def set_yscale(self, value, **kwargs):
fig = getattr(self, "figure", None)
if (
fig is not None
and hasattr(fig, "_is_auto_share_mode")
and fig._is_auto_share_mode("y")
):
self._unshare(which="y")
result = super().set_yscale(value, **kwargs)
self._apply_log_formatter_on_scale("y")
if fig is not None and hasattr(fig, "_refresh_auto_share"):
fig._refresh_auto_share("y")
return result

def _update_formatter(
Expand Down
Loading