a
    a                     @   st  d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	Z	ddl
ZddlmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z! ddl"m#Z$ ddl%m&Z' ddl(m)Z* ddl+m,Z- ddlm.Z.m/Z/ ddl0m1Z1m2Z2 ddl+m3Z3 dd	l4m5Z5 d
dl6m7Z7 d
dl6m8Z8 d
dl6m9Z9 ej:e;dgdgdgdG dd de.Z<dddZ=dS )aR  
axes3d.py, original mplot3d version by John Porter
Created: 23 Sep 2005

Parts fixed by Reinier Heeres <reinier@heeres.eu>
Minor additions by Ben Axelrod <baxelrod@coroware.com>
Significant updates and revisions by Ben Root <ben.v.root@gmail.com>

Module containing Axes3D, an object which can plot 3D objects on a
2D matplotlib figure.
    )defaultdictN)Integral)_apicbook	docstring_preprocess_data)AxesrcParams)_axis_method_wrapper_process_plot_format)Bbox)Triangulation   )art3d)proj3d)axis3dxlimylimzlim)Zxlim3dZylim3dZzlim3dc                       sH  e Zd ZdZdZdZe ej	d< ddddddd	d
 fddZ
dd Zdd Zdd Z fddZdd Zdd ZeddZeddZejddd	dedd  Zejdd!d	ded"d  Zejddd	ded#d  Zdd$d%Zdd&d'Zdd(d)Zd fd+d,	Zd-d.d/d0Zdd1d2Ze j! fd3d4Z"d5d6 Z#d	d7d8Z$d9d: Z% fd;d<Z&d=d> Z' fd?d@Z(dAdB Z) fdCdDZ* fdEdFZ+dGdH Z,dddd	dIdJdKZ-d
dMdNZ.ddOdPZ/ddQdRZ0dSdT Z1ddddUdVdWZ2ddddXdYdZZ3dddd[d\d]Z4d^d_ Z5e6jj7je5_d`da Z8e6jj9je8_dbdc Z:ddde Z;dfdg Z<dhdi Z=djdk Z>e?dlj@g d\e<_e=_e>_eddmZAeddnZBeddoZCeddpZDeddqZEeddrdsdtiduZFeddvZGeGjreG jeHIdw7  _dxdy ZJddzd{ZKd|d} ZLd~d ZMdd ZNdddZOdd ZPdd ZQdd ZR fddZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdddZ[dd Z\dd Z]dd Z^e_ddddddZ`dddZad fdd	Zbdd Zcdd Zddd ZedddZfd fdd	ZgegZhejgZidd fdd
ZjejZkejldddddddddddZmdd ZndddÄZoejlddddddń ZpddddddƜddȄZqddd˄Zrddd̈́ZsdddτZtdddфZuev d*ddddҜ fddԄ
ZwewZxev d*ddddҜ fddք
Zydd؄ Zzev dddٜ fddۄ
Z{e{Z|ev dddٜ fdd݄
Z}d fdd	Z~evg ddd fdd	ZeZev d fdd	Zev d ddZd! fdd	Zev d-ddd*dddZeZddd	ddddZevg ddd"ddZd#d*d fddZev ddddddd ddZeZ  ZS ($  Axes3Dz
    3D axes object.
    3dxyzr   Ni   perspT)azimelevsharez	proj_type
box_aspectcomputed_zorderc                   s  |du rg d}|| _ || _| | || _t | _t | _t | _t | _	| 
| j| j  || _|dur| jd | | d| _|
dd}t j||g|	R d|d|
 t   |   d| _d| _|   | jjjj| jjd| j| jjd	| j| jjd
| jh |    | j!"d | j#$ %ddg}|d |d  \| _&| _'| j(dd )d |rt*j+dddd |,|  dS )at  
        Parameters
        ----------
        fig : Figure
            The parent figure.
        rect : (float, float, float, float)
            The ``(left, bottom, width, height)`` axes position.
        azim : float, default: -60
            Azimuthal viewing angle.
        elev : float, default: 30
            Elevation viewing angle.
        sharez : Axes3D, optional
            Other axes to share z-limits with.
        proj_type : {'persp', 'ortho'}
            The projection type, default 'persp'.
        computed_zorder : bool, default: True
            If True, the draw order is computed based on the average position
            of the `.Artist`\s along the view direction.
            Set to False if you want to manually control the order in which
            Artists are drawn on top of each other using their *zorder*
            attribute. This can be used for fine-tuning if the automatic order
            does not produce the desired result. Note however, that a manual
            zorder will only be correct for a limited view angle. If the figure
            is rotated by the user, it will look wrong from certain angles.
        auto_add_to_figure : bool, default: True
            Prior to Matplotlib 3.4 Axes3D would add themselves
            to their host Figure on init.  Other Axes class do not
            do this.

            This behavior is deprecated in 3.4, the default will
            change to False in 3.5.  The keyword will be undocumented
            and a non-False value will be an error in 3.6.

        **kwargs
            Other optional keyword arguments:

            %(Axes3D:kwdoc)s
        N)        r#         ?r$   r   datalimauto_add_to_figureT)frameonr!   motion_notify_eventbutton_press_eventbutton_release_eventr   r   r   )r   r   r   F3.4z3.6aQ  Axes3D(fig) adding itself to the figure is deprecated since %(since)s. Pass the keyword argument auto_add_to_figure=False and use fig.add_axes(ax) to suppress this warning. The default value of auto_add_to_figure will change to False in mpl3.5 and True values will no longer work %(removal)s.  This is consistent with other Axes classes.)removalmessage)-initial_aziminitial_elevset_proj_typer"   r   unit
xy_viewLim
zz_viewLim
xy_dataLim
zz_dataLim	view_init_sharez_shared_axesjoin_adjustablepopsuper__init__set_axis_offset_axis_onM	fmt_zdata
mouse_initfigurecanvas	callbacks_pickled_cidsupdatempl_connect_on_move_button_press_button_releaseset_top_viewpatchset_linewidthtransLimitsinverted	transform	_pseudo_w	_pseudo_hspinesset_visibler   warn_deprecatedadd_axes)selffigrectr   r   r   r    r!   r"   argskwargsr&   Zpseudo_bbox	__class__ k/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/mpl_toolkits/mplot3d/axes3d.pyr>   8   sf    ,





	zAxes3D.__init__c                 C   s   d| _ d| _d S )NFT	_axis3donstalerY   r`   r`   ra   r?      s    zAxes3D.set_axis_offc                 C   s   d| _ d| _d S )NTrb   re   r`   r`   ra   r@      s    zAxes3D.set_axis_onc                 C   s   | j |S )zs
        For artists in an axes, if the zaxis has units support,
        convert *z* using zaxis unit type
        )zaxisconvert_units)rY   r   r`   r`   ra   convert_zunits   s    zAxes3D.convert_zunitsc                    sT   d| j  }d| j  }d| j  }d| j  }t j| |d d t j| |d d d S )Ngffffff?g?auto)distr=   set_xlimset_ylim)rY   ZxdwlZxdwZydwlZydwr^   r`   ra   rM      s    



zAxes3D.set_top_viewc                 C   sp   t d| jj| jj| | _t d| jj| jj| | _t 	d| j
j| jj| | _| j| j| jfD ]}|  q^dS )z5Init 3D axes; overrides creation of regular X/Y axes.r   r   r   N)r   XAxisr3   	intervalxr5   xaxisYAxis	intervalyyaxisZZAxisr4   r6   rf   Zinit3d)rY   axr`   r`   ra   
_init_axis   s    zAxes3D._init_axisc                 C   s   | j S )z0Return the ``ZAxis`` (`~.axis3d.Axis`) instance.rf   re   r`   r`   ra   	get_zaxis   s    zAxes3D.get_zaxisrf   get_gridlinesget_ticklines3.1rp   )alternativependingc                 C   s   | j S N)rp   re   r`   r`   ra   <lambda>       zAxes3D.<lambda>rs   c                 C   s   | j S r}   )rs   re   r`   r`   ra   r~      r   c                 C   s   | j S r}   rv   re   r`   r`   ra   r~      r   c              
   C   s\   |p
|   \}}}}}}|||f|||f|||f|||f|||f|||f|||f|||fgS r}   )
get_w_lims)rY   valsminxmaxxminymaxyminzmaxzr`   r`   ra   	unit_cube   s    zAxes3D.unit_cubec                 C   s(   |d u r| j }| |}t||}|S r}   )rA   r   r   Zproj_points)rY   r   rA   ZxyzsZtcuber`   r`   ra   
tunit_cube   s
    
zAxes3D.tunit_cubec                 C   s   |  ||}|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d f|d |d fg}|S )	Nr   r                     )r   )rY   r   rA   tcedgesr`   r`   ra   tunit_edges   s    zAxes3D.tunit_edgesFc                    s0   |dkrt d|dt j||||d dS )ai  
        Set the aspect ratios.

        Axes 3D does not current support any aspect but 'auto' which fills
        the axes with the data limits.

        To simulate having equal aspect in data space, set the ratio
        of your data limits to match the value of `.get_box_aspect`.
        To control box aspect ratios use `~.Axes3D.set_box_aspect`.

        Parameters
        ----------
        aspect : {'auto'}
            Possible values:

            =========   ==================================================
            value       description
            =========   ==================================================
            'auto'      automatic; fill the position rectangle with data.
            =========   ==================================================

        adjustable : None
            Currently ignored by Axes3D

            If not *None*, this defines which parameter will be adjusted to
            meet the required aspect. See `.set_adjustable` for further
            details.

        anchor : None or str or 2-tuple of float, optional
            If not *None*, this defines where the Axes will be drawn if there
            is extra space due to aspect constraints. The most common way to
            to specify the anchor are abbreviations of cardinal directions:

            =====   =====================
            value   description
            =====   =====================
            'C'     centered
            'SW'    lower left corner
            'S'     middle of bottom edge
            'SE'    lower right corner
            etc.
            =====   =====================

            See `~.Axes.set_anchor` for further details.

        share : bool, default: False
            If ``True``, apply the settings to all shared Axes.

        See Also
        --------
        mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect
        rj   zIAxes3D currently only supports the aspect argument 'auto'. You passed in .)
adjustableanchorshareN)NotImplementedErrorr=   
set_aspect)rY   aspectr   r   r   r^   r`   ra   r     s    5zAxes3D.set_aspectr   )zoomc                C   sj   |du rt jdtd}n*|}t j|td}|jdkrBtd||d| t j| 9 }|| _d| _dS )ao  
        Set the axes box aspect.

        The box aspect is the ratio of height to width in display
        units for each face of the box when viewed perpendicular to
        that face.  This is not to be confused with the data aspect
        (which for Axes3D is always 'auto').  The default ratios are
        4:4:3 (x:y:z).

        To simulate having equal aspect in data space, set the box
        aspect to match your data range in each dimension.

        *zoom* controls the overall size of the Axes3D in the figure.

        Parameters
        ----------
        aspect : 3-tuple of floats or None
            Changes the physical dimensions of the Axes3D, such that the ratio
            of the axis lengths in display units is x:y:z.

            If None, defaults to 4:4:3

        zoom : float
            Control overall size of the Axes3D in the figure.
        N)r   r   r   dtype)r   z?You must pass a 3-tuple that can be cast to floats. You passed gIr|E?T)	npasarrayfloatshape
ValueErrorlinalgnorm_box_aspectrd   )rY   r   r   Zorig_aspectr`   r`   ra   set_box_aspect>  s    
zAxes3D.set_box_aspectc                 C   sx   |d u r| j dd}|  j}tjdddd|}|j|j }d}|	 }|
|||}| ||  |d d S )NT)originalr   r   active)get_position
get_figuretransSubfiguremtransformsr   from_boundstransformedheightwidthfrozenshrunk_to_aspect_set_positionanchored
get_anchor)rY   positiontransbb
fig_aspectr!   pbpb1r`   r`   ra   apply_aspecth  s    
zAxes3D.apply_aspectc                    s     j  d_ }|r<| }| n   _fdddD }tj	t
 fi |   fdd}dd jD }jrtd	d  D d
 }| }}	t||ddD ]:}
t|
tjr||
_|d
7 }qt|
tjr|	|
_|	d
7 }	qn|D ]}
|
  qjr\ D ]}|  q0 D ]}|  qJt   W d    n1 s~0    Y  d S )NFc                    s:   i | ]2}|t jd |d| dtt |fddqS )r,   z
self.axes.)namer{   c                 S   s   |S r}   r`   )rY   _valuer`   r`   ra   r~     r   z(Axes3D.draw.<locals>.<dictcomp>.<lambda>)r   
deprecatedpropertygetattr).0r   re   r`   ra   
<dictcomp>  s   
zAxes3D.draw.<locals>.<dictcomp>)rA   vveceyeget_axis_positionc              	      sT   zt | j}|  W n. ttfyF   tjddd |   Y S 0 |  S dS )a7  
                Call `do_3d_projection` on an *artist*, and warn if passing
                *renderer*.

                Attempt to bind the empty signature first, so external Artists
                can avoid the deprecation warning if they support the new
                calling convention.
                r,   zvThe 'renderer' parameter of do_3d_projection() was deprecated in Matplotlib %(since)s and will be removed %(removal)s.r.   N)inspect	signaturedo_3d_projectionbindr   	TypeErrorr   rW   )artistr   )rendererr`   ra   r     s    	z%Axes3D.draw.<locals>.do_3d_projectionc                 s   s$   | ]}t |tjtjfr|V  qd S r}   )
isinstancemcoll
CollectionmpatchesPatch)r   r   r`   r`   ra   	<genexpr>  s   zAxes3D.draw.<locals>.<genexpr>c                 s   s   | ]}|  V  qd S r}   )
get_zorder)r   axisr`   r`   ra   r     s   r   T)keyreverse)_unstale_viewLimrN   draw_frameonget_axes_locatorr   get_projrA   r   _setattr_cmtype	_childrenr"   max_get_axis_listsortedr   r   r   zorderr   r   r   rc   Z	draw_paner=   )rY   r   locatorposZprops3dr   Zcollections_and_patchesZzorder_offsetZcollection_zorderZpatch_zorderr   r   r^   )r   rY   ra   r   y  sT    




zAxes3D.drawc                 C   sh   |   }| || j}|d d |d d k}|d d |d d k}|d d |d d k}|||fS )Nr   r   r   r   )r   r   rA   )rY   r   r   ZxhighZyhighZzhighr`   r`   ra   r     s    zAxes3D.get_axis_positionc                 C   sV   |d u rt j| j|t dS tj|  |d |   | j|dk|dk|dkd d S )N)event)	axis_namer   r   r   scalexscaleyscalez)		functoolspartial_unit_change_handlerobjectr   check_in_list_get_axis_maprelim_request_autoscale_view)rY   r   r   r`   r`   ra   r     s    

zAxes3D._unit_change_handlerc                 K   s   d S r}   r`   )rY   xysr]   r`   r`   ra   update_datalim  s    zAxes3D.update_datalimc                    s   t   o|  S r}   )r=   get_autoscale_onget_autoscalez_onre   r^   r`   ra   r     s    zAxes3D.get_autoscale_onc                 C   s   | j S )z(Return whether the z-axis is autoscaled._autoscaleZonre   r`   r`   ra   r     s    zAxes3D.get_autoscalez_onc                    s   t  | | | d S r}   )r=   set_autoscale_onset_autoscalez_onrY   br^   r`   ra   r     s    zAxes3D.set_autoscale_onc                 C   s
   || _ dS )z
        Set whether the z-axis is autoscaled on the next draw or call to
        `.Axes.autoscale_view`.

        Parameters
        ----------
        b : bool
        Nr   r   r`   r`   ra   r     s    	zAxes3D.set_autoscalez_onc                    s$   | j d }t | || j d< d S Nr   )_stale_viewlimsr=   set_xmarginrY   mr   r^   r`   ra   r   	  s    
zAxes3D.set_xmarginc                    s$   | j d }t | || j d< d S r   )r   r=   set_ymarginr  r^   r`   ra   r    s    
zAxes3D.set_ymarginc                 C   s8   |dk s|dkrt d|| _| jdddd d| _dS )z
        Set padding of Z data limits prior to autoscaling.

        *m* times the data interval will be added to each
        end of that interval before it is used in autoscaling.

        accepts: float in range 0 to 1
        r   r   zmargin must be in range 0 to 1FTr   N)r   _zmarginr   rd   )rY   r  r`   r`   ra   set_zmargin  s
    	zAxes3D.set_zmargin)r   r   r   tightc                G   s  |r&|dur&|dur&|dur&t dnBt|dkrD|d  } }}n$t|dkr\|\}}}n|rht d|du r|du r|du r|durtd|d	 | j| j| jfS |dur| | |dur| | |dur| 	| | j
||du|du|dud
 dS )a  
        Convenience method to set or retrieve autoscaling margins.

        Call signatures::

            margins()

        returns xmargin, ymargin, zmargin

        ::

            margins(margin)

            margins(xmargin, ymargin, zmargin)

            margins(x=xmargin, y=ymargin, z=zmargin)

            margins(..., tight=False)

        All forms above set the xmargin, ymargin and zmargin
        parameters. All keyword parameters are optional.  A single
        positional argument specifies xmargin, ymargin and zmargin.
        Passing both positional and keyword arguments for xmargin,
        ymargin, and/or zmargin is invalid.

        The *tight* parameter
        is passed to :meth:`autoscale_view`, which is executed after
        a margin is changed; the default here is *True*, on the
        assumption that when margins are specified, no additional
        padding to match tick marks is usually desired.  Setting
        *tight* to *None* will preserve the previous setting.

        Specifying any margin changes only the autoscaling; for example,
        if *xmargin* is not None, then *xmargin* times the X data
        interval will be added to each end of that interval before
        it is used in autoscaling.
        NzECannot pass both positional and keyword arguments for x, y, and/or z.r   r   r   zYMust pass a single positional argument for all margins, or one for each margin (x, y, z).Tzignoring tight=z in get moder  r   r   r   )r   lenr   warn_external_xmargin_ymarginr  r   r  r  autoscale_view)rY   r   r   r   r  marginsr`   r`   ra   r  *  s,    &



zAxes3D.marginsbothc                 C   s   |du rd}d}d}nT|dv r.t | | _}nd}|dv rJt | | _}nd}|dv rft | | _}nd}| j||||d dS )a9  
        Convenience method for simple axis view autoscaling.
        See :meth:`matplotlib.axes.Axes.autoscale` for full explanation.
        Note that this function behaves the same, but for all
        three axes.  Therefore, 'z' can be passed for *axis*,
        and 'both' applies to all three axes.
        NTr   r  Fr   r  r   r  r  )bool_autoscaleXon_autoscaleYonr   r   )rY   enabler   r  r   r   r   r`   r`   ra   	autoscalel  s     
zAxes3D.autoscalec                 C   s   t |t |kr<| jt t |t |g|  n | j||  | j||  |d urt| j||  | 	  d S r}   )
r   r   r5   update_from_data_xycolumn_stackravelupdate_from_data_xupdate_from_data_yr6   r  )rY   XYZhad_datar`   r`   ra   auto_scale_xyz  s    zAxes3D.auto_scale_xyzc                 C   s   |du rL| j }|sZ| jD ]0}t|tjr.d}qt|tjtjfrd} qZqnt	| }| _ |r| j
r| jd   | jj\}}| j }	|	||\}}| jdkr|| | j }
||
8 }||
7 }|s|	||\}}| || |rn| jrn| jd   | jj\}}| j }|||\}}| jdkrL|| | j }
||
8 }||
7 }|sb|||\}}| || |r| jr| jd   | jj\}}| j }|||\}}| jdkr|| | j }
||
8 }||
7 }|s|||\}}| || dS )a  
        Autoscale the view limits using the data limits.
        See :meth:`matplotlib.axes.Axes.autoscale_view` for documentation.
        Note that this function applies to the 3D axes, and as such
        adds the *scalez* to the function arguments.
        NTFr   r   r   r   )_tightr   r   mimage	AxesImagemlinesLine2Dr   r   r  r  r9   cleanr5   ro   rp   get_major_locatornonsingularr
  view_limits
set_xboundr  rr   rs   r  
set_yboundr   r6   rf   r  
set_zbound)rY   r  r   r   r   r!  r   x0x1Zxlocatordeltay0y1Zylocatorz0z1Zzlocatorr`   r`   ra   r    s\    






zAxes3D.autoscale_viewc                 C   s4   |   \}}|  \}}|  \}}||||||fS )zGet 3D world limits.)
get_xlim3d
get_ylim3d
get_zlim3d)rY   r   r   r   r   r   r   r`   r`   ra   r     s    zAxes3D.get_w_lims)xminxmaxc                C   s  |du rt |r|\}}|dur6|dur2td|}|durR|durNtd|}| jd||ffgdd | || j}| || j}|  \}}|du r|}|du r|}||krtd| d ||k}	| j	
 ||\}}| j	||\}}t||gt|	d	\}}||f| j_| jd | D ]}
d|
jd< q(|durNt|| _|r| jd
|  | jd | D ]>}|| urr|j| jjd|d |j| jkrr|jj  qrd| _||fS )zm
        Set 3D x limits.

        See :meth:`matplotlib.axes.Axes.set_xlim` for full documentation.
        Nz"Cannot pass both `xmin` and `left`z#Cannot pass both `xmax` and `right`r   Fconvertz-Attempting to set identical left == right == > results in singular transformations; automatically expanding.r   xlim_changedemitrj   T)r   iterabler   _process_unit_info_validate_converted_limitsconvert_xunitsget_xlimr   r	  rp   r'  r(  limit_range_for_scaler   r  r3   ro   r9   get_siblingsr   r  rF   processrl   rD   rE   	draw_idlerd   )rY   leftrightr?  rj   r7  r8  old_left	old_rightr   rt   otherr`   r`   ra   
set_xlim3d  sT    




zAxes3D.set_xlim3d)yminymaxc                C   s  |du rt |r|\}}|dur6|dur2td|}|durR|durNtd|}| jd||ffgdd | || j}| || j}|  \}}|du r|}|du r|}||krtd| d ||k}	| j	
 ||\}}| j	||\}}|	r|| }}||f| j_| jd | D ]}
d|
jd< q |durFt|| _|r| jd	|  | jd | D ]>}|| urj|j| jjd|d
 |j| jkrj|jj  qjd| _||fS )zm
        Set 3D y limits.

        See :meth:`matplotlib.axes.Axes.set_ylim` for full documentation.
        Nz$Cannot pass both `ymin` and `bottom`z!Cannot pass both `ymax` and `top`r   Fr9  -Attempting to set identical bottom == top == r;  ylim_changedr>  T)r   r@  r   rA  rB  convert_yunitsget_ylimr   r	  rs   r'  r(  rE  r3   rr   r9   rF  r   r  r  rF   rG  rm   rD   rE   rH  rd   )rY   bottomtopr?  rj   rO  rP  
old_bottomold_topswappedrt   rM  r`   r`   ra   
set_ylim3d  sV    





zAxes3D.set_ylim3d)zminzmaxc                C   s  |du rt |r|\}}|dur6|dur2td|}|durR|durNtd|}| jd||ffgdd | || j}| || j}|  \}}|du r|}|du r|}||krtd| d ||k}	| j	
 ||\}}| j	||\}}|	r|| }}||f| j_| jd | D ]}
d|
jd< q |durFt|| _|r| jd	|  | jd | D ]>}|| urj|j| jjd|d
 |j| jkrj|jj  qjd| _||fS )zl
        Set 3D z limits.

        See :meth:`matplotlib.axes.Axes.set_ylim` for full documentation
        Nz$Cannot pass both `zmin` and `bottom`z!Cannot pass both `zmax` and `top`r   Fr9  rQ  r;  Zzlim_changedr>  T)r   r@  r   rA  rB  rh   get_zlimr   r	  rf   r'  r(  rE  r4   ro   r9   rF  r   r  r   rF   rG  set_zlimrD   rE   rH  rd   )rY   rU  rV  r?  rj   r[  r\  rW  rX  rY  rt   rM  r`   r`   ra   
set_zlim3dN  sV    





zAxes3D.set_zlim3dc                 C   s   t | jjS r}   )tupler3   ro   re   r`   r`   ra   r4    s    zAxes3D.get_xlim3dc                 C   s   t | jjS r}   )r`  r3   rr   re   r`   r`   ra   r5    s    zAxes3D.get_ylim3dc                 C   s   t | jjS )zGet 3D z limits.)r`  r4   ro   re   r`   r`   ra   r6    s    zAxes3D.get_zlim3dc                 C   s   dd t   | j S )Nz3
        Return the zaxis scale string %s

        z, )r:   mscaleget_scale_namesrf   	get_scalere   r`   r`   ra   
get_zscale  s    zAxes3D.get_zscalec                 K   s4   | j j|fi | | jddd |   d| _d S )NF)r   r   T)rp   
_set_scaler  _update_transScalerd   rY   valuer]   r`   r`   ra   
set_xscale  s    zAxes3D.set_xscalec                 K   s4   | j j|fi | | jddd |   d| _d S )NF)r   r   T)rs   re  r  rf  rd   rg  r`   r`   ra   
set_yscale  s    zAxes3D.set_yscalec                 K   s4   | j j|fi | | jddd |   d| _d S )NF)r   r   T)rf   re  r  rf  rd   rg  r`   r`   ra   
set_zscale  s    zAxes3D.set_zscalea  
        Set the {}-axis scale.

        Parameters
        ----------
        value : {{"linear"}}
            The axis scale type to apply.  3D axes currently only support
            linear scales; other scales yield nonsensical results.

        **kwargs
            Keyword arguments are nominally forwarded to the scale class, but
            none of them is applicable for linear scales.
        get_ticklocs	set_ticksget_majorticklabelsget_minorticklabelsget_ticklabels_set_ticklabelszAxis.set_tickszAxes3D.set_zticks)doc_sub	axis_datez

        Notes
        -----
        This function is merely provided for completeness, but 3D axes do not
        support dates for ticks, and so this may not work as expected.
        c                 O   s   dS )z:Currently not implemented for 3D axes, and returns *None*.Nr`   )rY   r\   r]   r`   r`   ra   clabel  s    zAxes3D.clabelc                 C   sT   d| _ |du r| j| _n|| _|du r0| j| _n|| _tjtdddd|d| _dS )a  
        Set the elevation and azimuth of the axes in degrees (not radians).

        This can be used to rotate the axes programmatically.

        Parameters
        ----------
        elev : float, default: None
            The elevation angle in the vertical plane in degrees.
            If None then the initial value as specified in the `Axes3D`
            constructor is used.
        azim : float, default: None
            The azimuth angle in the horizontal plane in degrees.
            If None then the initial value as specified in the `Axes3D`
            constructor is used.
        vertical_axis : {"z", "x", "y"}, default: "z"
            The axis to align vertically. *azim* rotates about this axis.
        
   Nr   r   r   r   )vertical_axis)	rk   r0   r   r/   r   r   check_getitemdict_vertical_axis)rY   r   r   rv  r`   r`   ra   r7     s    

zAxes3D.view_initc                 C   s   t jtjtjd|d| _dS )zx
        Set the projection type.

        Parameters
        ----------
        proj_type : {'persp', 'ortho'}
        )r   ortho)r    N)r   rw  r   Zpersp_transformationortho_transformation_projection)rY   r    r`   r`   ra   r1     s    zAxes3D.set_proj_typec                 C   s   t || jd S )z1Roll arrays to match the different vertical axis.r   )r   rollry  )rY   arrr`   r`   ra   _roll_to_vertical  s    zAxes3D._roll_to_verticalc                 C   s2  |  | j}tjg |  |  |  R d|i}d| }t| j	}t| j
}t|t| }t|t| }t|}|  |||g}	|| j|	  }
|
| _||
 | _| jtj| j | _td}t|dtj krdnd|| j< t|
||}| | j | j}t||}t||}|S )z?Create the projection matrix from the current viewing position.Z	pb_aspect      ?r   r   )r  r   r   Zworld_transformationr4  r5  r6  r   deg2radr   r   cossinrk   r   r   r   r   zerosabspiry  Zview_transformationr|  dot)rY   r!   ZworldMRZelev_radZazim_radp0p1p2psr   VZviewMZprojMM0rA   r`   r`   ra   r     s8    


 zAxes3D.get_projr   c                 C   s*   d| _ t| | _t| | _dS )aa  
        Set the mouse buttons for 3D rotation and zooming.

        Parameters
        ----------
        rotate_btn : int or list of int, default: 1
            The mouse button or buttons to use for 3D rotation of the axes.
        zoom_btn : int or list of int, default: 3
            The mouse button or buttons to use to zoom the 3D axes.
        N)button_pressedr   
atleast_1dtolist_rotate_btn	_zoom_btn)rY   
rotate_btnzoom_btnr`   r`   ra   rC   B  s    zAxes3D.mouse_initc                 C   s   | j g g d dS )z2Disable mouse buttons for 3D rotation and zooming.)r  r  N)rC   re   r`   r`   ra   disable_mouse_rotationT  s    zAxes3D.disable_mouse_rotationc                 C   s   dS )z
        Return whether this axes supports the zoom box button functionality.

        3D axes objects do not use the zoom box button.
        Fr`   re   r`   r`   ra   can_zoomX  s    zAxes3D.can_zoomc                 C   s   dS )z
        Return whether this axes supports the pan/zoom button functionality.

        3D axes objects do not use the pan/zoom button.
        Fr`   re   r`   r`   ra   can_pan`  s    zAxes3D.can_panc                    s   t    | j  | jd urp| jjj| j_| jjj| j_| j \}}| j||dd d | j	| jj
  n0| j	d z| dd W n ty   Y n0 d| _| jtju rtd | _nd| _| td	  d S )
NFr>  linearr   r   Tzaxes.zmarginr#   zaxes3d.grid)r=   clarf   clearr8   majorminorr]  r^  re  rc  r   r   r|  r   r{  r	   r  grid)rY   r2  r3  r^   r`   ra   r  h  s$    


z
Axes3D.clac                 C   sT   |j | krP|j| _|j|j | _| _t| jj	d}|rP|
 d u rP| jj	j  d S Ntoolbar)inaxesbuttonr  xdataydatasxsyr   rD   rE   
_nav_stackr  push_currentrY   r   r  r`   r`   ra   rK     s    
zAxes3D._button_pressc                 C   s*   d | _ t| jjd}|r&| jjj  d S r  )r  r   rD   rE   r  r  r  r`   r`   ra   rL     s    zAxes3D._button_releasec                 C   s   |   |  |  | j| jfS r}   )rD  rT  r]  r   r   re   r`   r`   ra   	_get_view  s    zAxes3D._get_viewc                 C   s.   |\}}}}}| j |||d || _|| _d S )N)r   r   r   )setr   r   )rY   viewr   r   r   r   r   r`   r`   ra   	_set_view  s    zAxes3D._set_viewc              	   C   s@   z|  |W S  ttfy:   | j j}||}| Y S 0 dS )z
        Return *z* string formatted.  This function will use the
        :attr:`fmt_zdata` attribute if it is callable, else will fall
        back on the zaxis major formatter
        N)rB   AttributeErrorr   rf   get_major_formatterformat_data_short)rY   r   funcvalr`   r`   ra   format_zdata  s    zAxes3D.format_zdatac                    s   | j du rdS | j| jv r<d| jdd| jddddS t|   fd	d
d\}}|\}}}|\}}	}
t	|  | }t	|  |	 }|| }|| | || |
  }t
 || j \}}}| |}| |}| |}d|||f S )z
        Given the 2D view coordinates attempt to guess a 3D coordinate.
        Looks for the nearest edge to the point and then assumes that
        the point is at the same z location as the nearest point on the edge.
        N zazimuth=z.0fu   °, elevation=   °-u   −c                    s   t | d | d  fS )Nr   r   )r   Z_line2d_seg_dist)edgexdydr`   ra   r~     s   z%Axes3D.format_coord.<locals>.<lambda>)r   zx=%s, y=%s, z=%s)rA   r  r  r   r   replaceminr   r   hypotr   Zinv_transformformat_xdataformat_ydatar  )rY   r  r  r  r  r-  r0  r2  r.  r1  r3  d0d1dtr   r   r   xsyszsr`   r  ra   format_coord  s,    






zAxes3D.format_coordc                 C   s  | j s
dS | jdu rdS |j|j }}|du r2dS || j || j  }}| j}| j}|| | _| _| j | jv r|dkr|dkrdS t	
| j|| d  | _t	
| j|| d  | _|   d| _| jj  n| j dkr
|dkr|dkrdS |  \}}	}
}}}d|| |  }d|| |  }t| jt| j }}|	| |t| t| |t|   }||
 | t| |t| t|   }|| | t|  }| || |	|  | |
| ||  | || ||  |   | jj  n| j | jv r|  \}}	}
}}}d|| |  }|	| | }||
 | }|| | }| || |	|  | |
| ||  | || ||  |   | jj  dS )z
        Mouse moving.

        By default, button-1 rotates and button-3 zooms; these buttons can be
        modified via `mouse_init`.
        Nr      Tr   r   )r  rA   r  r  r  r  rS   rT   r  r   Z_norm_angler   r   r   rd   rD   rE   rH  r   r   r  r  r  rN  rZ  r_  r  )rY   r   r   r   dxdywhr   r   r   r   r   r   r   r   dxxZdyyZdzzdfdzr`   r`   ra   rJ     sZ    
.0zAxes3D._on_movec                 K   s&   |dur|| j _| j j||fi |S )zI
        Set zlabel.  See doc for `.set_ylabel` for description.
        N)rf   labelpadset_label_text)rY   Zzlabelfontdictr  r]   r`   r`   ra   
set_zlabel  s    zAxes3D.set_zlabelc                 C   s   | j  }| S )z.
        Get the z-label text string.
        )rf   	get_labelget_text)rY   labelr`   r`   ra   
get_zlabel  s    
zAxes3D.get_zlabelc                 C   s   | j S )z)Get whether the 3D axes panels are drawn.)r   re   r`   r`   ra   get_frame_on&  s    zAxes3D.get_frame_onc                 C   s   t || _d| _dS )zs
        Set whether the 3D axes panels are drawn.

        Parameters
        ----------
        b : bool
        TN)r  r   rd   r   r`   r`   ra   set_frame_on*  s    
zAxes3D.set_frame_onz3.5r   visiblec                 K   s   t |rd}|| _d| _dS )z
        Set / unset 3D grid.

        .. note::

            Currently, this function does not behave the same as
            :meth:`matplotlib.axes.Axes.grid`, but it is intended to
            eventually support that behavior.
        TN)r  Z
_draw_gridrd   )rY   r  r]   r`   r`   ra   r  5  s    zAxes3D.gridc                 K   s|   |dv }|dv }|dv }|r2| j  jf i | |rL| j jf i | |rf| j jf i | | j||||d dS )a  
        Convenience method for controlling tick locators.

        See :meth:`matplotlib.axes.Axes.locator_params` for full
        documentation.  Note that this is for Axes3D objects,
        therefore, setting *axis* to 'both' will result in the
        parameters being set for all three axes.  Also, *axis*
        can also take a value of 'z' to apply parameters to the
        z axis.
        r  r  r  r  N)rp   r'  
set_paramsrs   rf   r   )rY   r   r  r]   _x_y_zr`   r`   ra   locator_paramsF  s    
zAxes3D.locator_paramsc                    s   t jg d|d |dv r.t j|fi | |dv rt|}|dd |dd |dd |d	d | jjf i | dS )
a  
        Convenience method for changing the appearance of ticks and
        tick labels.

        See :meth:`matplotlib.axes.Axes.tick_params` for more complete
        documentation.

        The only difference is that setting *axis* to 'both' will
        mean that the settings are applied to all three axes. Also,
        the *axis* parameter also accepts a value of 'z', which
        would mean to apply to only the z-axis.

        Also, because of how Axes3D objects are drawn very differently
        from regular 2D axes, some of these settings may have
        ambiguous meaning.  For simplicity, the 'z' axis will
        accept settings as if it was like the 'y' axis.

        .. note::
           Axes3D currently ignores some of these settings.
        )r   r   r   r  r   )r   r   r  r  rV  NrU  labeltoplabelbottom)r   r   r=   tick_paramsrx  r<   rf   set_tick_params)rY   r   r]   Zzkwr^   r`   ra   r  ]  s    zAxes3D.tick_paramsc                 C   s    |   \}}| j||dd dS )z$
        Invert the z-axis.
        Nri   )r]  r^  rY   rU  rV  r`   r`   ra   invert_zaxis  s    zAxes3D.invert_zaxisc                 C   s   |   \}}||k S )z9
        Returns True if the z-axis is inverted.
        r]  r  r`   r`   ra   zaxis_inverted  s    zAxes3D.zaxis_invertedc                 C   s(   |   \}}||k r||fS ||fS dS )zP
        Return the lower and upper z-axis bounds, in increasing order.
        Nr  r  r`   r`   ra   
get_zbound  s    zAxes3D.get_zboundc                 C   sd   |du rt |r|\}}|  \}}|du r2|}|du r>|}| jt||ft|  ddd dS )z
        Set the lower and upper numerical bounds of the z-axis.

        This method will honor axes inversion regardless of parameter order.
        It will not change the autoscaling setting (`.get_autoscalez_on()`).
        Nr<  ri   )r   r@  r  r^  r   r  r  )rY   lowerupper	old_lower	old_upperr`   r`   ra   r,    s    
zAxes3D.set_zboundc                    s*   t  j|||fi |}t||| |S )z
        Add text to the plot. kwargs will be passed on to Axes.text,
        except for the *zdir* keyword, which sets the direction to be
        used as the z direction.
        )r=   textr   Ztext_2d_to_3d)rY   r   r   r   szdirr]   r  r^   r`   ra   r    s    zAxes3D.textr  c          
         s   |   }|r4t|d ts4|^}}d|v r@tdn|dd}t|t|}t j	||g|R i |}|D ]}	t
j|	||d qrt
||||\}}}| |||| |S )a0  
        Plot 2D or 3D data.

        Parameters
        ----------
        xs : 1D array-like
            x coordinates of vertices.
        ys : 1D array-like
            y coordinates of vertices.
        zs : float or 1D array-like
            z coordinates of vertices; either one for all points or one for
            each point.
        zdir : {'x', 'y', 'z'}, default: 'z'
            When plotting 2D data, the direction to use as z ('x', 'y' or 'z').
        **kwargs
            Other arguments are forwarded to `matplotlib.axes.Axes.plot`.
        r   r  z+plot() for multiple values for argument 'z'r  r  )has_datar   strr   r<   r   broadcast_tor   r=   plotr   line_2d_to_3djuggle_axesr   )
rY   r  r  r  r\   r]   r  r  linesliner^   r`   ra   r    s    
zAxes3D.plotr,   r\   r]   )r{   )r   vminvmaxlightsourcec          "         s:  |   }
|jdkrtdt|}t|||\}}}|j\}}d|	v pPd|	v }d|	v p`d|	v }|rr|rrtd|	dd|	dd|	dd	}|	dd	}t	d
 r|}n| }|rt
tt|| dt
tt|| dd|	v r|	d}n4|	dd}|du r| j }tt|}d}|	dd}|	d|du }|du rftjddd g }|d  dkr|d  dkr|du rtjfdd|||fD dd}nttd|d |d g }ttd|d |d g }g }t|dd |dd D ]\t|dd |dd D ]Z\  fdd|||fD }t|j}|| |dur:||    q:qt|tjrt| r&g }g }t ||D ]F\}}t|t|jdd  }t!|r|| || q|}|dur&|}t"j#|g|R i |	} |durx|rb| $|| %||}| &| | '| n|rt|tjr|d j(dd}!ntdd |D }!| )|! |dus|dur| *|| |dur| +| n*|r| $|| %||}n|}| &| | ,|  | -||||
 | S )a.	  
        Create a surface plot.

        By default it will be colored in shades of a solid color, but it also
        supports colormapping by supplying the *cmap* argument.

        .. note::

           The *rcount* and *ccount* kwargs, which both default to 50,
           determine the maximum number of samples used in each direction.  If
           the input data is larger, it will be downsampled (by slicing) to
           these numbers of points.

        .. note::

           To maximize rendering speed consider setting *rstride* and *cstride*
           to divisors of the number of rows minus 1 and columns minus 1
           respectively. For example, given 51 rows rstride can be any of the
           divisors of 50.

           Similarly, a setting of *rstride* and *cstride* equal to 1 (or
           *rcount* and *ccount* equal the number of rows and columns) can use
           the optimized path.

        Parameters
        ----------
        X, Y, Z : 2D arrays
            Data values.

        rcount, ccount : int
            Maximum number of samples used in each direction.  If the input
            data is larger, it will be downsampled (by slicing) to these
            numbers of points.  Defaults to 50.

        rstride, cstride : int
            Downsampling stride in each direction.  These arguments are
            mutually exclusive with *rcount* and *ccount*.  If only one of
            *rstride* or *cstride* is set, the other defaults to 10.

            'classic' mode uses a default of ``rstride = cstride = 10`` instead
            of the new default of ``rcount = ccount = 50``.

        color : color-like
            Color of the surface patches.

        cmap : Colormap
            Colormap of the surface patches.

        facecolors : array-like of colors.
            Colors of each individual patch.

        norm : Normalize
            Normalization for the colormap.

        vmin, vmax : float
            Bounds for the normalization.

        shade : bool, default: True
            Whether to shade the facecolors.  Shading is always disabled when
            *cmap* is specified.

        lightsource : `~matplotlib.colors.LightSource`
            The lightsource to use when *shade* is True.

        **kwargs
            Other arguments are forwarded to `.Poly3DCollection`.
        r   !Argument Z must be 2-dimensional.rstridecstridercountccount.Cannot specify both stride and count argumentsru  2   _internal.classic_moder   
facecolorscolorNcmapshaderz   zPassing shade=None to Axes3D.plot_surface() is deprecated since matplotlib 3.1 and will change its semantic or raise an error in matplotlib 3.3. Please use shade=False instead.r   r   c                    s   g | ]}t | qS r`   )r   _array_patch_perimetersr   a)r   r  r`   ra   
<listcomp>d  s   z'Axes3D.plot_surface.<locals>.<listcomp>r  r  c              	      s.   g | ]&}t |d   d  f qS )r   )r   _array_perimeterr  )cscs_nextrsrs_nextr`   ra   r  o  s   ).r   c                 S   s    g | ]}|d d df   qS Nr   )mean)r   r  r`   r`   ra   r    r   ).r  ndimr   r   _to_unmasked_float_arrayr   broadcast_arraysr   r<   r	   intr   ceil
_get_linesget_next_colorarraymcolorsto_rgbagetr   rW   stacklistrangezipTappendr   ndarrayisnanany	itertoolszip_longestr  r   Poly3DCollection_shade_colors_generate_normalsset_facecolorsset_edgecolorsr  	set_arrayset_climset_normadd_collectionr   )"rY   r  r  r  r   r  r  r  r\   r]   r  rowscols
has_stride	has_countr  r  Zcompute_stridesZfcolorsr  r  r	  colsetpolysZrow_indsZcol_indsr  Z	new_polysZ
new_colsetpcolZnew_polypolycavg_zr`   )r  r  r   r  r  r  ra   plot_surface  s    G





""










zAxes3D.plot_surfacec           
      C   s:  t |tjr||jd }d|d d| d   }}}|d|ddf |d|ddf  }|d|ddf |d|ddf  }ntt|df}tt|df}t|D ]\}}	t|	}d|d d| d   }}}|	|ddf |	|ddf  ||ddf< |	|ddf |	|ddf  ||ddf< qt||S )a  
        Compute the normals of a list of polygons.

        Normals point towards the viewer for a face with its vertices in
        counterclockwise order, following the right hand rule.

        Uses three points equally spaced around the polygon.
        This normal of course might not make sense for polygons with more than
        three points not lying in a plane, but it's a plausible and fast
        approximation.

        Parameters
        ----------
        polygons : list of (M_i, 3) array-like, or (..., M, 3) array-like
            A sequence of polygons to compute normals for, which can have
            varying numbers of vertices. If the polygons all have the same
            number of vertices and array is passed, then the operation will
            be vectorized.

        Returns
        -------
        normals : (..., 3) array
            A normal vector estimated for the polygon.
        r   r   r   .N)r   r   r&  r   emptyr  	enumeratecross)
rY   polygonsni1i2Zi3v1v2Zpoly_ir  r`   r`   ra   r-    s    
$&,.zAxes3D._generate_normalsc           	         s   |du rt jddd}tjdd, |tjj|ddd	 |j }W d   n1 sT0    Y  t| }| rt 	d
d t 	ddj
 fdd}d|| < t |}|dddf }||ddtjf | }||dddf< nt| }|S )z
        Shade *color* using normal vectors given by *normals*.
        *color* can also be an array of the same length as *normals*.
        N   g-x3@)azdegaltdegignore)invalidr   T)r   keepdimsr  333333?c                    s    | S r}   r`   )r   Zin_normZout_normr`   ra   r     s    z"Axes3D._shade_colors.<locals>.normr   r   )r  LightSourcer   errstater   r   	directionr'  r(  	Normalizeinverseto_rgba_arraynewaxis
asanyarraycopy)	rY   r  normalsr  r	  maskr   alphacolorsr`   rP  ra   r,    s$    "

zAxes3D._shade_colorsc                    s  |   }jdkrtdt \ j\}}d|v pFd|v }	d|v pVd|v }
|	rh|
rhtd|dd}|dd}|dd	}|dd	}td
 r|
r|rtt	t
|| dnd}|rtt	t
|| dnd}nJ|	s0|r
tt	t
|| dnd}|r,tt	t
|| dnd}t tt  |rttd||}|dkr|d |d kr||d g7 }ng }|rttd||}|dkr|d |d kr||d g7 }ng }|dkr|dkrtdjdkrg }g } fdd|D }fdd|D }fdd|D }fdd|D }fdd|D }fdd|D }dd t|||D dd t|||D  }tj|g|R i |}| | |  | |S )a  
        Plot a 3D wireframe.

        .. note::

           The *rcount* and *ccount* kwargs, which both default to 50,
           determine the maximum number of samples used in each direction.  If
           the input data is larger, it will be downsampled (by slicing) to
           these numbers of points.

        Parameters
        ----------
        X, Y, Z : 2D arrays
            Data values.

        rcount, ccount : int
            Maximum number of samples used in each direction.  If the input
            data is larger, it will be downsampled (by slicing) to these
            numbers of points.  Setting a count to zero causes the data to be
            not sampled in the corresponding direction, producing a 3D line
            plot rather than a wireframe plot.  Defaults to 50.

        rstride, cstride : int
            Downsampling stride in each direction.  These arguments are
            mutually exclusive with *rcount* and *ccount*.  If only one of
            *rstride* or *cstride* is set, the other defaults to 1.  Setting a
            stride to zero causes the data to be not sampled in the
            corresponding direction, producing a 3D line plot rather than a
            wireframe plot.

            'classic' mode uses a default of ``rstride = cstride = 1`` instead
            of the new default of ``rcount = ccount = 50``.

        **kwargs
            Other arguments are forwarded to `.Line3DCollection`.
        r   r  r  r   r  r  r  r   r  r  r   r  z*Either rstride or cstride must be non zeroc                    s   g | ]} | qS r`   r`   r   i)r  r`   ra   r  e  r   z)Axes3D.plot_wireframe.<locals>.<listcomp>c                    s   g | ]} | qS r`   r`   r^  )r  r`   ra   r  f  r   c                    s   g | ]} | qS r`   r`   r^  )r  r`   ra   r  g  r   c                    s   g | ]} | qS r`   r`   r^  )tXr`   ra   r  i  r   c                    s   g | ]} | qS r`   r`   r^  )tYr`   ra   r  j  r   c                    s   g | ]} | qS r`   r`   r^  )tZr`   ra   r  k  r   c                 S   s"   g | ]\}}}t t|||qS r`   r!  r#  r   xlylzlr`   r`   ra   r  m  s   c                 S   s"   g | ]\}}}t t|||qS r`   rc  rd  r`   r`   ra   r  o  s   )r  r  r   r   r  r   r<   r	   r  r   r  	transposer!  r"  sizer#  r   Line3DCollectionr3  r   )rY   r  r  r  r\   r]   r  r4  r5  r6  r7  r  r   r  r  ZriiZciixlinesZylinesZzlinesZtxlinesZtylinesZtzlinesr  linecr`   )r  r  r  r`  ra  rb  ra   plot_wireframe  sj    '

 """"


zAxes3D.plot_wireframe)r  r   r  r  r  c                O   s  |   }|du r| j }tt|}|dd}	|d|	du }
t	j
|i |\}}}z|d}W n ty   |^}}Y n0 t|}| }|j| }|j| }|| }tj|||fdd}tj|g|R i |}|	rD|dddddf jdd}|| |dus"|dur.||| |durr|| n.|
rd| |}| |||}n|}|| | | | |j|j|| |S )	aT  
        Plot a triangulated surface.

        The (optional) triangulation can be specified in one of two ways;
        either::

          plot_trisurf(triangulation, ...)

        where triangulation is a `~matplotlib.tri.Triangulation` object, or::

          plot_trisurf(X, Y, ...)
          plot_trisurf(X, Y, triangles, ...)
          plot_trisurf(X, Y, triangles=triangles, ...)

        in which case a Triangulation object will be created.  See
        `.Triangulation` for a explanation of these possibilities.

        The remaining arguments are::

          plot_trisurf(..., Z)

        where *Z* is the array of values to contour, one per point
        in the triangulation.

        Parameters
        ----------
        X, Y, Z : array-like
            Data values as 1D arrays.
        color
            Color of the surface patches.
        cmap
            A colormap for the surface patches.
        norm : Normalize
            An instance of Normalize to map values to colors.
        vmin, vmax : float, default: None
            Minimum and maximum value to map.
        shade : bool, default: True
            Whether to shade the facecolors.  Shading is always disabled when
            *cmap* is specified.
        lightsource : `~matplotlib.colors.LightSource`
            The lightsource to use when *shade* is True.
        **kwargs
            All other arguments are passed on to
            :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`

        Examples
        --------
        .. plot:: gallery/mplot3d/trisurf3d.py
        .. plot:: gallery/mplot3d/trisurf3d_2.py
        Nr  r	  r  r  r  r   r   )r  r  r  r   r  r  r  r  r<   r   get_from_args_and_kwargsKeyErrorr   get_masked_trianglesr   r   r   r   r+  r  r0  r1  r2  r-  r,  r.  r3  r   )rY   r  r   r  r  r  r\   r]   r  r  r	  trir   	trianglesxtytZztvertsr<  r=  rZ  r8  r`   r`   ra   plot_trisurfx  sD    5








zAxes3D.plot_trisurfr   c              	   C   s  |j }|j}|d |d  d }t||D ]V\}}| }|sBq*t||| }	t||| }
| d }g }g }tt|	d | }|dkrt|	d dkr*d}nq*t|	d d |d  }t	t
t|d D ]Z}t
t|| }t
t|d | }||	d | |	d | |
d | |
d | g qt|}| |}| ||}| ||}tj|||d}|| | | q*|D ]}|  qdS )z4
        Extend a contour in 3D by creating
        r   r   r   r  
edgecolorsN)levelscollectionsr#  	get_pathsr   Z_paths_to_3d_segmentsget_edgecolorroundr  r"  r  r%  r   r  r-  r,  r+  set_sort_zposadd_collection3dremove)rY   csetstridery  collsr  r   rl  pathsZtopvertsZbotvertsr  Z	polyvertsrZ  Znstepsstepsizer_  rE  rF  r]  Zcolors2Zpolycolr;  r`   r`   ra   _3d_extend_contour  sL    





zAxes3D._3d_extend_contourc                 C   sR   d| }|r|  || n4t|j|jD ]$\}}|d ur<|}tj|||d q(d S )Nr  r  )r  r#  ry  rz  r   line_collection_2d_to_3d)rY   r  extend3dr  r  offsetr   rl  r`   r`   ra   add_contour_set  s    zAxes3D.add_contour_setc                 C   s   | j |||d d S )Nr  r  )_add_contourf_set)rY   r  r  r  r`   r`   ra   add_contourf_set  s    zAxes3D.add_contourf_setc           	      C   s   d| }|j dd t|j d  }|jr\|j d t|j dd d  }t|d|}|jr|j d t|j dd d  }t||}t||jD ].\}}|dur|}t	j
|||d || q|S )z
        Returns
        -------
        levels : numpy.ndarray
            Levels at which the filled contours are added.
        r  Nr  r   r   r?  r  )ry  r   diff_extend_mininsert_extend_maxr%  r#  rz  r   poly_collection_2d_to_3dr~  )	rY   r  r  r  Z	midpointsZ	min_levelZ	max_levelr   rl  r`   r`   ra   r    s    ""zAxes3D._add_contourf_set)r  r  r  r  c                   sb   |   }
t||||\}}}t j|||g|R i |	}| ||||| | ||||
 |S )aV  
        Create a 3D contour plot.

        Parameters
        ----------
        X, Y, Z : array-like,
            Input data. See `~matplotlib.axes.Axes.contour` for acceptable
            data shapes.
        extend3d : bool, default: False
            Whether to extend contour in 3D.
        stride : int
            Step size for extending contour.
        zdir : {'x', 'y', 'z'}, default: 'z'
            The direction to use.
        offset : float, optional
            If specified, plot a projection of the contour lines at this
            position in a plane normal to zdir.
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER

        *args, **kwargs
            Other arguments are forwarded to `matplotlib.axes.Axes.contour`.

        Returns
        -------
        matplotlib.contour.QuadContourSet
        )r  r   rotate_axesr=   contourr  r   )rY   r  r  r  r  r  r  r  r\   r]   r  jXjYjZr  r^   r`   ra   r  7  s    zAxes3D.contourc                   s   |   }tj|i |\}}}|j}	|j}
d|v r>|d}n|^}}t|	|
||\}}}t|||j|j	}t
 j||g|R i |}| ||||| | |	|
|| |S )a  
        Create a 3D contour plot.

        .. note::
            This method currently produces incorrect output due to a
            longstanding bug in 3D PolyCollection rendering.

        Parameters
        ----------
        X, Y, Z : array-like
            Input data. See `~matplotlib.axes.Axes.tricontour` for acceptable
            data shapes.
        extend3d : bool, default: False
            Whether to extend contour in 3D.
        stride : int
            Step size for extending contour.
        zdir : {'x', 'y', 'z'}, default: 'z'
            The direction to use.
        offset : float, optional
            If specified, plot a projection of the contour lines at this
            position in a plane normal to zdir.
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER
        *args, **kwargs
            Other arguments are forwarded to `matplotlib.axes.Axes.tricontour`.

        Returns
        -------
        matplotlib.tri.tricontour.TriContourSet
        r  )r  r   rn  r   r   r<   r   r  rr  r[  r=   
tricontourr  r   )rY   r  r  r  r  r\   r]   r  rq  r  r  r  r  r  r  r  r^   r`   ra   r  `  s"    !zAxes3D.tricontourc                    s>   d|d|d|||i  fdddD }| j g ||R   d S )Nr   r   r   c                    s(   g | ] }t  | t  | fqS r`   r   nanminnanmax)r   dimZdim_valsr`   ra   r    s   z/Axes3D._auto_scale_contourf.<locals>.<listcomp>r   )r   )rY   r  r  r  r  ry  r  limitsr`   r  ra   _auto_scale_contourf  s
    
zAxes3D._auto_scale_contourfr  c                   sb   |   }t||||\}	}
}t j|	|
|g|R i |}| |||}| |||||| |S )a  
        Create a 3D filled contour plot.

        Parameters
        ----------
        X, Y, Z : array-like
            Input data. See `~matplotlib.axes.Axes.contourf` for acceptable
            data shapes.
        zdir : {'x', 'y', 'z'}, default: 'z'
            The direction to use.
        offset : float, optional
            If specified, plot a projection of the contour lines at this
            position in a plane normal to zdir.
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER
        *args, **kwargs
            Other arguments are forwarded to `matplotlib.axes.Axes.contourf`.

        Returns
        -------
        matplotlib.contour.QuadContourSet
        )r  r   r  r=   contourfr  r  )rY   r  r  r  r  r  r\   r]   r  r  r  r  r  ry  r^   r`   ra   r    s    zAxes3D.contourfc                   s   |   }tj|i |\}}}|j}|j}d|v r>|d}	n|^}	}t|||	|\}
}}t|
||j|j	}t
 j||g|R i |}| |||}| |||	||| |S )as  
        Create a 3D filled contour plot.

        .. note::
            This method currently produces incorrect output due to a
            longstanding bug in 3D PolyCollection rendering.

        Parameters
        ----------
        X, Y, Z : array-like
            Input data. See `~matplotlib.axes.Axes.tricontourf` for acceptable
            data shapes.
        zdir : {'x', 'y', 'z'}, default: 'z'
            The direction to use.
        offset : float, optional
            If specified, plot a projection of the contour lines at this
            position in a plane normal to zdir.
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER
        *args, **kwargs
            Other arguments are forwarded to
            `matplotlib.axes.Axes.tricontourf`.

        Returns
        -------
        matplotlib.tri.tricontour.TriContourSet
        r  )r  r   rn  r   r   r<   r   r  rr  r[  r=   tricontourfr  r  )rY   r  r  r\   r]   r  rq  r  r  r  r  r  r  r  ry  r^   r`   ra   r    s"    zAxes3D.tricontourfr   c                    s   t |}|jrt |nd}t|tju rHtj|||d |	| nRt|tj
u rrtj|||d |	| n(t|tju rtj|||d |	| t |}|S )a  
        Add a 3D collection object to the plot.

        2D collection types are converted to a 3D version by
        modifying the object and adding z coordinate information.

        Supported are:

        - PolyCollection
        - LineCollection
        - PatchCollection
        r   r  )r   r  ri  r  r   r   PolyCollectionr   r  r~  LineCollectionr  PatchCollectionpatch_collection_2d_to_3dr=   r3  )rY   r;  r  r  ZzvalsZzsortval
collectionr^   r`   ra   r    s    

zAxes3D.add_collection3d)	r  r  r  r  rx  c	facecolorr  r  )replace_names   c                    s   |   }
|}tjdd |||fD  \}}}tj|}t|||||\}}}}}t||rh| }t	 j
||g|R ||d|	}tj||||d | jdk r|jdkr| d | ||||
 |S )a  
        Create a scatter plot.

        Parameters
        ----------
        xs, ys : array-like
            The data positions.
        zs : float or array-like, default: 0
            The z-positions. Either an array of the same length as *xs* and
            *ys* or a single value to place all points in the same plane.
        zdir : {'x', 'y', 'z', '-x', '-y', '-z'}, default: 'z'
            The axis direction for the *zs*. This is useful when plotting 2D
            data on a 3D Axes. The data must be passed as *xs*, *ys*. Setting
            *zdir* to 'y' then plots the data to the x-z-plane.

            See also :doc:`/gallery/mplot3d/2dcollections3d`.

        s : float or array-like, default: 20
            The marker size in points**2. Either an array of the same length
            as *xs* and *ys* or a single value to make all markers the same
            size.
        c : color, sequence, or sequence of colors, optional
            The marker color. Possible values:

            - A single color format string.
            - A sequence of colors of length n.
            - A sequence of n numbers to be mapped to colors using *cmap* and
              *norm*.
            - A 2D array in which the rows are RGB or RGBA.

            For more details see the *c* argument of `~.axes.Axes.scatter`.
        depthshade : bool, default: True
            Whether to shade the scatter markers to give the appearance of
            depth. Each call to ``scatter()`` will perform its depthshading
            independently.
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER
        **kwargs
            All other arguments are passed on to `~.axes.Axes.scatter`.

        Returns
        -------
        paths : `~matplotlib.collections.PathCollection`
        c                 S   s"   g | ]}t t j|t jqS r`   )r   r  mafillednan)r   tr`   r`   ra   r  L	  r   z"Axes3D.scatter.<locals>.<listcomp>)r  r  )r  r  
depthshade皙?r   )r  r   r  r  r  r   delete_masked_pointsmay_share_memoryrY  r=   scatterr   r  r  ri  r  r   )rY   r  r  r  r  r  r  r  r\   r]   r  Zzs_origpatchesr^   r`   ra   r  	  s"    2
"

zAxes3D.scatterc                    s   |   }t j||g|R i |}t|t|}g }	g }
t||D ]T\}}t|}|	|	 7 }	|
|gt| 7 }
t
||| d|v rF||d  qFt|	dkrt|	 \}}n
g g  }}t|||
|\}}}
| |||
| |S )a  
        Add 2D bar(s).

        Parameters
        ----------
        left : 1D array-like
            The x coordinates of the left sides of the bars.
        height : 1D array-like
            The height of the bars.
        zs : float or 1D array-like
            Z coordinate of bars; if a single value is specified, it will be
            used for all bars.
        zdir : {'x', 'y', 'z'}, default: 'z'
            When plotting 2D data, the direction to use as z ('x', 'y' or 'z').
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER
        **kwargs
            Other arguments are forwarded to `matplotlib.axes.Axes.bar`.

        Returns
        -------
        mpl_toolkits.mplot3d.art3d.Patch3DCollection
        r\  r   )r  r=   barr   r  r  r#  r   Z_get_patch_vertsr  Zpatch_2d_to_3d	set_alphar  r   )rY   rI  r   r  r  r\   r]   r  r  ru  Zverts_zsr:  r   Zvsr  r  r^   r`   ra   r  b	  s$    

z
Axes3D.baraveragec                 O   s   |   }tt||||||\}}}}}}t|}t|| }t|}t|| }t|}t|| }tg d}t|j|j }d||fd||fd||ffD ]J\}}}|dtj	tj	f }|dtj	tj	f }|||d|f   |d|f< q|
d|jdd  }g }|du r0| j g}tt|}t|t|krn|D ]}||gd  qTn&|}t|t|k r|dt| 9 }|	r| |}| |||
}n|}tj|g|R ||d	|}| | | ||f||f||f| |S )
a  
        Generate a 3D barplot.

        This method creates three dimensional barplot where the width,
        depth, height, and color of the bars can all be uniquely set.

        Parameters
        ----------
        x, y, z : array-like
            The coordinates of the anchor point of the bars.

        dx, dy, dz : float or array-like
            The width, depth, and height of the bars, respectively.

        color : sequence of colors, optional
            The color of the bars can be specified globally or
            individually. This parameter can be:

            - A single color, to color all bars the same color.
            - An array of colors of length N bars, to color each bar
              independently.
            - An array of colors of length 6, to color the faces of the
              bars similarly.
            - An array of colors of length 6 * N bars, to color each face
              independently.

            When coloring the faces of the boxes specifically, this is
            the order of the coloring:

            1. -Z (bottom of box)
            2. +Z (top of box)
            3. -Y
            4. +Y
            5. -X
            6. +X

        zsort : str, optional
            The z-axis sorting scheme passed onto `~.art3d.Poly3DCollection`

        shade : bool, default: True
            When true, this shades the dark sides of the bars (relative
            to the plot's source of light).

        lightsource : `~matplotlib.colors.LightSource`
            The lightsource to use when *shade* is True.

        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER

        **kwargs
            Any additional keyword arguments are passed onto
            `~.art3d.Poly3DCollection`.

        Returns
        -------
        collection : `~.art3d.Poly3DCollection`
            A collection of three dimensional polygons representing
            the bars.
        ))r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )r  r  r  r  )r  r  r  r  )r  r  r  r  )r  r  r  r  r   r   r   .)r  Nr   )zsortr  )r  r   r  r  r  r   r  r@  r   rW  reshape_get_patches_for_fillr  r!  r  rV  r  extendr-  r,  r   r+  r3  r   )rY   r   r   r   r  r  r  r  r  r	  r  r\   r]   r  r   r   r   r   r   r   Zcuboidr9  r_  r:  dpr  r  rZ  Zsfacecolorsr;  r`   r`   ra   bar3d	  sT    ?


.&


zAxes3D.bar3dcenterc                    s<   t  j|f||d|}| j \}}| jd|  |S )N)r  locgq=
ףp?)r=   	set_titletitler   set_y)rY   r  r  r  r]   retr   r   r^   r`   ra   r  >
  s    zAxes3D.set_titlerO  tail)lengtharrow_length_ratiopivot	normalizec                   s  ddd}|   }d}	t||	k r6td|	t|f |d|	 }
dd |
D }tjg |
|R  }|d|	 }
||	d }|rttj|  fd	d|
D }
nd
d |
D }
tdd |
D rt	j
g g||	d R i |}| | |S tjd|gtd}|| }tjg d|d |dkr0||8 }n|dkrF||d 8 }t|
dd }t|
d|	 t}tjj|dd}|dk |  }|r|  |  d }n|  }t|dkr6|tj|| dd}||}|ddddf tj|| }|t|ddf}|dd}g ||}ng }t	j
|g||	d R i |}| | | |dddf |dddf |dddf | |S )a  
        ax.quiver(X, Y, Z, U, V, W, /, length=1, arrow_length_ratio=.3, pivot='tail', normalize=False, **kwargs)

        Plot a 3D field of arrows.

        The arguments could be array-like or scalars, so long as they
        they can be broadcast together. The arguments can also be
        masked arrays. If an element in any of argument is masked, then
        that corresponding quiver element will not be plotted.

        Parameters
        ----------
        X, Y, Z : array-like
            The x, y and z coordinates of the arrow locations (default is
            tail of arrow; see *pivot* kwarg).

        U, V, W : array-like
            The x, y and z components of the arrow vectors.

        length : float, default: 1
            The length of each quiver.

        arrow_length_ratio : float, default: 0.3
            The ratio of the arrow head with respect to the quiver.

        pivot : {'tail', 'middle', 'tip'}, default: 'tail'
            The part of the arrow that is at the grid point; the arrow
            rotates about this point, hence the name *pivot*.

        normalize : bool, default: False
            Whether all arrows are normalized to have the same length, or keep
            the lengths defined by *u*, *v*, and *w*.

        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER

        **kwargs
            Any additional keyword arguments are delegated to
            :class:`~matplotlib.collections.LineCollection`
           c              
   S   sd  | d d df }| d d df }t jj| d d d df dd}t j|||dkt |d}t j| ||dkt |d}t|}t|}t	|}	t 
||d d|   || d|  ||	 g|| d|  ||d d|   | |	 g| |	 ||	 t ||gg}
|
 }|g dg df  d9  < t d	|
| }t d	|| }t j||gdd}|S )
Nr   r   r   r  )whereout)r   r   r   r   )r   r   r   r   r  zij...,...j->...i)r   r   r   divide
zeros_like	ones_likemathradiansr  r  r  	full_likerY  einsumr   )UVWangler   r   r   Zx_pZy_pZrar  r  ZRposZRnegZ	Rpos_vecsZ	Rneg_vecs	head_dirsr`   r`   ra   calc_arrowss
  s(     


(*z"Axes3D.quiver.<locals>.calc_arrowsr   z-Wrong number of arguments. Expected %d got %dNc                 S   s    g | ]}t |tjjr|jqS r`   )r   r   r  MaskedArrayr[  r   kr`   r`   ra   r  
  s   z!Axes3D.quiver.<locals>.<listcomp>c                    s    g | ]}t jj| d  qS )r[  )r   r  r  
compressedr  r  r`   ra   r  
  s   c                 S   s   g | ]}t |qS r`   )r   r  r  r`   r`   ra   r  
  r   c                 s   s   | ]}t |d kV  qdS )r   N)r  )r   vr`   r`   ra   r   
  r   z Axes3D.quiver.<locals>.<genexpr>r#   r   )r  middletip)r  r  r  r   r   r   r  r   )r  r   r  )r  )r  r  r   r   r  r   reduce
logical_orr(  r   rj  r3  r  r   r   r   r  astyper   r   r  multiplyouterswapaxesr   )rY   r  r  r  r  r\   r]   r  r  Zargi
input_argsmasksbcastrl  Zshaft_dtZarrow_dtZXYZr  r   Zshaftsr  headsr  r`   r  ra   quiverE
  sb    .


 



" 
4zAxes3D.quiver)r  rx  r	  r  c          2   	      s  t |dkrdd }ndd }||i |\}}jdkrDtdtjjtjd}	t|	d  |du r|t \}
}}n fd	d
|D \}
}}fdd}|du r| j	
 }||d}||d}| |
|| tjg dg dg dg dgtjd}tt}dd }|dD ]}|j|	\}}}t|}t|}t|}||j}|ddd }|D ]4}|D ]&}|||dg}t|}| r|| ||  t|dd |dd D ]\}}||||g} ||||g}!t| }"t|!}#|" r&|# s&||" |!|  n&|" sƈ|# r||# |!|  q||||d g}$||||g}%t|$}&|& rr||& |%|  qrqhqi }'| D ]\}(})|du r|)}*ng }*|)D ]}+|+dddf |+dddf |+dddf f},t|+j}-|
|, |-dddf< ||, |-dddf< ||, |-dddf< |*|- q||( }.||( }/|r| |*}0| |.|0|}.|/dur| |/|0|}/tj|*f|.|/d|}1| |1 |1|'|(< q|'S )a
  
        ax.voxels([x, y, z,] /, filled, facecolors=None, edgecolors=None, **kwargs)

        Plot a set of filled voxels

        All voxels are plotted as 1x1x1 cubes on the axis, with
        ``filled[0, 0, 0]`` placed with its lower corner at the origin.
        Occluded faces are not plotted.

        Parameters
        ----------
        filled : 3D np.array of bool
            A 3D array of values, with truthy values indicating which voxels
            to fill

        x, y, z : 3D np.array, optional
            The coordinates of the corners of the voxels. This should broadcast
            to a shape one larger in every dimension than the shape of
            *filled*.  These can be used to plot non-cubic voxels.

            If not specified, defaults to increasing integers along each axis,
            like those returned by :func:`~numpy.indices`.
            As indicated by the ``/`` in the function signature, these
            arguments can only be passed positionally.

        facecolors, edgecolors : array-like, optional
            The color to draw the faces and edges of the voxels. Can only be
            passed as keyword arguments.
            These parameters can be:

            - A single color value, to color all voxels the same color. This
              can be either a string, or a 1D rgb/rgba array
            - ``None``, the default, to use a single color for the faces, and
              the style default for the edges.
            - A 3D ndarray of color names, with each item the color for the
              corresponding voxel. The size must match the voxels.
            - A 4D ndarray of rgb/rgba data, with the components along the
              last axis.

        shade : bool, default: True
            Whether to shade the facecolors.  Shading is always disabled when
            *cmap* is specified.

        lightsource : `~matplotlib.colors.LightSource`
            The lightsource to use when *shade* is True.

        **kwargs
            Additional keyword arguments to pass onto
            `~mpl_toolkits.mplot3d.art3d.Poly3DCollection`.

        Returns
        -------
        faces : dict
            A dictionary indexed by coordinate, where ``faces[i, j, k]`` is a
            `.Poly3DCollection` of the faces drawn for the voxel
            ``filled[i, j, k]``. If no faces were drawn for a given voxel,
            either because it was not asked to be drawn, or it is fully
            occluded, then ``(i, j, k) not in faces``.

        Examples
        --------
        .. plot:: gallery/mplot3d/voxels.py
        .. plot:: gallery/mplot3d/voxels_rgb.py
        .. plot:: gallery/mplot3d/voxels_torus.py
        .. plot:: gallery/mplot3d/voxels_numpy_logo.py
        r   c                 [   s   | ||f||fS r}   r`   )Z
_Axes3D__xZ
_Axes3D__yZ
_Axes3D__zr  r]   r`   r`   ra   voxels(  s    zAxes3D.voxels.<locals>.voxelsc                 [   s
   d | |fS r}   r`   )r  r]   r`   r`   ra   r  +  s    z%Argument filled must be 3-dimensionalr   r   Nc                 3   s   | ]}t | V  qd S r}   )r   r  )r   r  )coord_shaper`   ra   r   :  r   z Axes3D.voxels.<locals>.<genexpr>c                    sp   t | dv r&t |  jt |  S t | dv r^t | d d  jkrZtd|| S td|d S )N)r   r   )r   r   r   z8When multidimensional, {} must match the shape of filledzInvalid {} argument)r   r  r  r   r   format)r  r   )r  r`   ra   _broadcast_color_arg<  s    z+Axes3D.voxels.<locals>._broadcast_color_argr  rx  r  r  r  r  c                 s   s8   t j| t jd}t| D ]}|V  t j|ddd}qdS )z%Generate cyclic permutation matrices.r   r   r   r  N)r   r   intpr"  r}  )rD  matr_  r`   r`   ra   permutation_matrices_  s    z+Axes3D.voxels.<locals>.permutation_matricesr  r   r   rw  )r  r  r   r   r  r   r  r`  indicesr  r  r   r   r!  r$  r  aranger%  r#  itemsr@  r-  r,  r   r+  r  )2rY   r  rx  r	  r  r\   r]   r  Zxyzri  r   r   r   r  squareZvoxel_facesr  ZpermutepcZqcrcZpindsZqindsZrindsZsquare_rot_posZsquare_rot_negr:  qr  i0Zr1r2r  r  rE  rF  ZpkZpk2ZikrC  coordZ
faces_indsZfacesZ	face_indsindfacer  	edgecolorrZ  polyr`   )r  r  ra   r  
  s    H




	





"

.


zAxes3D.voxels)r   r   r   xerryerrzerrr  c           C   
      sV  |   }t|tj}dd | D }|dd | jd|fd|fd|fg|dd	 t	|rd|n|g}t	|rx|n|g}t	|r|n|g}t
|t
|  krt
|ksn td
t|	trd|	f}	t|	tr0t
|	dkrt|	d trt|	d trt|	d d|	d }	ntd|	dnt|	tr>ntt|	tst	|	rz||	  W n< ttfy  ztd|	dW Y dn
d0 0 ntd|	d|dd}d|d< | jj|dkr||fn|||f|dd\\}}tj||d |r||d d  n||d d  | dkrJ| | nd}|d d|vrjd|d< |
du r||d }
dD ]}||d qi |d|
i}|r||d< nd|v r|d |d< dD ]}||v r|| ||< qi |dd i}|du rtd! }|dkr$d"| |d#< |dur6||d$< |
|d< tt
|td|	< d%d& }fd'd( g g g   }}}g } d)d)d*d+}!dddd,|d#td- d }"|"| jjd. 9 }"| j ! "d/|"|"fg}"t#tj$|"dd0}"tj%| ddd1  tj&'| ( }#W d   n1 s0    Y  t)|#t*|"dddgd }"|"d29 }"i ||"dd3}$|$d#d t+g d,|||g|||g|||g|||gD ]\}%}&t,|%|% }'du rȐqt	sgt
|& t-t.t
|&/tt.t
|&/t fd4d5t0|||gD }(|(\\})}*\}+},\}-}.B  }/|/1 r|dkr||)|+|-g|/@ }0||*|,|.g|/@ }1tj2|0d|!|' d6|}2tj2|1d|!|' d6|}3| |2 | |3 |3|2 |3|3 1 r4||*|,|.g@ \}4}5}6| j4|4|5|6gR i |$ 1 rv||)|+|-g@ \}7}8}9| j4|7|8|9g R i |$ tj5t*|(j6fi |}:| 7|: |3|: | 3|( qt*| } fd7d8};|;| d\}<}=|;| d\}>}?|;| d\}@}A| 8|<|=f|>|?f|@|Af| t9j:|t|t|f|dup2|du|du|d9}B| j;3|B |||fS ):a  
        Plot lines and/or markers with errorbars around them.

        *x*/*y*/*z* define the data locations, and *xerr*/*yerr*/*zerr* define
        the errorbar sizes. By default, this draws the data markers/lines as
        well the errorbars. Use fmt='none' to draw errorbars only.

        Parameters
        ----------
        x, y, z : float or array-like
            The data positions.

        xerr, yerr, zerr : float or array-like, shape (N,) or (2, N), optional
            The errorbar sizes:

            - scalar: Symmetric +/- values for all data points.
            - shape(N,): Symmetric +/-values for each data point.
            - shape(2, N): Separate - and + values for each bar. First row
              contains the lower errors, the second row contains the upper
              errors.
            - *None*: No errorbar.

            Note that all error arrays should have *positive* values.

        fmt : str, default: ''
            The format for the data points / data lines. See `.plot` for
            details.

            Use 'none' (case insensitive) to plot errorbars without any data
            markers.

        ecolor : color, default: None
            The color of the errorbar lines.  If None, use the color of the
            line connecting the markers.

        elinewidth : float, default: None
            The linewidth of the errorbar lines. If None, the linewidth of
            the current style is used.

        capsize : float, default: :rc:`errorbar.capsize`
            The length of the error bar caps in points.

        capthick : float, default: None
            An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*).
            This setting is a more sensible name for the property that
            controls the thickness of the error bar cap in points. For
            backwards compatibility, if *mew* or *markeredgewidth* are given,
            then they will over-ride *capthick*. This may change in future
            releases.

        barsabove : bool, default: False
            If True, will plot the errorbars above the plot
            symbols. Default is below.

        xlolims, ylolims, zlolims : bool, default: False
            These arguments can be used to indicate that a value gives only
            lower limits. In that case a caret symbol is used to indicate
            this. *lims*-arguments may be scalars, or array-likes of the same
            length as the errors. To use limits with inverted axes,
            `~.Axes.set_xlim` or `~.Axes.set_ylim` must be called before
            :meth:`errorbar`. Note the tricky parameter names: setting e.g.
            *ylolims* to True means that the y-value is a *lower* limit of the
            True value, so, only an *upward*-pointing arrow will be drawn!

        xuplims, yuplims, zuplims : bool, default: False
            Same as above, but for controlling the upper limits.

        errorevery : int or (int, int), default: 1
            draws error bars on a subset of the data. *errorevery* =N draws
            error bars on the points (x[::N], y[::N], z[::N]).
            *errorevery* =(start, N) draws error bars on the points
            (x[start::N], y[start::N], z[start::N]). e.g. errorevery=(6, 3)
            adds error bars to the data at (x[6], x[9], x[12], x[15], ...).
            Used to avoid overlapping error bars when two series share x-axis
            values.

        Returns
        -------
        errlines : list
            List of `~mpl_toolkits.mplot3d.art3d.Line3DCollection` instances
            each containing an errorbar line.
        caplines : list
            List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each
            containing a capline object.
        limmarks : list
            List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each
            containing a marker with an upper or lower limit.

        Other Parameters
        ----------------
        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER

        **kwargs
            All other keyword arguments for styling errorbar lines are passed
            `~mpl_toolkits.mplot3d.art3d.Line3DCollection`.

        Examples
        --------
        .. plot:: gallery/mplot3d/errorbar3d.py
        c                 S   s   i | ]\}}|d ur||qS r}   r`   )r   r  r  r`   r`   ra   r   %  r   z#Axes3D.errorbar.<locals>.<dictcomp>r   r   r   r   r   Fr9  z)'x', 'y', and 'z' must have the same sizer   r   Nzerrorevery=z! is a not a tuple of two integerszL is iterable but not a valid NumPy fancy index to match 'xerr'/'yerr'/'zerr'z is not a recognized valuer  
_nolegend_r  T)return_kwargs)r  g?noner  C0)marker
markersizemarkerfacecolormarkeredgewidthmarkeredgecolor	markevery	linestyle	fillstyle	drawstyledash_capstyledash_joinstylesolid_capstylesolid_joinstyle	linewidth)rR   r\  r   
rasterizedr  Nonezerrorbar.capsizeg       @r  r  c                    s    fdd| D S )Nc                    s   g | ]}g t | qS r`   )r)  compress)r   r  r  r`   ra   r    r   z8Axes3D.errorbar.<locals>._apply_mask.<locals>.<listcomp>r`   )arraysr[  r`   r  ra   _apply_mask  s    z$Axes3D.errorbar.<locals>._apply_maskc                    sZ   t | jdkr| \}}n
| |  }}t|  B ||| }t|  B ||| }||fS r  )r  r   r   r  )errdataZlomaskZhimaskZlow_errZhigh_errZlowsZhighs)	everymaskr`   ra   _extract_errs  s    

z&Axes3D.errorbar.<locals>._extract_errs|_)r   r   r   r   zlines.markersizeH   r+   r  )r   r   gV&,t=?)r  r  c                    s&   g | ]\}} |  |qS r`   r`   )r   r_  r  )r$  
dir_vectorr!  lolimsuplimsr`   ra   r    s   z#Axes3D.errorbar.<locals>.<listcomp>)lsr  c              	      sL   t | d d  | d d d d f t | d d  | d d d d f fS r}   r  )Zerr_arrZcoord_label)i_xyzr`   ra   _digout_minmax  s    $$z'Axes3D.errorbar.<locals>._digout_minmax)has_xerrhas_yerrr  )<r  r   normalize_kwargsr$  r%  r  
setdefaultrA  r   r@  r  r   r   r   r`  slicer  
IndexErrorr<   r  
_plot_argsr   r  
set_zorderr  add_liner	   r  r  r  rD   dpi	transAxesrQ   rR   r  r  r   r   invr   r  r  r#  Zget_dir_vectorr  r  r  rA  r(  ZLine3Dr%  r  rj  r$  r3  r   
mcontainerErrorbarContainer
containers)CrY   r   r   r   r	  r  r  fmt	barsabove
erroreveryecolor
elinewidthcapsizecapthickxlolimsxuplimsZylolimsZyuplimsZzlolimsZzuplimsr]   r  r  	data_line
base_styler   eb_lines_styleeb_cap_styler   ZerrlinescaplinesZlimmarksZ	coorderrsZ	capmarkerZ
quiversizeZinvMZeb_quiver_styler  r"  Zi_zdirZcoorderrre  xhrf  Zyhrg  zhnolimsZlo_caps_xyzZhi_caps_xyzcap_locap_hiZxh0Zyh0Zzh0Zxl0Zyl0Zzl0Zerrliner-  r   r   r   r   r   r   errorbar_containerr`   )r$  r(  r!  r#  r,  r)  r*  ra   errorbar  s@   k"













0












zAxes3D.errorbarfor_layout_onlyc          	   	      s   t  j||||d}|g}| jrt|  D ]J}| rdz|j||d}W n tyb   ||}Y n0 |r(|| q(tj	|S )N)call_axes_locatorbbox_extra_artistsrS  rR  )
r=   get_tightbboxrc   r   get_visibler   r%  r   r   union)	rY   r   rT  rU  rS  r  batchr   Zaxis_bbr^   r`   ra   rV    s&    
zAxes3D.get_tightbboxzC0-C0ozC3-)linefmt	markerfmtbasefmtrU  r  orientationc                   s  ddl m}
 |  }tjg d|	d t|t|f}t|t|f}t|t|f}|	dkr|| }}|| }} fddt|||D }nf|	dkr|| }}|| }} fd	dt|||D }n.|| }}|| }} fd
dt|||D }t	|\}}}|du r t
d }| j||| |	dd\}tj|||dd}| | | j||||dd\}|
|||f|d}| | t||  g|	\}}}| g ||g ||g ||| |S )a  
        Create a 3D stem plot.

        A stem plot draws lines perpendicular to a baseline, and places markers
        at the heads. By default, the baseline is defined by *x* and *y*, and
        stems are drawn vertically from *bottom* to *z*.

        Parameters
        ----------
        x, y, z : array-like
            The positions of the heads of the stems. The stems are drawn along
            the *orientation*-direction from the baseline at *bottom* (in the
            *orientation*-coordinate) to the heads. By default, the *x* and *y*
            positions are used for the baseline and *z* for the head position,
            but this can be changed by *orientation*.

        linefmt : str, default: 'C0-'
            A string defining the properties of the vertical lines. Usually,
            this will be a color or a color and a linestyle:

            =========  =============
            Character  Line Style
            =========  =============
            ``'-'``    solid line
            ``'--'``   dashed line
            ``'-.'``   dash-dot line
            ``':'``    dotted line
            =========  =============

            Note: While it is technically possible to specify valid formats
            other than color or color and linestyle (e.g. 'rx' or '-.'), this
            is beyond the intention of the method and will most likely not
            result in a reasonable plot.

        markerfmt : str, default: 'C0o'
            A string defining the properties of the markers at the stem heads.

        basefmt : str, default: 'C3-'
            A format string defining the properties of the baseline.

        bottom : float, default: 0
            The position of the baseline, in *orientation*-coordinates.

        label : str, default: None
            The label to use for the stems in legends.

        orientation : {'x', 'y', 'z'}, default: 'z'
            The direction along which stems are drawn.

        data : indexable object, optional
            DATA_PARAMETER_PLACEHOLDER

        Returns
        -------
        `.StemContainer`
            The container may be treated like a tuple
            (*markerline*, *stemlines*, *baseline*)

        Examples
        --------
        .. plot:: gallery/mplot3d/stem3d_demo.py
        r   )StemContainerr   )r^  r   c                    s&   g | ]\}}} ||f|||fgqS r`   r`   r   thisxthisyZthiszrU  r`   ra   r  ~  s   zAxes3D.stem.<locals>.<listcomp>r   c                    s&   g | ]\}}}| |f|||fgqS r`   r`   r`  rc  r`   ra   r    s   c                    s&   g | ]\}}}|| f|||fgqS r`   r`   r`  rc  r`   ra   r    s   Nzlines.linestyler
  )r  r  r  )
linestylesr]  r  )r  )matplotlib.containerr_  r  r   r   r   r  r   r#  r   r	   r  r   rj  r3  add_containerr  r   )rY   r   r   r   r[  r\  r]  rU  r  r^  r_  r  r   r   r   basexZbasexlimbaseyZbaseylimr  r  
linemarker	linecolorbaseline	stemlines
markerlinestem_containerZjxZjyZjzr`   rc  ra   stem-  sV    B
















(zAxes3D.stem)N)N)NN)NN)NNF)N)N)Tr  N)NN)NTTT)NNTF)NNTF)NNTF)NNr   )r   r   )NN)T)r  N)r  )NN)N)N)r   )Fr   r   N)r   N)r   N)r   r   )r   r   r  NT)r   r   )Nr  TN)Nr  )NNNr  Fr   NNNNFFFFFF)TN)__name__
__module____qualname____doc__r   _axis_namesr   Grouperr   r9   r>   r?   r@   rh   rM   ru   rw   r
   Zget_zgridlinesZget_zticklinesr   r   r   Zw_xaxisZw_yaxisZw_zaxisr   r   r   r   r   r   martistallow_rasterizationr   r   r   r   r   r   r   r   r   r  r  r  r  r   r  r   rN  rZ  r_  r4  maxesrD  r5  rT  r6  rd  ri  rj  rk  mapr  Z
get_zticksZ
set_zticksZget_zmajorticklabelsZget_zminorticklabelsZget_zticklabelsZset_zticklabelsZ
zaxis_datetextwrapdedentrt  r7   r1   r  r   rC   r  r  r  r  rK   rL   r  r  r  r  rJ   r  r  r  r  rename_parameterr  r  r  r  r  r  r,  r  Ztext3DZtext2Dr  Zplot3Ddelete_parameterr>  r-  r,  rm  rv  r  r  r  r  r   r  Z	contour3Dr  r  r  Z
contourf3Dr  r  r  Z	scatter3Dr  r  r  r  Zquiver3Dr  rQ  rV  ro  Zstem3D__classcell__r`   r`   r^   ra   r   ,   sx  q




=*a		B 
>9::






$6$G	"

) O+$
ve4
&5
 1!G5  &  Y     b tr   r  c                 C   s   t dd|  }}t ||\}}t |d |d   d dt j  }t |d d d |d d d   d dt j d d  }|| }|d }|d }|d }|||fS )	z,Return a tuple X, Y, Z with a test data set.g      g      @r   r   g      ?r  ru  i  )r   r  meshgridexpr  )r/  r   r   r  r  ZZ1ZZ2r  r`   r`   ra   get_test_data  s    &*r  )r  )>rs  rz  r   r   r   r)  r  numbersr   rz  numpyr   
matplotlibr   r   r   r   matplotlib.artistr   rv  matplotlib.axesaxesrx  matplotlib.collectionsr   matplotlib.colorsr]  r  matplotlib.imageimager"  matplotlib.linesr  r$  matplotlib.patchesr  r   matplotlib.scalescalera  re  	containerr:  matplotlib.transforms
transformsr   r   r	   matplotlib.axes._baser
   r   r   Zmatplotlib.tri.triangulationr   r  r   r   r   interpd_define_aliasesr   r  r`   r`   r`   ra   <module>   sv                              