Skip to content

Commit aab4211

Browse files
Separate out 3D axis label and ticks positions
1 parent cc70dcf commit aab4211

File tree

1 file changed

+98
-35
lines changed

1 file changed

+98
-35
lines changed

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ def __init__(self, *args, **kwargs):
7676

7777
name = self.axis_name
7878

79-
self.position = 'auto'
79+
self._label_position = 'default'
80+
self._tick_position = 'default'
8081

8182
# This is a temporary member variable.
8283
# Do not depend on this existing in future releases!
@@ -185,6 +186,54 @@ def get_minor_ticks(self, numticks=None):
185186
obj.set_transform(self.axes.transData)
186187
return ticks
187188

189+
def set_ticks_position(self, position):
190+
"""
191+
Set the ticks position.
192+
193+
Parameters
194+
----------
195+
position : {'lower', 'upper', 'both', 'default', 'none'}
196+
The position of the bolded axis lines, ticks, and tick labels.
197+
"""
198+
_api.check_in_list(['lower', 'upper', 'both', 'default', 'none'],
199+
position=position)
200+
self._tick_position = position
201+
202+
def get_ticks_position(self):
203+
"""
204+
Get the ticks position.
205+
206+
Returns
207+
-------
208+
position : {'lower', 'upper', 'both', 'default', 'none'}
209+
The position of the bolded axis lines, ticks, and tick labels.
210+
"""
211+
return self._tick_position
212+
213+
def set_label_position(self, position):
214+
"""
215+
Set the label position.
216+
217+
Parameters
218+
----------
219+
position : {'lower', 'upper', 'both', 'default', 'none'}
220+
The position of the axis label.
221+
"""
222+
_api.check_in_list(['lower', 'upper', 'both', 'default', 'none'],
223+
position=position)
224+
self._label_position = position
225+
226+
def get_label_position(self):
227+
"""
228+
Get the label position.
229+
230+
Returns
231+
-------
232+
position : {'lower', 'upper', 'both', 'default', 'none'}
233+
The position of the axis label.
234+
"""
235+
return self._label_position
236+
188237
def set_pane_color(self, color, alpha=None):
189238
"""
190239
Set pane color.
@@ -262,7 +311,7 @@ def _get_axis_line_edge_points(self, minmax, maxmin, position=None):
262311
# When changing vertical axis some of the axes has to be
263312
# moved to the other plane so it looks the same as if the z-axis
264313
# was the vertical axis.
265-
mb = [minmax, maxmin] # line from origin to near invisible corner
314+
mb = [minmax, maxmin] # line from origin to nearest corner to camera
266315
mb_rev = mb[::-1]
267316
mm = [[mb, mb_rev, mb_rev], [mb_rev, mb_rev, mb], [mb, mb, mb]]
268317
mm = mm[self.axes._vertical_axis][self._axinfo["i"]]
@@ -283,6 +332,25 @@ def _get_axis_line_edge_points(self, minmax, maxmin, position=None):
283332

284333
return edge_point_0, edge_point_1
285334

335+
def _get_all_axis_line_edge_points(self, minmax, maxmin, position=None):
336+
# Determine edge points for the axis lines
337+
edgep1s = []
338+
edgep2s = []
339+
if position in (None, 'default'):
340+
edgep1, edgep2 = self._get_axis_line_edge_points(minmax, maxmin)
341+
edgep1s = [edgep1]
342+
edgep2s = [edgep2]
343+
else:
344+
edgep1_l, edgep2_l = self._get_axis_line_edge_points(minmax, maxmin, position='lower')
345+
edgep1_u, edgep2_u = self._get_axis_line_edge_points(minmax, maxmin, position='upper')
346+
if position in ('lower', 'both'):
347+
edgep1s.append(edgep1_l)
348+
edgep2s.append(edgep2_l)
349+
if position in ('upper', 'both'):
350+
edgep1s.append(edgep1_u)
351+
edgep2s.append(edgep2_u)
352+
return edgep1s, edgep2s
353+
286354
def _get_tickdir(self):
287355
"""
288356
Get the direction of the tick.
@@ -339,8 +407,8 @@ def _axmask(self):
339407
return axmask
340408

341409

342-
def _draw_ticks(self, renderer, edgep1, deltas_per_point):
343-
mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
410+
def _draw_ticks(self, renderer, edgep1, centers, deltas, highs,
411+
deltas_per_point):
344412
ticks = self._update_ticks()
345413
info = self._axinfo
346414
index = info["i"]
@@ -380,10 +448,8 @@ def _draw_ticks(self, renderer, edgep1, deltas_per_point):
380448
tick.draw(renderer)
381449

382450

383-
def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, pep,
384-
dx, dy):
385-
mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
386-
451+
def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, centers,
452+
highs, pep, dx, dy):
387453
# Get general axis information:
388454
info = self._axinfo
389455
index = info["i"]
@@ -453,9 +519,9 @@ def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, pep,
453519
self.offsetText.draw(renderer)
454520

455521

456-
def _draw_labels(self, renderer, edgep1, edgep2, labeldeltas, dx, dy):
522+
def _draw_labels(self, renderer, edgep1, edgep2, labeldeltas, centers,
523+
dx, dy):
457524
info = self._axinfo
458-
mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
459525

460526
# Draw labels
461527
lxyz = 0.5 * (edgep1 + edgep2)
@@ -491,31 +557,14 @@ def draw(self, renderer):
491557
(self.labelpad + default_offset) * deltas_per_point * deltas)
492558

493559
# Determine edge points for the axis lines
494-
edgep1s = []
495-
edgep2s = []
496560
minmax = np.where(highs, maxs, mins) # "origin" point
497561
maxmin = np.where(~highs, maxs, mins) # "opposite" corner near camera
498-
if self.position == 'auto':
499-
edgep1, edgep2 = self._get_axis_line_edge_points(minmax, maxmin)
500-
edgep1s = [edgep1]
501-
edgep2s = [edgep2]
502-
else:
503-
edgep1_l, edgep2_l = self._get_axis_line_edge_points(minmax, maxmin, position='lower')
504-
edgep1_u, edgep2_u = self._get_axis_line_edge_points(minmax, maxmin, position='upper')
505-
if self.position in ('lower', 'both'):
506-
edgep1s.append(edgep1_l)
507-
edgep2s.append(edgep2_l)
508-
if self.position in ('upper', 'both'):
509-
edgep1s.append(edgep1_u)
510-
edgep2s.append(edgep2_u)
511562

512-
for edgep1, edgep2 in zip(edgep1s, edgep2s):
513-
# Draw the lines
563+
for edgep1, edgep2 in zip(*self._get_all_axis_line_edge_points(
564+
minmax, maxmin, self._tick_position)):
514565
# Project the edge points along the current position
515566
pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M)
516567
pep = np.asarray(pep)
517-
self.line.set_data(pep[0], pep[1])
518-
self.line.draw(renderer)
519568

520569
# The transAxes transform is used because the Text object
521570
# rotates the text relative to the display coordinate system.
@@ -527,15 +576,29 @@ def draw(self, renderer):
527576
dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) -
528577
self.axes.transAxes.transform([pep[0:2, 0]]))[0]
529578

530-
# Draw labels
531-
self._draw_labels(renderer, edgep1, edgep2, labeldeltas, dx, dy)
579+
# Draw the lines
580+
self.line.set_data(pep[0], pep[1])
581+
self.line.draw(renderer)
582+
583+
# Draw ticks
584+
self._draw_ticks(renderer, edgep1, centers, deltas, highs,
585+
deltas_per_point)
532586

533587
# Draw Offset text
534-
self._draw_offset_text(renderer, edgep1, edgep2, labeldeltas, pep,
535-
dx, dy)
588+
self._draw_offset_text(renderer, edgep1, edgep2, labeldeltas,
589+
centers, highs, pep, dx, dy)
536590

537-
# Draw ticks
538-
self._draw_ticks(renderer, edgep1, deltas_per_point)
591+
for edgep1, edgep2 in zip(*self._get_all_axis_line_edge_points(
592+
minmax, maxmin, self._label_position)):
593+
# See comments above
594+
pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M)
595+
pep = np.asarray(pep)
596+
dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) -
597+
self.axes.transAxes.transform([pep[0:2, 0]]))[0]
598+
599+
# Draw labels
600+
self._draw_labels(renderer, edgep1, edgep2, labeldeltas, centers,
601+
dx, dy)
539602

540603
renderer.close_group('axis3d')
541604
self.stale = False

0 commit comments

Comments
 (0)