Thanks to visit codestin.com
Credit goes to github.com

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
17 changes: 17 additions & 0 deletions lib/mpl_toolkits/mplot3d/axis3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,23 @@ 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()

# For constrained_layout, the layout engine queries tightbbox before
# any draw() call, so tick 2D positions have not been set yet and the
# bbox would be degenerate. Do a no-output draw to initialize them.
# M must be computed first if it hasn't been set yet.
# The flag is per-axis so each of xaxis/yaxis/zaxis is initialised once.
if (not getattr(self, '_tightbbox_initialized', False)
and self.get_figure(root=True).get_constrained_layout()):
if self.axes.M is None:
self.axes.M = self.axes.get_proj()
self.axes.invM = np.linalg.inv(self.axes.M)
with renderer._draw_disabled():
self.draw(renderer)
self._tightbbox_initialized = True

# 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions lib/mpl_toolkits/mplot3d/tests/test_axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -2780,6 +2780,39 @@ def test_axis_get_tightbbox_includes_offset_text():
f"bbox.y1 ({bbox.y1}) should be >= offset_bbox.y1 ({offset_bbox.y1})"


def test_axis_get_tightbbox_before_draw_includes_ticklabels():
# Regression test for GH#31277.
# Axis3D.get_tightbbox() must return a non-degenerate bbox before draw()
# has been called when constrained_layout is active, so that the layout
# engine can account for 3D tick labels.
fig = plt.figure(constrained_layout=True)
ax = fig.add_subplot(projection='3d')

renderer = fig.canvas.get_renderer()
for axis in [ax.xaxis, ax.yaxis, ax.zaxis]:
bbox = axis.get_tightbbox(renderer)
assert bbox is not None, f"{axis.axis_name}: get_tightbbox returned None"
assert bbox.width > 0 and bbox.height > 0, \
f"{axis.axis_name}: tightbbox has zero area before draw()"


def test_constrained_layout_3d_no_overlap_with_subplot_title():
# Regression test for GH#31277.
# When using constrained_layout, 3D tick labels must not overlap the title
# of an adjacent 2D subplot.
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, \
"3D subplot tick labels overlap the title of the 2D subplot below"


def test_ctrl_rotation_snaps_to_5deg():
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
Expand Down
Loading