diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 37cc3d5f89e8..8091c7939502 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1269,7 +1269,7 @@ def _set_artist_props(self, a): def _update_ticks(self): """ Update ticks (position and labels) using the current data interval of - the axes. Return the list of ticks that will be drawn. + the axes. """ major_locs = self.get_majorticklocs() major_labels = self.major.formatter.format_ticks(major_locs) @@ -1285,7 +1285,7 @@ def _update_ticks(self): tick.update_position(loc) tick.label1.set_text(label) tick.label2.set_text(label) - ticks = [*major_ticks, *minor_ticks] + self._ticks = [*major_ticks, *minor_ticks] view_low, view_high = self.get_view_interval() if view_low > view_high: @@ -1302,10 +1302,16 @@ def _update_ticks(self): view_high = view_high - delta * margin view_low = view_low + delta * margin - interval_t = self.get_transform().transform([view_low, view_high]) + self._interval_t = self.get_transform().transform([view_low, view_high]) + def _get_ticks_to_draw(self, update=True): + """ + Return the list of ticks that will be drawn. + """ + if update: + self._update_ticks() ticks_to_draw = [] - for tick in ticks: + for tick in self._ticks: try: loc_t = self.get_transform().transform(tick.get_loc()) except AssertionError: @@ -1313,7 +1319,7 @@ def _update_ticks(self): # some scales might make them, so we need this try/except. pass else: - if mtransforms._interval_contains_close(interval_t, loc_t): + if mtransforms._interval_contains_close(self._interval_t, loc_t): ticks_to_draw.append(tick) return ticks_to_draw @@ -1341,7 +1347,7 @@ def get_tightbbox(self, renderer=None, *, for_layout_only=False): return if renderer is None: renderer = self.get_figure(root=True)._get_renderer() - ticks_to_draw = self._update_ticks() + ticks_to_draw = self._get_ticks_to_draw(update=True) self._update_label_position(renderer) @@ -1394,7 +1400,7 @@ def draw(self, renderer): return renderer.open_group(__name__, gid=self.get_gid()) - ticks_to_draw = self._update_ticks() + ticks_to_draw = self._get_ticks_to_draw(update=True) tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer) for tick in ticks_to_draw: @@ -2230,7 +2236,7 @@ def _get_tick_boxes_siblings(self, renderer): # If we want to align labels from other Axes: for ax in grouper.get_siblings(self.axes): axis = ax._axis_map[name] - ticks_to_draw = axis._update_ticks() + ticks_to_draw = axis._get_ticks_to_draw(update=True) tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer) bboxes.extend(tlb) bboxes2.extend(tlb2) diff --git a/lib/matplotlib/spines.py b/lib/matplotlib/spines.py index 7e77a393f2a2..b04ae3819f90 100644 --- a/lib/matplotlib/spines.py +++ b/lib/matplotlib/spines.py @@ -155,7 +155,7 @@ def get_window_extent(self, renderer=None): if self.axis is None or not self.axis.get_visible(): return bb bboxes = [bb] - drawn_ticks = self.axis._update_ticks() + drawn_ticks = self.axis._get_ticks_to_draw(update=True) major_tick = next(iter({*drawn_ticks} & {*self.axis.majorTicks}), None) minor_tick = next(iter({*drawn_ticks} & {*self.axis.minorTicks}), None) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 38857e846c55..504f12702265 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3128,7 +3128,8 @@ def test_log_scales(): ax.invert_yaxis() ax.set_xscale('log', base=9.0) xticks, yticks = ( - [(t.get_loc(), t.label1.get_text()) for t in axis._update_ticks()] + [(t.get_loc(), t.label1.get_text()) + for t in axis._get_ticks_to_draw(update=True)] for axis in [ax.xaxis, ax.yaxis] ) assert xticks == [ diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index b694bc827646..c82c8180e411 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -456,6 +456,9 @@ def draw(self, renderer): artist.do_3d_projection() if self._axis3don: + # Update ticks + for axis in self._axis_map.values(): + axis._update_ticks() # Draw panes first for axis in self._axis_map.values(): axis.draw_pane(renderer) diff --git a/lib/mpl_toolkits/mplot3d/axis3d.py b/lib/mpl_toolkits/mplot3d/axis3d.py index 4da5031b990c..4a1248dbdb4f 100644 --- a/lib/mpl_toolkits/mplot3d/axis3d.py +++ b/lib/mpl_toolkits/mplot3d/axis3d.py @@ -435,10 +435,9 @@ def _axmask(self): def _draw_ticks(self, renderer, edgep1, centers, deltas, highs, deltas_per_point, pos): - ticks = self._update_ticks() + ticks = self._get_ticks_to_draw(update=False) # We updated in Axes3D.draw() info = self._axinfo index = info["i"] - juggled = info["juggled"] mins, maxs, tc, highs = self._get_coord_info() centers, deltas = self._calc_centers_deltas(maxs, mins) @@ -461,17 +460,28 @@ def _draw_ticks(self, renderer, edgep1, centers, deltas, highs, # Get tick line positions pos = edgep1.copy() pos[index] = tick.get_loc() - pos[tickdir] = out_tickdir - x1, y1, z1 = proj3d.proj_transform(*pos, self.axes.M) - pos[tickdir] = in_tickdir - x2, y2, z2 = proj3d.proj_transform(*pos, self.axes.M) - # Get position of label - labeldeltas = (tick.get_pad() + default_label_offset) * points + # Add out and in tickdir positions + positions = [] + for td in (out_tickdir, in_tickdir): + p = pos.copy() + p[tickdir] = td + positions.append(p) + + # Add label position + p = pos.copy() + p[tickdir] = edgep1_tickdir + positions.append(_move_from_center( + p, centers, + (tick.get_pad() + default_label_offset) * points, + self._axmask() + )) + + xs, ys, zs = proj3d._proj_trans_points(np.array(positions), self.axes.M) - pos[tickdir] = edgep1_tickdir - pos = _move_from_center(pos, centers, labeldeltas, self._axmask()) - lx, ly, lz = proj3d.proj_transform(*pos, self.axes.M) + x1, y1, z1 = xs[0], ys[0], zs[0] + x2, y2, z2 = xs[1], ys[1], zs[1] + lx, ly, lz = xs[2], ys[2], zs[2] _tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.tick1line.set_linewidth(tick_lw[tick._major]) @@ -636,7 +646,7 @@ def draw_grid(self, renderer): renderer.open_group("grid3d", gid=self.get_gid()) - ticks = self._update_ticks() + ticks = self._get_ticks_to_draw(update=False) # We updated in Axes3D.draw() if len(ticks): # Get general axis information: info = self._axinfo