Skip to content
Open
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
73 changes: 73 additions & 0 deletions ultraplot/axes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2792,6 +2792,79 @@ def _reposition_subplot(self):
self.update_params()
setter(self.figbox) # equivalent to above

# In UltraLayout, place panels relative to their parent axes, not the grid.
if (
self._panel_parent
and self._panel_side
and self.figure.gridspec._use_ultra_layout
):
gs = self.get_subplotspec().get_gridspec()
figwidth, figheight = self.figure.get_size_inches()
ss = self.get_subplotspec().get_topmost_subplotspec()
row1, row2, col1, col2 = ss._get_rows_columns(ncols=gs.ncols_total)
side = self._panel_side
parent_bbox = self._panel_parent.get_position()
panels = list(self._panel_parent._panel_dict.get(side, ()))
anchor_ax = self._panel_parent
if self in panels:
idx = panels.index(self)
if idx > 0:
anchor_ax = panels[idx - 1]
elif panels:
anchor_ax = panels[-1]
anchor_bbox = anchor_ax.get_position()
anchor_ss = anchor_ax.get_subplotspec().get_topmost_subplotspec()
a_row1, a_row2, a_col1, a_col2 = anchor_ss._get_rows_columns(
ncols=gs.ncols_total
)

if side in ("right", "left"):
boundary = None
width = sum(gs._wratios_total[col1 : col2 + 1]) / figwidth
if a_col2 < col1:
boundary = a_col2
elif col2 < a_col1:
boundary = col2
# Fall back to an interface adjacent to this panel
boundary = min(
max(
_not_none(boundary, a_col2 if side == "right" else col2),
0,
),
len(gs.wspace_total) - 1,
)
pad = gs.wspace_total[boundary] / figwidth
if side == "right":
x0 = anchor_bbox.x1 + pad
else:
x0 = anchor_bbox.x0 - pad - width
bbox = mtransforms.Bbox.from_bounds(
x0, parent_bbox.y0, width, parent_bbox.height
)
else:
boundary = None
height = sum(gs._hratios_total[row1 : row2 + 1]) / figheight
if a_row2 < row1:
boundary = a_row2
elif row2 < a_row1:
boundary = row2
boundary = min(
max(
_not_none(boundary, a_row2 if side == "top" else row2),
0,
),
len(gs.hspace_total) - 1,
)
pad = gs.hspace_total[boundary] / figheight
if side == "top":
y0 = anchor_bbox.y1 + pad
else:
y0 = anchor_bbox.y0 - pad - height
bbox = mtransforms.Bbox.from_bounds(
parent_bbox.x0, y0, parent_bbox.width, height
)
setter(bbox)

def _update_abc(self, **kwargs):
"""
Update the a-b-c label.
Expand Down
2 changes: 1 addition & 1 deletion ultraplot/axes/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3187,9 +3187,9 @@ def _parse_level_lim(
for z in zs:
if z is None: # e.g. empty scatter color
continue
z = inputs._to_numpy_array(z)
if z.ndim > 2: # e.g. imshow data
continue
z = inputs._to_numpy_array(z)
if inbounds and x is not None and y is not None: # ignore if None coords
z = self._inbounds_vlim(x, y, z, to_centers=to_centers)
imin, imax = inputs._safe_range(z, pmin, pmax)
Expand Down
16 changes: 14 additions & 2 deletions ultraplot/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,9 @@ def __init__(
)
self._refnum = refnum
self._refaspect = refaspect
self._refaspect_default = 1 # updated for imshow and geographic plots
# Default to a square reference aspect; auto_layout will update this when an
# explicit aspect is detected (e.g., imshow, geographic plots).
self._refaspect_default = 1
self._refwidth = units(refwidth, "in")
self._refheight = units(refheight, "in")
self._figwidth = figwidth = units(figwidth, "in")
Expand Down Expand Up @@ -1841,7 +1843,7 @@ def _axes_dict(naxs, input, kw=False, default=None):
# Create or update the gridspec and add subplots with subplotspecs
# NOTE: The gridspec is added to the figure when we pass the subplotspec
if gs is None:
gs = pgridspec.GridSpec(*array.shape, **gridspec_kw)
gs = pgridspec.GridSpec(*array.shape, layout_array=array, **gridspec_kw)
else:
gs.update(**gridspec_kw)
axs = naxs * [None] # list of axes
Expand Down Expand Up @@ -2399,6 +2401,16 @@ def _align_content(): # noqa: E306
gs._auto_layout_tight(renderer)
_align_content()

# Finalize figure size using the latest spaces. If the size changes, update
# layout one more time to minimize surrounding whitespace with the new bounds.
figsize = gs._update_figsize()
eps = 0.01
if self._refwidth is not None or self._refheight is not None:
eps = 0
if not self._is_same_size(figsize, eps=eps):
# Use zero tolerance so sub-inch adjustments apply when ref sizes are set.
self.set_size_inches(figsize, internal=True, eps=0)

@warnings._rename_kwargs(
"0.10.0", mathtext_fallback="uplt.rc.mathtext_fallback = {}"
)
Expand Down
Loading
Loading