@@ -192,7 +192,7 @@ def set_ticks_position(self, position):
192192
193193 Parameters
194194 ----------
195- position : {'lower', 'upper', 'both', 'default', 'none'}
195+ str : {'lower', 'upper', 'both', 'default', 'none'}
196196 The position of the bolded axis lines, ticks, and tick labels.
197197 """
198198 _api .check_in_list (['lower' , 'upper' , 'both' , 'default' , 'none' ],
@@ -205,7 +205,7 @@ def get_ticks_position(self):
205205
206206 Returns
207207 -------
208- position : {'lower', 'upper', 'both', 'default', 'none'}
208+ str : {'lower', 'upper', 'both', 'default', 'none'}
209209 The position of the bolded axis lines, ticks, and tick labels.
210210 """
211211 return self ._tick_position
@@ -216,7 +216,7 @@ def set_label_position(self, position):
216216
217217 Parameters
218218 ----------
219- position : {'lower', 'upper', 'both', 'default', 'none'}
219+ str : {'lower', 'upper', 'both', 'default', 'none'}
220220 The position of the axis label.
221221 """
222222 _api .check_in_list (['lower' , 'upper' , 'both' , 'default' , 'none' ],
@@ -229,7 +229,7 @@ def get_label_position(self):
229229
230230 Returns
231231 -------
232- position : {'lower', 'upper', 'both', 'default', 'none'}
232+ str : {'lower', 'upper', 'both', 'default', 'none'}
233233 The position of the axis label.
234234 """
235235 return self ._label_position
@@ -319,10 +319,8 @@ def _get_axis_line_edge_points(self, minmax, maxmin, position=None):
319319 juggled = self ._axinfo ["juggled" ]
320320 edge_point_0 = mm [0 ].copy () # origin point
321321
322- if ( (position == 'lower'
323- and mm [1 ][juggled [- 1 ]] < mm [0 ][juggled [- 1 ]])
324- or (position == 'upper'
325- and mm [1 ][juggled [- 1 ]] > mm [0 ][juggled [- 1 ]])):
322+ if ((position == 'lower' and mm [1 ][juggled [- 1 ]] < mm [0 ][juggled [- 1 ]]) or
323+ (position == 'upper' and mm [1 ][juggled [- 1 ]] > mm [0 ][juggled [- 1 ]])):
326324 edge_point_0 [juggled [- 1 ]] = mm [1 ][juggled [- 1 ]]
327325 else :
328326 edge_point_0 [juggled [0 ]] = mm [1 ][juggled [0 ]]
@@ -332,42 +330,72 @@ def _get_axis_line_edge_points(self, minmax, maxmin, position=None):
332330
333331 return edge_point_0 , edge_point_1
334332
335- def _get_all_axis_line_edge_points (self , minmax , maxmin , position = None ):
333+ def _get_all_axis_line_edge_points (self , minmax , maxmin , axis_position = None ):
336334 # Determine edge points for the axis lines
337335 edgep1s = []
338336 edgep2s = []
339- if position in (None , 'default' ):
337+ position = []
338+ if axis_position in (None , 'default' ):
340339 edgep1 , edgep2 = self ._get_axis_line_edge_points (minmax , maxmin )
341340 edgep1s = [edgep1 ]
342341 edgep2s = [edgep2 ]
342+ position = ['default' ]
343343 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' )
344+ edgep1_l , edgep2_l = self ._get_axis_line_edge_points (minmax , maxmin ,
345+ position = 'lower' )
346+ edgep1_u , edgep2_u = self ._get_axis_line_edge_points (minmax , maxmin ,
347+ position = 'upper' )
346348 if position in ('lower' , 'both' ):
347349 edgep1s .append (edgep1_l )
348350 edgep2s .append (edgep2_l )
349- if position in ('upper' , 'both' ):
351+ position .append ('lower' )
352+ if axis_position in ('upper' , 'both' ):
350353 edgep1s .append (edgep1_u )
351354 edgep2s .append (edgep2_u )
352- return edgep1s , edgep2s
355+ position .append ('upper' )
356+ return edgep1s , edgep2s , position
353357
354- def _get_tickdir (self ):
358+ def _get_tickdir (self , position ):
355359 """
356360 Get the direction of the tick.
357361
362+ Parameters
363+ ----------
364+ position : str, optional : {'upper', 'lower', 'default'}
365+ The position of the axis.
366+
358367 Returns
359368 -------
360369 tickdir : int
361370 Index which indicates which coordinate the tick line will
362371 align with.
363372 """
373+ _api .check_in_list (('upper' , 'lower' , 'default' ), position = position )
374+
364375 # TODO: Move somewhere else where it's triggered less:
365- tickdirs_base = [v ["tickdir" ] for v in self ._AXINFO .values ()]
376+ tickdirs_base = [v ["tickdir" ] for v in self ._AXINFO .values ()] # default
377+ elev_mod = np .mod (self .axes .elev + 180 , 360 ) - 180
378+ azim_mod = np .mod (self .axes .azim , 360 )
379+ if position == 'upper' :
380+ if elev_mod >= 0 :
381+ tickdirs_base = [2 , 2 , 0 ]
382+ else :
383+ tickdirs_base = [1 , 0 , 0 ]
384+ if (0 <= azim_mod < 180 ):
385+ tickdirs_base [2 ] = 1
386+ elif position == 'lower' :
387+ if elev_mod >= 0 :
388+ tickdirs_base = [1 , 0 , 1 ]
389+ else :
390+ tickdirs_base = [2 , 2 , 1 ]
391+ if (0 <= azim_mod < 180 ):
392+ tickdirs_base [2 ] = 0
366393 info_i = [v ["i" ] for v in self ._AXINFO .values ()]
367394
368395 i = self ._axinfo ["i" ]
369- j = self .axes ._vertical_axis - 2
370- # tickdir = [[1, 2, 1], [2, 2, 0], [1, 0, 0]][i]
396+ vert_ax = self .axes ._vertical_axis
397+ j = vert_ax - 2
398+ # default: tickdir = [[1, 2, 1], [2, 2, 0], [1, 0, 0]][vert_ax][i]
371399 tickdir = np .roll (info_i , - j )[np .roll (tickdirs_base , j )][i ]
372400 return tickdir
373401
@@ -398,23 +426,19 @@ def draw_pane(self, renderer):
398426 self .pane .draw (renderer )
399427 renderer .close_group ('pane3d' )
400428
401-
402429 def _axmask (self ):
403- info = self ._axinfo
404- index = info ["i" ]
405430 axmask = [True , True , True ]
406- axmask [index ] = False
431+ axmask [self . _axinfo [ "i" ] ] = False
407432 return axmask
408433
409-
410434 def _draw_ticks (self , renderer , edgep1 , centers , deltas , highs ,
411- deltas_per_point ):
435+ deltas_per_point , pos ):
412436 ticks = self ._update_ticks ()
413437 info = self ._axinfo
414438 index = info ["i" ]
415439
416440 # Draw ticks:
417- tickdir = self ._get_tickdir ()
441+ tickdir = self ._get_tickdir (pos )
418442 tickdelta = deltas [tickdir ] if highs [tickdir ] else - deltas [tickdir ]
419443
420444 tick_info = info ['tick' ]
@@ -447,13 +471,13 @@ def _draw_ticks(self, renderer, edgep1, centers, deltas, highs,
447471 tick .tick1line .set_linewidth (tick_lw [tick ._major ])
448472 tick .draw (renderer )
449473
450-
451474 def _draw_offset_text (self , renderer , edgep1 , edgep2 , labeldeltas , centers ,
452475 highs , pep , dx , dy ):
453476 # Get general axis information:
454477 info = self ._axinfo
455478 index = info ["i" ]
456479 juggled = info ["juggled" ]
480+ tickdir = info ["tickdir" ]
457481
458482 # Which of the two edge points do we want to
459483 # use for locating the offset text?
@@ -484,14 +508,14 @@ def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, centers,
484508 # using the wrong reference points).
485509 #
486510 # (TT, FF, TF, FT) are the shorthand for the tuple of
487- # (centpt[info[' tickdir']] <= pep[info[' tickdir'] , outerindex],
511+ # (centpt[tickdir] <= pep[tickdir, outerindex],
488512 # centpt[index] <= pep[index, outerindex])
489513 #
490514 # Three-letters (e.g., TFT, FTT) are short-hand for the array of bools
491515 # from the variable 'highs'.
492516 # ---------------------------------------------------------------------
493517 centpt = proj3d .proj_transform (* centers , self .axes .M )
494- if centpt [info [ ' tickdir' ]] > pep [info [ ' tickdir' ] , outerindex ]:
518+ if centpt [tickdir ] > pep [tickdir , outerindex ]:
495519 # if FT and if highs has an even number of Trues
496520 if (centpt [index ] <= pep [index , outerindex ]
497521 and np .count_nonzero (highs ) % 2 == 0 ):
@@ -518,10 +542,8 @@ def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, centers,
518542 self .offsetText .set_ha (align )
519543 self .offsetText .draw (renderer )
520544
521-
522- def _draw_labels (self , renderer , edgep1 , edgep2 , labeldeltas , centers ,
523- dx , dy ):
524- info = self ._axinfo
545+ def _draw_labels (self , renderer , edgep1 , edgep2 , labeldeltas , centers , dx , dy ):
546+ label = self ._axinfo ["label" ]
525547
526548 # Draw labels
527549 lxyz = 0.5 * (edgep1 + edgep2 )
@@ -531,12 +553,11 @@ def _draw_labels(self, renderer, edgep1, edgep2, labeldeltas, centers,
531553 if self .get_rotate_label (self .label .get_text ()):
532554 angle = art3d ._norm_text_angle (np .rad2deg (np .arctan2 (dy , dx )))
533555 self .label .set_rotation (angle )
534- self .label .set_va (info [ ' label' ] ['va' ])
535- self .label .set_ha (info [ ' label' ] ['ha' ])
536- self .label .set_rotation_mode (info [ ' label' ] ['rotation_mode' ])
556+ self .label .set_va (label ['va' ])
557+ self .label .set_ha (label ['ha' ])
558+ self .label .set_rotation_mode (label ['rotation_mode' ])
537559 self .label .draw (renderer )
538560
539-
540561 @artist .allow_rasterization
541562 def draw (self , renderer ):
542563 self .label ._transform = self .axes .transData
@@ -553,15 +574,14 @@ def draw(self, renderer):
553574 ax_points_estimate = sum (72. * ax_inches )
554575 deltas_per_point = 48 / ax_points_estimate
555576 default_offset = 21.
556- labeldeltas = (
557- (self .labelpad + default_offset ) * deltas_per_point * deltas )
577+ labeldeltas = (self .labelpad + default_offset ) * deltas_per_point * deltas
558578
559579 # Determine edge points for the axis lines
560580 minmax = np .where (highs , maxs , mins ) # "origin" point
561581 maxmin = np .where (~ highs , maxs , mins ) # "opposite" corner near camera
562582
563- for edgep1 , edgep2 in zip (* self ._get_all_axis_line_edge_points (
564- minmax , maxmin , self ._tick_position )):
583+ for edgep1 , edgep2 , pos in zip (* self ._get_all_axis_line_edge_points (
584+ minmax , maxmin , self ._tick_position )):
565585 # Project the edge points along the current position
566586 pep = proj3d ._proj_trans_points ([edgep1 , edgep2 ], self .axes .M )
567587 pep = np .asarray (pep )
@@ -582,23 +602,22 @@ def draw(self, renderer):
582602
583603 # Draw ticks
584604 self ._draw_ticks (renderer , edgep1 , centers , deltas , highs ,
585- deltas_per_point )
605+ deltas_per_point , pos )
586606
587607 # Draw Offset text
588608 self ._draw_offset_text (renderer , edgep1 , edgep2 , labeldeltas ,
589609 centers , highs , pep , dx , dy )
590610
591- for edgep1 , edgep2 in zip (* self ._get_all_axis_line_edge_points (
592- minmax , maxmin , self ._label_position )):
611+ for edgep1 , edgep2 , pos in zip (* self ._get_all_axis_line_edge_points (
612+ minmax , maxmin , self ._label_position )):
593613 # See comments above
594614 pep = proj3d ._proj_trans_points ([edgep1 , edgep2 ], self .axes .M )
595615 pep = np .asarray (pep )
596616 dx , dy = (self .axes .transAxes .transform ([pep [0 :2 , 1 ]]) -
597617 self .axes .transAxes .transform ([pep [0 :2 , 0 ]]))[0 ]
598618
599619 # Draw labels
600- self ._draw_labels (renderer , edgep1 , edgep2 , labeldeltas , centers ,
601- dx , dy )
620+ self ._draw_labels (renderer , edgep1 , edgep2 , labeldeltas , centers , dx , dy )
602621
603622 renderer .close_group ('axis3d' )
604623 self .stale = False
@@ -652,7 +671,7 @@ def get_tightbbox(self, renderer=None, *, for_layout_only=False):
652671 # (and hope they are up to date) because at draw time we
653672 # shift the ticks and their labels around in (x, y) space
654673 # based on the projection, the current view port, and their
655- # position in 3D space. If we extend the transforms framework
674+ # position in 3D space. If we extend the transforms framework
656675 # into 3D we would not need to do this different book keeping
657676 # than we do in the normal axis
658677 major_locs = self .get_majorticklocs ()
0 commit comments