Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Loading