Skip to content

Commit b9f9d2e

Browse files
committed
ENH: implement get_tightbbox on Axis3D
1 parent bc43279 commit b9f9d2e

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,27 @@ def permutation_matrices(n):
28532853

28542854
return polygons
28552855

2856+
def get_tightbbox(self, renderer, call_axes_locator=True,
2857+
bbox_extra_artists=None, *, for_layout_only=False):
2858+
ret = super().get_tightbbox(renderer,
2859+
call_axes_locator=call_axes_locator,
2860+
bbox_extra_artists=bbox_extra_artists,
2861+
for_layout_only=for_layout_only)
2862+
batch = [ret]
2863+
if self._axis3don:
2864+
for axis in self._get_axis_list():
2865+
if axis.get_visible():
2866+
try:
2867+
axis_bb = axis.get_tightbbox(
2868+
renderer,
2869+
for_layout_only=for_layout_only
2870+
)
2871+
except TypeError:
2872+
# in case downstream library has redefined axis:
2873+
axis_bb = axis.get_tightbbox(renderer)
2874+
if axis_bb:
2875+
batch.append(axis_bb)
2876+
return mtransforms.Bbox.union(batch)
28562877

28572878
docstring.interpd.update(Axes3D=artist.kwdoc(Axes3D))
28582879
docstring.dedent_interpd(Axes3D.__init__)

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Parts rewritten by Reinier Heeres <reinier@heeres.eu>
44

55
import numpy as np
6-
6+
import matplotlib.transforms as mtransforms
77
from matplotlib import (
88
artist, lines as mlines, axis as maxis, patches as mpatches, rcParams)
99
from . import art3d, proj3d
@@ -398,12 +398,53 @@ def draw(self, renderer):
398398
renderer.close_group('axis3d')
399399
self.stale = False
400400

401-
# TODO: Get this to work properly when mplot3d supports
402-
# the transforms framework.
403-
def get_tightbbox(self, renderer):
404-
# Currently returns None so that Axis.get_tightbbox
405-
# doesn't return junk info.
406-
return None
401+
# TODO: Get this to work (more) properly when mplot3d supports the
402+
# transforms framework.
403+
def get_tightbbox(self, renderer, *, for_layout_only=False):
404+
# inherited docstring
405+
if not self.get_visible():
406+
return
407+
# We have to directly access the internal data structures
408+
# (and hope they are up to date) because at draw time we
409+
# shift the ticks and their labels around in (x, y) space
410+
# based on the projection, the current view port, and their
411+
# position in 3D space. If we extend the transforms framework
412+
# into 3D we would not need to do this different book keeping
413+
# than we do in the normal axis
414+
major_locs = self.get_majorticklocs()
415+
minor_locs = self.get_minorticklocs()
416+
417+
ticks = [*self.get_minor_ticks(len(minor_locs)),
418+
*self.get_major_ticks(len(major_locs))]
419+
view_low, view_high = self.get_view_interval()
420+
if view_low > view_high:
421+
view_low, view_high = view_high, view_low
422+
interval_t = self.get_transform().transform([view_low, view_high])
423+
424+
ticks_to_draw = []
425+
for tick in ticks:
426+
try:
427+
loc_t = self.get_transform().transform(tick.get_loc())
428+
except AssertionError:
429+
# transforms.transform doesn't allow masked values but
430+
# some scales might make them, so we need this try/except.
431+
pass
432+
else:
433+
if mtransforms._interval_contains_close(interval_t, loc_t):
434+
ticks_to_draw.append(tick)
435+
436+
ticks = ticks_to_draw
437+
438+
bb_1, bb_2 = self._get_tick_bboxes(ticks, renderer)
439+
other = []
440+
441+
if self.line.get_visible():
442+
other.append(self.line.get_window_extent(renderer))
443+
if (self.label.get_visible() and not for_layout_only and
444+
self.label.get_text()):
445+
other.append(self.label.get_window_extent(renderer))
446+
447+
return mtransforms.Bbox.union([*bb_1, *bb_2, *other])
407448

408449
@property
409450
def d_interval(self):

0 commit comments

Comments
 (0)