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
14 changes: 14 additions & 0 deletions lib/mpl_toolkits/mplot3d/axis3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,20 @@ def get_tightbbox(self, renderer=None, *, for_layout_only=False):
# docstring inherited
if not self.get_visible():
return
if renderer is None:
renderer = self.get_figure(root=True)._get_renderer()

locator = self.axes.get_axes_locator()
self.axes.apply_aspect(locator(self.axes, renderer) if locator else None)

# The 2D positions of 3D ticks and labels are updated during draw()
# based on the current projection. Refresh that state without
# rendering so the bbox query sees the same geometry as the real draw.
self.axes.M = self.axes.get_proj()
self.axes.invM = np.linalg.inv(self.axes.M)
with renderer._draw_disabled():
self.draw(renderer)

# We have to directly access the internal data structures
# (and hope they are up to date) because at draw time we
# shift the ticks and their labels around in (x, y) space
Expand Down
32 changes: 32 additions & 0 deletions lib/mpl_toolkits/mplot3d/tests/test_axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -2738,6 +2738,38 @@ def test_axes3d_set_aspect_deperecated_params():
ax.set_aspect('equal', adjustable='invalid_value')


def test_axis_get_tightbbox_before_draw_matches_after_draw():
fig = plt.figure()
ax = fig.add_subplot(projection='3d')

axes = [ax.xaxis, ax.yaxis, ax.zaxis]
renderer = fig.canvas.get_renderer()
bboxes_before = {
axis.axis_name: axis.get_tightbbox(renderer).extents.copy()
for axis in axes
}

fig.canvas.draw()
renderer = fig.canvas.get_renderer()
for axis in axes:
np.testing.assert_allclose(
bboxes_before[axis.axis_name],
axis.get_tightbbox(renderer).extents)


def test_constrained_layout_3d_axis_tightbbox_prevents_overlap():
fig = plt.figure(constrained_layout=True)
ax1 = fig.add_subplot(2, 1, 1, projection='3d')
ax1.set_title('3D Plot')
ax2 = fig.add_subplot(2, 1, 2)
ax2.set_title('2D Plot')

fig.canvas.draw()
renderer = fig.canvas.get_renderer()

assert ax1.get_tightbbox(renderer).y0 >= ax2.title.get_window_extent(renderer).y1


def test_axis_get_tightbbox_includes_offset_text():
# Test that axis.get_tightbbox includes the offset_text
# Regression test for issue #30744
Expand Down
Loading