Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3872601
Refactor: Improve tick and label sharing logic
cvanelteren Oct 18, 2025
8fdd3ac
Test: Update tests for new label sharing logic
cvanelteren Oct 18, 2025
f75e987
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 18, 2025
b8c7155
fix edge cases
cvanelteren Oct 23, 2025
9180c93
stash
cvanelteren Oct 23, 2025
4ba0b5b
restore gridspec hidden parameter defaults
cvanelteren Oct 23, 2025
e688c37
revert explicit axis limit setting
cvanelteren Oct 23, 2025
0b48a78
Merge branch 'main' into test/update-label-sharing-tests
cvanelteren Oct 23, 2025
e23064f
bump merge
cvanelteren Oct 23, 2025
c6f496c
use new grid
cvanelteren Oct 23, 2025
219aab6
rm ticks for twin
cvanelteren Oct 23, 2025
7488032
add scale override
cvanelteren Oct 23, 2025
06646c5
bump
cvanelteren Oct 23, 2025
5f5bdbb
auto update limits
cvanelteren Oct 24, 2025
b039683
propagate panels for geo properly
cvanelteren Oct 24, 2025
73b97c3
propagate panels for geo properly
cvanelteren Oct 24, 2025
963a269
init
cvanelteren Oct 24, 2025
ded046d
fix gridspec indexing
cvanelteren Oct 24, 2025
38363bb
propagate grid type mismatch
cvanelteren Oct 24, 2025
f250108
rm debug
cvanelteren Oct 24, 2025
5801291
bump test
cvanelteren Oct 24, 2025
6c2bbd2
default lim to auto
cvanelteren Oct 24, 2025
ebeba47
make mpl compatible and refactor into smaller functions
cvanelteren Oct 24, 2025
c1691dd
skip colorbars on crawl
cvanelteren Oct 24, 2025
bde7626
forgot this chunk
cvanelteren Oct 24, 2025
cf4e2ac
restore test and remove debug
cvanelteren Oct 24, 2025
759926b
make panel sharing symmetric
cvanelteren Oct 24, 2025
73eb1e6
add additional guards
cvanelteren Oct 24, 2025
1461159
more tests to check if guards are working
cvanelteren Oct 25, 2025
80374b8
guard against non-rectilinear shares
cvanelteren Oct 25, 2025
deb2a31
Ensure that colorbars and legend do no interfere with layout
cvanelteren Oct 25, 2025
5f20dea
Check that colorbars do not interfere with layout
cvanelteren Oct 25, 2025
3ae2a3a
more stress tests
cvanelteren Oct 25, 2025
25f7d63
bump tests
cvanelteren Oct 25, 2025
c857e80
fix spelling
cvanelteren Oct 25, 2025
cd383b4
bump tests
cvanelteren Oct 25, 2025
b93f41f
bump test
cvanelteren Oct 25, 2025
4d60108
bump test
cvanelteren Oct 25, 2025
25a6cb8
remove show
cvanelteren Oct 25, 2025
8152429
add simple share test
cvanelteren Oct 25, 2025
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
31 changes: 27 additions & 4 deletions ultraplot/axes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,8 @@ def shared(paxs):
iax._panel_sharex_group = True
iax._sharex_setup(bottom) # parent is bottom-most
paxs = shared(self._panel_dict["top"])
if paxs and self.figure._sharex > 0:
self._panel_sharex_group = True
for iax in paxs:
iax._panel_sharex_group = True
iax._sharex_setup(bottom)
Expand All @@ -1559,6 +1561,8 @@ def shared(paxs):
iax._panel_sharey_group = True
iax._sharey_setup(left) # parent is left-most
paxs = shared(self._panel_dict["right"])
if paxs and self.figure._sharey > 0:
self._panel_sharey_group = True
for iax in paxs:
iax._panel_sharey_group = True
iax._sharey_setup(left)
Expand Down Expand Up @@ -3261,6 +3265,27 @@ def _is_panel_group_member(self, other: "Axes") -> bool:
# Not in the same panel group
return False

def _label_key(self, side: str) -> str:
"""
Map requested side name to the correct tick_params key across mpl versions.

This accounts for the API change around Matplotlib 3.10 where labeltop/labelbottom
became first-class tick parameter keys. For older versions, these map to
labelright/labelleft respectively.
"""
from packaging import version
from ..internals import _version_mpl

# TODO: internal deprecation warning when we drop 3.9, we need to remove this

use_new = version.parse(str(_version_mpl)) >= version.parse("3.10")
if side == "labeltop":
return "labeltop" if use_new else "labelright"
if side == "labelbottom":
return "labelbottom" if use_new else "labelleft"
# "labelleft" and "labelright" are stable across versions
return side

def _is_ticklabel_on(self, side: str) -> bool:
"""
Check if tick labels are on for the specified sides.
Expand All @@ -3274,10 +3299,8 @@ def _is_ticklabel_on(self, side: str) -> bool:
label = "label1"
if side in ["labelright", "labeltop"]:
label = "label2"
for tick in axis.get_major_ticks():
if getattr(tick, label).get_visible():
return True
return False

return axis.get_tick_params().get(self._label_key(side), False)

@docstring._snippet_manager
def inset(self, *args, **kwargs):
Expand Down
74 changes: 31 additions & 43 deletions ultraplot/axes/geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,27 +652,16 @@ def _apply_axis_sharing(self):
or to the *right* of the leftmost panel. But the sharing level used for
the leftmost and bottommost is the *figure* sharing level.
"""
# Handle X axis sharing
if self._sharex:
self._handle_axis_sharing(
source_axis=self._sharex._lonaxis,
target_axis=self._lonaxis,
)

# Handle Y axis sharing
if self._sharey:
self._handle_axis_sharing(
source_axis=self._sharey._lataxis,
target_axis=self._lataxis,
)
# Share interval x
if self._sharex and self.figure._sharex >= 2:
self._lonaxis.set_view_interval(*self._sharex._lonaxis.get_view_interval())
self._lonaxis.set_minor_locator(self._sharex._lonaxis.get_minor_locator())

# This block is apart of the draw sequence as the
# gridliner object is created late in the
# build chain.
if not self.stale:
return
if self.figure._get_sharing_level() == 0:
return
# Share interval y
if self._sharey and self.figure._sharey >= 2:
self._lataxis.set_view_interval(*self._sharey._lataxis.get_view_interval())
self._lataxis.set_minor_locator(self._sharey._lataxis.get_minor_locator())

def _get_gridliner_labels(
self,
Expand All @@ -691,38 +680,36 @@ def _toggle_gridliner_labels(
labelright=None,
geo=None,
):
# For BasemapAxes the gridlines are dicts with key as the coordinate and keys the line and label
# We override the dict here assuming the labels are mut excl due to the N S E W extra chars
"""
Toggle visibility of gridliner labels for each direction.

Parameters
----------
labeltop, labelbottom, labelleft, labelright : bool or None
Whether to show labels on each side. If None, do not change.
geo : optional
Not used in this method.
"""
# Ensure gridlines_major is fully initialized
if any(i is None for i in self.gridlines_major):
return

gridlabels = self._get_gridliner_labels(
bottom=labelbottom, top=labeltop, left=labelleft, right=labelright
)
bools = [labelbottom, labeltop, labelleft, labelright]
directions = "bottom top left right".split()
for direction, toggle in zip(directions, bools):

toggles = {
"bottom": labelbottom,
"top": labeltop,
"left": labelleft,
"right": labelright,
}

for direction, toggle in toggles.items():
if toggle is None:
continue
for label in gridlabels.get(direction, []):
label.set_visible(toggle)

def _handle_axis_sharing(
self,
source_axis: "GeoAxes",
target_axis: "GeoAxes",
):
"""
Helper method to handle axis sharing for both X and Y axes.

Args:
source_axis: The source axis to share from
target_axis: The target axis to apply sharing to
"""
# Copy view interval and minor locator from source to target

if self.figure._get_sharing_level() >= 2:
target_axis.set_view_interval(*source_axis.get_view_interval())
target_axis.set_minor_locator(source_axis.get_minor_locator())
label.set_visible(bool(toggle) or toggle in ("x", "y"))

@override
def draw(self, renderer=None, *args, **kwargs):
Expand Down Expand Up @@ -1441,6 +1428,7 @@ def _is_ticklabel_on(self, side: str) -> bool:
"""
# Deal with different cartopy versions
left_labels, right_labels, bottom_labels, top_labels = self._get_side_labels()

if self.gridlines_major is None:
return False
elif side == "labelleft":
Expand Down
10 changes: 10 additions & 0 deletions ultraplot/axes/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"""
import inspect

try:
from typing import override
except:
from typing_extensions import override

import matplotlib.projections.polar as mpolar
import numpy as np

Expand Down Expand Up @@ -138,6 +143,11 @@ def __init__(self, *args, **kwargs):
for axis in (self.xaxis, self.yaxis):
axis.set_tick_params(which="both", size=0)

@override
def _apply_axis_sharing(self):
# Not implemented. Silently pass
return

def _update_formatter(self, x, *, formatter=None, formatter_kw=None):
"""
Update the gridline label formatter.
Expand Down
5 changes: 2 additions & 3 deletions ultraplot/axes/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ def _share_axis_with(self, other: "Axes", *, which: str):
)

self._shared_axes[which].join(self, other)

# Get axis objects
this_axis = getattr(self, f"{which}axis")
other_axis = getattr(other, f"{which}axis")
Expand All @@ -227,7 +226,7 @@ def _share_axis_with(self, other: "Axes", *, which: str):
get_autoscale = getattr(other, f"get_autoscale{which}_on")

lim0, lim1 = limits
set_lim(lim0, lim1, emit=False, auto=get_autoscale())
set_lim(lim0, lim1, emit=False, auto=get_autoscale()) # Set scale

# Set scale
# Override scale
this_axis._scale = other_axis._scale
Loading
Loading