B
    ]t\R                 @   sn   d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z
 d dlmZ d dlmZ G dd dejZdS )    N)	docstringrcParams)allow_rasterizationc                   s  e Zd ZdZdd Zej fddZdd Zdd	 Z	d
d Z
dd Zdd Zdd Z fddZd9 fdd	Zdd Zdd Zdd Zdd Zdd  Zd!d" Ze fd#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zed1d2 Zed3d4 Z ed5d6 Z!d7d8 Z"  Z#S ):Spinea  an axis spine -- the line noting the data area boundaries

    Spines are the lines connecting the axis tick marks and noting the
    boundaries of the data area. They can be placed at arbitrary
    positions. See function:`~matplotlib.spines.Spine.set_position`
    for more information.

    The default position is ``('outward',0)``.

    Spines are subclasses of class:`~matplotlib.patches.Patch`, and
    inherit much of their behavior.

    Spines draw a line, a circle, or an arc depending if
    function:`~matplotlib.spines.Spine.set_patch_line`,
    function:`~matplotlib.spines.Spine.set_patch_circle`, or
    function:`~matplotlib.spines.Spine.set_patch_arc` has been called.
    Line-like is the default.

    c             C   s   dS )Nr    )selfr   r   0lib/python3.7/site-packages/matplotlib/spines.py__str__!   s    zSpine.__str__c                s   t  jf | || _| | jj || _| d | td  | 	td  | 
d d| _| d | | jj d| _d| _d| _t|tjjstd|| _d	| _t | _dS )
z
        - *axes* : the Axes instance containing the spine
        - *spine_type* : a string specifying the spine type
        - *path* : the path instance used to draw the spine

        Valid kwargs are:
        %(Patch)s
        Znonezaxes.edgecolorzaxes.linewidthZ
projectingNg      @Fz4'path' must be an instance of 'matplotlib.path.Path'line)super__init__axesZ
set_figurefigure
spine_typeZset_facecolorset_edgecolorr   Zset_linewidthZset_capstyleaxisZ
set_zorderset_transform	transData_bounds_smart_bounds	_position
isinstance
matplotlibpathPath
ValueError_path_patch_typemtransformsIdentityTransform_patch_transform)r   r   r   r   kwargs)	__class__r   r   r   $   s(    



zSpine.__init__c             C   sB   || _ | jdkr | jj| n| jdkr8| jj| d| _dS )z6set the spine and associated axis to have smart bounds)leftright)topbottomTN)r   r   r   Zyaxisset_smart_boundsZxaxisstale)r   valuer   r   r   r'   S   s    

zSpine.set_smart_boundsc             C   s   | j S )z&get whether the spine has smart bounds)r   )r   r   r   r   get_smart_bounds^   s    zSpine.get_smart_boundsc             C   sT   d| _ || _|d | _|d | _|| _|| _tj||| _	| 
| jj d| _dS )zset the spine to be arc-likearc   TN)r   _center_width_heightZ_theta1Z_theta2mpathr   r+   r   r   r   	transAxesr(   )r   centerradiustheta1theta2r   r   r   set_patch_arcb   s    

zSpine.set_patch_arcc             C   s8   d| _ || _|d | _|d | _| | jj d| _dS )zset the spine to be circularcircler,   TN)r   r-   r.   r/   r   r   r1   r(   )r   r2   r3   r   r   r   set_patch_circleo   s    

zSpine.set_patch_circlec             C   s   d| _ d| _dS )zset the spine to be linearr
   TN)r   r(   )r   r   r   r   set_patch_liney   s    zSpine.set_patch_linec             C   sj   | j dkst| | jd | | jd f}| | j}| | j}t 	|d |d j
| | _dS )a  NOTE: This cannot be called until after this has been added
                 to an Axes, otherwise unit conversion will fail. This
                 makes it very important to call the accessor method and
                 not directly access the transformation member variable.
        )r+   r7   r      g      ?N)r   AssertionErrorZconvert_xunitsr-   Zconvert_yunitsr.   r/   r   Affine2DZscale	translater    )r   r2   widthZheightr   r   r   _recompute_transform   s    zSpine._recompute_transformc                s&   | j dkr|   | jS t  S d S )N)r+   r7   )r   r?   r    r   get_patch_transform)r   )r"   r   r   r@      s    
zSpine.get_patch_transformNc                s   |    t j|dS )N)renderer)_adjust_locationr   get_window_extent)r   rA   )r"   r   r   rC      s    zSpine.get_window_extentc             C   s   | j S )N)r   )r   r   r   r   get_path   s    zSpine.get_pathc             C   s    | j d krd| _ | | j  d S )N)outwardg        )r   set_position)r   r   r   r   _ensure_position_is_set   s    
zSpine._ensure_position_is_setc             C   s$   || _ | j dk	r| j   d| _dS )zregister an axis

        An axis should be registered with its corresponding spine from
        the Axes instance. This allows the spine to clear any axis
        properties when needed.
        NT)r   clar(   )r   r   r   r   r   register_axis   s    

zSpine.register_axisc             C   s   d| _ | jdk	r| j  dS )zClear the current spineN)r   r   rH   )r   r   r   r   rH      s    
z	Spine.clac             C   sj   |    | j}t|tr2|dkr&d}n|dkr2d}t|dkrFtd|\}}|dkrb|dkrbd	S d
S dS )zreturn True if directly on axes frame

        This is useful for determining if a spine is the edge of an
        old style MPL plot. If so, this function will return True.
        r2   )r   g      ?zero)datar   r,   zposition should be 2-tuplerE   r   TFN)rG   r   r   strlenr   )r   positionposition_typeamountr   r   r   is_frame_like   s    
zSpine.is_frame_likec             C   s  | j dkrdS | jdkrh| j dkr4| jjj\}}n(| j dkrN| jjj\}}ntd| j  | jrrt||g\}}| j dkr| jj	j\}}| j
 }n"| j dkr| jj	j\}}| j }t|}t||g\}}||k r|}n:||k||k@ }|| }	t|	r|	d }n|}t||}||kr,|}n:||k||k@ }|| }	t|	rX|	d }n|}t||}n
| j\}}| jdkr| j d	kry| j }
W n tk
r   d
}
Y nX y| j }W n tk
r   d}Y nX ||
 | }||
 | }||kr
|| }}tjt|t|| _| j dkr| jjj\}}y| j }W n tk
rh   |}Y nX || ||  }|| _|| _ntd| j  nf| jj}|jdkstd| j dkr||d< ||d< n,| j d	kr||d< ||d< ntd| j  dS )z3automatically set spine bounds to the view intervalr7   N)r#   r$   )r%   r&   zunknown spine spine_type: %sr   r+   )r&   r%   r:   r&   z#unable to set bounds for spine "%s")r,   r,   zunexpected vertices shape)r   r:   )r:   r:   )r   r   )r:   r   ) r   r   r   ZviewLimZ	intervalyZ	intervalxr   r   sortedZdataLimZ
get_yticksZ
get_xticksnpsortrM   maxminr   Zget_theta_directionAttributeErrorZget_theta_offsetr0   r   r+   Zrad2degr   Zget_roriginr/   r.   Zverticesshaper;   )r   lowhighZviewlim_lowZviewlim_highZdatalim_lowZdatalim_highZticksZcondZtickvals	directionoffsetZrminZrmaxZroriginZscaled_diameterZv1r   r   r   rB      s    





















zSpine._adjust_locationc                s   |    t |}d| _|S )NF)rB   r   drawr(   )r   rA   Zret)r"   r   r   r^   7  s    z
Spine.drawc          	   C   s  |    | j}t|tr2|dkr&d}n|dkr2d}t|dksFtd|\}}|dksZt|dkr|d	krzd
t f| _nv| j	dkrddddd| j	 }||d	  d }||d  d }dt
||| jjf| _ntd| j	  d
t f| _n|dkrr| j	dkr(dtjd	d	d	d|d	f| _nH| j	dkrRdtjdd	d	d	d	|f| _ntd| j	  d
t f| _n|dkr| j	dkr|d8 }| j	dkrdt |d	f| _nB| j	dkrdt d	|f| _ntd| j	  d
t f| _dS )z5calculate the offset transform performed by the spiner2   )r   g      ?rJ   )rK   r   r,   zposition should be 2-tuple)r   rE   rK   rE   r   identity)r#   r$   r%   r&   )rR   r   )r:   r   )r   rR   )r   r:   )r#   r$   r&   r%   g      R@r:   postz2unknown spine type "%s": no spine offset performedr   )r#   r$   pre)r&   r%   rK   )r$   r%   N)rG   r   r   rL   rM   r;   r   r   _spine_transformr   ZScaledTranslationr   Zdpi_scale_transwarningswarnr<   Zfrom_valuesr=   )r   rN   rO   rP   Z
offset_vecZoffset_xZoffset_yr   r   r   _calc_offset_transform>  sv    






zSpine._calc_offset_transformc             C   sl   |dkr
n(t |dkrtd|d dkr2td|| _|   | |   | jdk	rb| j  d| _dS )	ap  set the position of the spine

        Spine position is specified by a 2 tuple of (position type,
        amount). The position types are:

        * 'outward' : place the spine out from the data area by the
          specified number of points. (Negative values specify placing the
          spine inward.)

        * 'axes' : place the spine at the specified Axes coordinate (from
          0.0-1.0).

        * 'data' : place the spine at the specified data coordinate.

        Additionally, shorthand notations define a special positions:

        * 'center' -> ('axes',0.5)
        * 'zero' -> ('data', 0.0)

        )r2   rJ   r,   z&position should be 'center' or 2-tupler   )rE   r   rK   z:position[0] should be one of 'outward', 'axes', or 'data' NT)	rM   r   r   re   r   get_spine_transformr   Zreset_ticksr(   )r   rN   r   r   r   rF     s    

zSpine.set_positionc             C   s   |    | jS )zget the spine position)rG   r   )r   r   r   r   get_position  s    zSpine.get_positionc             C   s   |    | j\}}|dkr| jj|| jj | jj  }| jdkrRt|| jj	}n*| jdkrnt| jj	|}nt
d| j |S | jdkr| jjdd}n(| jdkr| jjdd}nt
d| j |dkr|S |dkr|| S |d	kr|| S t
d
| dS )zget the spine transformrK   )r#   r$   )r%   r&   zunknown spine spine_type: %sZgrid)Zwhichr_   r`   ra   z unknown spine_transform type: %sN)rG   rb   r   Z
transScaleZtransLimitsr1   r   r   Zblended_transform_factoryr   r   Zget_yaxis_transformZget_xaxis_transform)r   ZwhatZhowZ
data_xformresultZbase_transformr   r   r   rf     s6    






zSpine.get_spine_transformc             C   s&   | j dkrtd||f| _d| _dS )zSet the bounds of the spine.r7   z5set_bounds() method incompatible with circular spinesTN)r   r   r   r(   )r   rZ   r[   r   r   r   
set_bounds  s
    

zSpine.set_boundsc             C   s   | j S )zGet the bounds of the spine.)r   )r   r   r   r   
get_bounds  s    zSpine.get_boundsc             K   s   |dkrt ddg}nT|dkr0t ddg}n<|dkrHt ddg}n$|dkr`t ddg}ntd	| | |||f|}|td
|  |S )zA
        (staticmethod) Returns a linear :class:`Spine`.
        r#   )g        g+?r$   )g      ?g+?r&   )g+?g        r%   )g+?g      ?z"unable to make path for spine "%s"zaxes.spines.{0})r0   r   r   Zset_visibler   format)clsr   r   r!   r   rh   r   r   r   linear_spine  s    zSpine.linear_spinec       
      K   s2   t j||}| |||f|}	|	|||| |	S )z>
        (classmethod) Returns an arc :class:`Spine`.
        )r0   r   r+   r6   )
rl   r   r   r2   r3   r4   r5   r!   r   rh   r   r   r   	arc_spine  s    zSpine.arc_spinec             K   s.   t j }d}| |||f|}||| |S )zC
        (staticmethod) Returns a circular :class:`Spine`.
        r7   )r0   r   Zunit_circler8   )rl   r   r2   r3   r!   r   r   rh   r   r   r   circular_spine  s
    
zSpine.circular_spinec             C   s   |  | d| _dS )a  
        Set the edgecolor.

        Parameters
        ----------
        c : color or sequence of rgba tuples

        .. seealso::

            :meth:`set_facecolor`, :meth:`set_edgecolor`
               For setting the edge or face color individually.
        TN)r   r(   )r   cr   r   r   	set_color  s    
zSpine.set_color)N)$__name__
__module____qualname____doc__r	   r   Zdedent_interpdr   r'   r*   r6   r8   r9   r?   r@   rC   rD   rG   rI   rH   rQ   rB   r   r^   re   rF   rg   rf   ri   rj   classmethodrm   rn   ro   rq   __classcell__r   r   )r"   r   r      s8   /
lJ'%r   )rc   ZnumpyrT   r   r   r   Zmatplotlib.artistr   Zmatplotlib.transformsZ
transformsr   Zmatplotlib.patchesZpatchesZmpatchesZmatplotlib.pathr   r0   ZPatchr   r   r   r   r   <module>   s   