@@ -53,6 +53,7 @@ class Axes3D(Axes):
5353 def __init__ (
5454 self , fig , rect = None , * args ,
5555 azim = - 60 , elev = 30 , sharez = None , proj_type = 'persp' ,
56+ box_aspect = None ,
5657 ** kwargs ):
5758 """
5859 Parameters
@@ -91,11 +92,7 @@ def __init__(
9192 self .zz_viewLim = Bbox .unit ()
9293 self .xy_dataLim = Bbox .unit ()
9394 self .zz_dataLim = Bbox .unit ()
94- if 'pb_aspect' in kwargs :
95- self .pb_aspect = np .asarray (kwargs ['pb_aspect' ])
96- else :
97- # chosen for similarity with the previous initial view
98- self .pb_aspect = np .array ([4 , 4 , 3 ]) / 3.5
95+
9996 # inhibit autoscale_view until the axes are defined
10097 # they can't be defined until Axes.__init__ has been called
10198 self .view_init (self .initial_elev , self .initial_azim )
@@ -105,7 +102,9 @@ def __init__(
105102 self ._shared_z_axes .join (self , sharez )
106103 self ._adjustable = 'datalim'
107104
108- super ().__init__ (fig , rect , frameon = True , * args , ** kwargs )
105+ super ().__init__ (
106+ fig , rect , frameon = True , box_aspect = box_aspect , * args , ** kwargs
107+ )
109108 # Disable drawing of axes by base class
110109 super ().set_axis_off ()
111110 # Enable drawing of axes by Axes3D class
@@ -309,6 +308,9 @@ def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
309308 share : bool, default: False
310309 If ``True``, apply the settings to all shared Axes.
311310
311+ See Also
312+ --------
313+ mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect
312314 """
313315 if aspect != 'auto' :
314316 raise NotImplementedError (
@@ -347,8 +349,43 @@ def set_anchor(self, anchor, share=False):
347349 ax ._anchor = anchor
348350 ax .stale = True
349351
350- def set_pb_aspect (self , pb_aspect , zoom = 1 ):
351- self .pb_aspect = pb_aspect * 1.8 * zoom / proj3d .mod (pb_aspect )
352+ def set_box_aspect (self , aspect , zoom = 1 ):
353+ """
354+ Set the axes box aspect.
355+
356+ The box aspect is the ratio of the axes height to the axes width in
357+ physical units. This is not to be confused with the data
358+ aspect, set via `~.Axes.set_aspect`.
359+
360+ Parameters
361+ ----------
362+ aspect : 3-tuple of floats on None
363+ Changes the physical dimensions of the Axes, such that the ratio
364+ of the size of the axis in physical units is x:y:z
365+
366+ The input will be normalized to a unit vector.
367+
368+ If None, it is approximately ::
369+
370+ ax.set_box_aspect(aspect=(4, 4, 3), zoom=1)
371+
372+ zoom : float
373+ Control the "zoom" of the
374+
375+ See Also
376+ --------
377+ mpl_toolkits.mplot3d.axes3d.Axes3D.set_aspect
378+ for a description of aspect handling.
379+ """
380+ if aspect is None :
381+ aspect = np .asarray ((4 , 4 , 3 ), dtype = float )
382+ else :
383+ aspect = np .asarray (aspect , dtype = float )
384+ # default scale tuned to match the mpl32 appearance.
385+ aspect *= 1.8294640721620434 * zoom / np .linalg .norm (aspect )
386+
387+ self ._box_aspect = aspect
388+ self .stale = True
352389
353390 def apply_aspect (self , position = None ):
354391 if position is None :
@@ -426,6 +463,7 @@ def get_axis_position(self):
426463 return xhigh , yhigh , zhigh
427464
428465 def _on_units_changed (self , scalex = False , scaley = False , scalez = False ):
466+
429467 """
430468 Callback for processing changes to axis units.
431469
@@ -973,8 +1011,6 @@ def set_proj_type(self, proj_type):
9731011
9741012 def get_proj (self ):
9751013 """Create the projection matrix from the current viewing position."""
976- # chosen for similarity with the initial view before gh-8896
977-
9781014 # elev stores the elevation angle in the z plane
9791015 # azim stores the azimuth angle in the x,y plane
9801016 #
@@ -990,10 +1026,11 @@ def get_proj(self):
9901026 # transform to uniform world coordinates 0-1, 0-1, 0-1
9911027 worldM = proj3d .world_transformation (xmin , xmax ,
9921028 ymin , ymax ,
993- zmin , zmax , pb_aspect = self .pb_aspect )
1029+ zmin , zmax ,
1030+ pb_aspect = self ._box_aspect )
9941031
9951032 # look into the middle of the new coordinates
996- R = self .pb_aspect / 2
1033+ R = self ._box_aspect / 2
9971034
9981035 xp = R [0 ] + np .cos (razim ) * np .cos (relev ) * self .dist
9991036 yp = R [1 ] + np .sin (razim ) * np .cos (relev ) * self .dist
0 commit comments