|
3 | 3 | # Parts rewritten by Reinier Heeres <reinier@heeres.eu>
|
4 | 4 |
|
5 | 5 | import numpy as np
|
6 |
| - |
| 6 | +import matplotlib.transforms as mtransforms |
7 | 7 | from matplotlib import (
|
8 | 8 | artist, lines as mlines, axis as maxis, patches as mpatches, rcParams)
|
9 | 9 | from . import art3d, proj3d
|
@@ -398,12 +398,53 @@ def draw(self, renderer):
|
398 | 398 | renderer.close_group('axis3d')
|
399 | 399 | self.stale = False
|
400 | 400 |
|
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]) |
407 | 448 |
|
408 | 449 | @property
|
409 | 450 | def d_interval(self):
|
|
0 commit comments