U
    EvfX                     @   s   d Z ddlZddl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ZG d	d
 d
ZG dd deZG dd deZdd ZG dd deZG dd deZdd ZdddZdS )zJ
Helper classes to adjust the positions of multiple axes at drawing time.
    N)_api)SubplotSpec   )	axes_sizec                   @   s   e Zd ZdZd2ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd3ddZdd Zdd  Zd!d" Zd#d$ Zed%d& Zed'd( Zd4d)d*Zd5d+d,Zd-d. Zd6d0d1ZdS )7DivideraQ  
    An Axes positioning class.

    The divider is initialized with lists of horizontal and vertical sizes
    (:mod:`mpl_toolkits.axes_grid1.axes_size`) based on which a given
    rectangular area will be divided.

    The `new_locator` method then creates a callable object
    that can be used as the *axes_locator* of the axes.
    NCc                 C   sD   || _ || _|| _|| _|| _| | || _d| _d| _d| _	dS )a  
        Parameters
        ----------
        fig : Figure
        pos : tuple of 4 floats
            Position of the rectangle that will be divided.
        horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
            Sizes for horizontal division.
        vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
            Sizes for vertical division.
        aspect : bool
            Whether overall rectangular area is reduced so that the relative
            part of the horizontal and vertical scales have the same scale.
        anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
            Placement of the reduced rectangle, when *aspect* is True.
        r   N)
_fig_pos_horizontal	_vertical_anchor
set_anchor_aspect
_xrefindex
_yrefindex_locator)selffigpos
horizontalverticalaspectanchor r   H/tmp/pip-unpacked-wheel-7vhvci0g/mpl_toolkits/axes_grid1/axes_divider.py__init__   s    
zDivider.__init__c                    s   t  fdd|  D S )Nc                    s   g | ]}|  qS r   get_size.0srendererr   r   
<listcomp>:   s     z0Divider.get_horizontal_sizes.<locals>.<listcomp>)nparrayget_horizontalr   r"   r   r!   r   get_horizontal_sizes9   s    zDivider.get_horizontal_sizesc                    s   t  fdd|  D S )Nc                    s   g | ]}|  qS r   r   r   r!   r   r   r#   =   s     z.Divider.get_vertical_sizes.<locals>.<listcomp>)r$   r%   get_verticalr'   r   r!   r   get_vertical_sizes<   s    zDivider.get_vertical_sizesc                 C   s
   || _ dS )z
        Set the position of the rectangle.

        Parameters
        ----------
        pos : tuple of 4 floats
            position of the rectangle that will be divided
        Nr	   )r   r   r   r   r   set_position?   s    	zDivider.set_positionc                 C   s   | j S )z%Return the position of the rectangle.r+   r   r   r   r   get_positionJ   s    zDivider.get_positionc                 C   sJ   t |trtjtjj|d n"t |ttfr8t	|dkr@t
d|| _dS )a  
        Parameters
        ----------
        anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
            Either an (*x*, *y*) pair of relative coordinates (0 is left or
            bottom, 1 is right or top), 'C' (center), or a cardinal direction
            ('SW', southwest, is bottom left, etc.).

        See Also
        --------
        .Axes.set_anchor
        )r      zanchor must be str or 2-tupleN)
isinstancestrr   check_in_listmtransformsBboxZcoefstuplelistlen	TypeErrorr   )r   r   r   r   r   r   N   s
    
zDivider.set_anchorc                 C   s   | j S )zReturn the anchor.)r   r-   r   r   r   
get_anchorb   s    zDivider.get_anchorc                 C   s
   || _ dS )z
        Parameters
        ----------
        h : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
            sizes for horizontal division
        Nr
   )r   hr   r   r   set_horizontalf   s    zDivider.set_horizontalc                 C   s   | j S )zReturn horizontal sizes.r:   r-   r   r   r   r&   o   s    zDivider.get_horizontalc                 C   s
   || _ dS )z
        Parameters
        ----------
        v : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
            sizes for vertical division
        Nr   )r   vr   r   r   set_verticals   s    zDivider.set_verticalc                 C   s   | j S )zReturn vertical sizes.r=   r-   r   r   r   r)   |   s    zDivider.get_verticalFc                 C   s
   || _ dS )zE
        Parameters
        ----------
        aspect : bool
        Nr   r   r   r   r   r   
set_aspect   s    zDivider.set_aspectc                 C   s   | j S )zReturn aspect.r@   r-   r   r   r   
get_aspect   s    zDivider.get_aspectc                 C   s
   || _ d S Nr   )r   r   r   r   r   set_locator   s    zDivider.set_locatorc                 C   s   | j S rD   rE   r-   r   r   r   get_locator   s    zDivider.get_locatorc                 C   s$   | j d kr|  S |  ||jS d S rD   )r   r.   bounds)r   axr"   r   r   r   get_position_runtime   s    
zDivider.get_position_runtimec                 C   s"   |  d\}}|r|| | S dS )Nr   )sum)sizestotalZrel_sumZabs_sumr   r   r   _calc_k   s    zDivider._calc_kc                 C   s   t d| |dg S )Nr   r   )r   )r$   cumsum)rL   kr   r   r   _calc_offsets   s    zDivider._calc_offsetsc                 C   s  | j jj| j j \}}| ||\}	}
}}| |}| |}| ||| }| ||| }|  rt	||}| 
||}| 
||}|d |d  | }|d |d  | }tj|	|
||}tj|	|
||}||  |j\}}n"| 
||}| 
||}|	|
 }}|dkrd}|dkr*d}||| |  || ||  |  }}||| |  || ||  |  }}tj||||S )a  
        Parameters
        ----------
        nx, nx1 : int
            Integers specifying the column-position of the cell. When *nx1* is
            None, a single *nx*-th column is specified. Otherwise, the
            location of columns spanning between *nx* to *nx1* (but excluding
            *nx1*-th column) is specified.
        ny, ny1 : int
            Same as *nx* and *nx1*, but for row positions.
        axes
        renderer
        r   N)r   bboxsizedpirJ   r(   r*   rN   rC   minrQ   r3   r4   from_boundsanchoredr9   p0)r   nxnynx1ny1axesr"   fig_wfig_hxywr;   ZhsizesZvsizesZk_hZk_vrP   oxoywwhhpbpb1x0y0x1w1y1h1r   r   r   locate   s2    





&&zDivider.locatec                 C   s0   t | |||dk	r|n|d |dk	r&|n|d S )a  
        Return a new `.AxesLocator` for the specified cell.

        Parameters
        ----------
        nx, nx1 : int
            Integers specifying the column-position of the
            cell. When *nx1* is None, a single *nx*-th column is
            specified. Otherwise, location of columns spanning between *nx*
            to *nx1* (but excluding *nx1*-th column) is specified.
        ny, ny1 : int
            Same as *nx* and *nx1*, but for row positions.
        Nr   AxesLocator)r   rZ   r[   r\   r]   r   r   r   new_locator   s      zDivider.new_locatorc                 C   s   t jddddg|d |dkr<| jd| |  jd7  _nH|dkrR| j| n2|dkrx| jd| |  jd7  _n| j| d S )Nleftrightbottomtoppositionr   r   )r   r2   r
   insertr   appendr   r   )r   ry   rT   r   r   r   append_size   s    zDivider.append_size皙?c                 C   s:   |dkrddddg}|D ]}|  |t|||  qdS )a1  
        Add auto-adjustable padding around *use_axes* to take their decorations
        (title, labels, ticks, ticklabels) into account during layout.

        Parameters
        ----------
        use_axes : `~matplotlib.axes.Axes` or list of `~matplotlib.axes.Axes`
            The Axes whose decorations are taken into account.
        pad : float, optional
            Additional padding in inches.
        adjust_dirs : list of {"left", "right", "bottom", "top"}, optional
            The sides where padding is added; defaults to all four sides.
        Nrt   ru   rv   rw   )r|   SizeZ_AxesDecorationsSize)r   use_axespadadjust_dirsdr   r   r   add_auto_adjustable_area   s    z Divider.add_auto_adjustable_area)Nr   )F)NNNN)NN)r}   N)__name__
__module____qualname____doc__r   r(   r*   r,   r.   r   r9   r<   r&   r?   r)   rB   rC   rF   rG   rJ   staticmethodrN   rQ   rp   rs   r|   r   r   r   r   r   r      s6      
		



1
r   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
rr   zc
    A callable object which returns the position and size of a given
    `.AxesDivider` cell.
    Nc                 C   sh   || _ |j}|j}|| ||  | _| _|dkr:t| j }|dkrPt| j d }|| | _|| | _dS )a  
        Parameters
        ----------
        axes_divider : `~mpl_toolkits.axes_grid1.axes_divider.AxesDivider`
        nx, nx1 : int
            Integers specifying the column-position of the
            cell. When *nx1* is None, a single *nx*-th column is
            specified. Otherwise, location of columns spanning between *nx*
            to *nx1* (but excluding *nx1*-th column) is specified.
        ny, ny1 : int
            Same as *nx* and *nx1*, but for row positions.
        Nr   )_axes_dividerr   r   _nx_nyr7   _nx1_ny1)r   Zaxes_dividerrZ   r[   r\   r]   r   r   r   r   r   r     s    

zAxesLocator.__init__c                 C   s>   | j j}| j j}| j | j| | j| | j| | j| ||S rD   )r   r   r   rp   r   r   r   r   )r   r^   r"   r   r   r   r   r   __call__-  s    zAxesLocator.__call__c                 C   s
   | j  S rD   )r   get_subplotspecr-   r   r   r   r   9  s    zAxesLocator.get_subplotspec)NN)r   r   r   r   r   r   r   r   r   r   r   rr     s   
rr   c                       sD   e Zd ZdZddddd fdd
Zdd Zd	d
 Zdd Z  ZS )SubplotDividerzT
    The Divider class whose rectangle area is specified as a subplot geometry.
    Nr   r   r   r   r   c                   sD   || _ t j|ddddg|pg |p$g ||d | t|| dS )a=  
        Parameters
        ----------
        fig : `~matplotlib.figure.Figure`

        *args : tuple (*nrows*, *ncols*, *index*) or int
            The array of subplots in the figure has dimensions ``(nrows,
            ncols)``, and *index* is the index of the subplot being created.
            *index* starts at 1 in the upper left corner and increases to the
            right.

            If *nrows*, *ncols*, and *index* are all single digit numbers, then
            *args* can be passed as a single 3-digit number (e.g. 234 for
            (2, 3, 4)).
        r   r   r   N)figuresuperr   set_subplotspecr   Z_from_subplot_args)r   r   r   r   r   r   args	__class__r   r   r   B  s      zSubplotDivider.__init__c                 C   s   |   | jjS )z%Return the bounds of the subplot box.)r   r.   r   rH   r-   r   r   r   r.   Y  s    zSubplotDivider.get_positionc                 C   s   | j S )zGet the SubplotSpec instance.)_subplotspecr-   r   r   r   r   ]  s    zSubplotDivider.get_subplotspecc                 C   s   || _ | || j dS )zSet the SubplotSpec instance.N)r   r,   r.   r   )r   Zsubplotspecr   r   r   r   a  s    zSubplotDivider.set_subplotspec)	r   r   r   r   r   r.   r   r   __classcell__r   r   r   r   r   =  s    r   c                       st   e Zd ZdZd fdd	ZddddZdd	d
ZdddZdddddZdd Z	dd Z
dd Zdd Z  ZS )AxesDividerz0
    Divider based on the preexisting axes.
    Nc                    sf   || _ |dkrt|| _n|| _|dkr8t|| _n|| _t j| d| jg| jgddd dS )zw
        Parameters
        ----------
        axes : :class:`~matplotlib.axes.Axes`
        xref
        yref
        Nr   )r   r   r   r   r   r   )	_axesr~   ZAxesX_xrefZAxesY_yrefr   r   
get_figure)r   r^   ZxrefZyrefr   r   r   r   l  s      zAxesDivider.__init__)
axes_classc                K   s0   | j }|d krt|}|| |jddf|S NT)original)r   typer   r.   )r   r   kwargsr^   r   r   r   _get_new_axes  s    zAxesDivider._get_new_axesFc                 K   s   |dkrt jd | j }|rft|tjs8tj|| jd}|rZ| jd| |  j	d7  _	n| j
| t|tjstj|| jd}|r| jd| |  j	d7  _	| jd| jd}n&| j
| | jt| jd | jd}| jf |}|| |S )z
        Helper method for ``append_axes("left")`` and ``append_axes("right")``.

        See the documentation of `append_axes` for more details.

        :meta private:
        Nzfigure.subplot.wspaceZfraction_refr   r   rZ   r[   )mplrcParamsr   r0   r~   _Basefrom_anyr
   rz   r   r{   rs   r   r7   r   set_axes_locatorr   rT   r   
pack_startr   locatorrI   r   r   r   new_horizontal  s.     
zAxesDivider.new_horizontalc                 K   s   |dkrt jd | j }|rft|tjs8tj|| jd}|rZ| jd| |  j	d7  _	n| j
| t|tjstj|| jd}|r| jd| |  j	d7  _	| j| jdd}n&| j
| | j| jt| jd d}| jf |}|| |S )z
        Helper method for ``append_axes("top")`` and ``append_axes("bottom")``.

        See the documentation of `append_axes` for more details.

        :meta private:
        Nzfigure.subplot.hspacer   r   r   r   )r   r   r   r0   r~   r   r   r   rz   r   r{   rs   r   r7   r   r   r   r   r   r   new_vertical  s.     
zAxesDivider.new_verticalc          	      K   s\   t j| jdf| jdf| jdf| jdfd|d\}}|||f||d|}| j| |S )am  
        Add a new axes on a given side of the main axes.

        Parameters
        ----------
        position : {"left", "right", "bottom", "top"}
            Where the new axes is positioned relative to the main axes.
        size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            The axes width or height.  float or str arguments are interpreted
            as ``axes_size.from_any(size, AxesX(<main_axes>))`` for left or
            right axes, and likewise with ``AxesY`` for bottom or top axes.
        pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            Padding between the axes.  float or str arguments are interpreted
            as for *size*.  Defaults to :rc:`figure.subplot.wspace` times the
            main Axes width (left or right axes) or :rc:`figure.subplot.hspace`
            times the main Axes height (bottom or top axes).
        axes_class : subclass type of `~.axes.Axes`, optional
            The type of the new axes.  Defaults to the type of the main axes.
        **kwargs
            All extra keywords arguments are passed to the created axes.
        TF)rt   ru   rv   rw   rx   )r   r   )r   Zcheck_getitemr   r   r   Zadd_axes)	r   ry   rT   r   r   r   Zcreate_axesr   rI   r   r   r   append_axes  s&    
  zAxesDivider.append_axesc                 C   s0   | j d kr&| j }|dkr dS dS n| j S d S )NautoFT)r   r   rC   rA   r   r   r   rC     s    

zAxesDivider.get_aspectc                 C   s(   | j d kr| jjdd}|jS | j S d S r   )r	   r   r.   rH   )r   rS   r   r   r   r.     s    
zAxesDivider.get_positionc                 C   s   | j d kr| j S | j S d S rD   )r   r   r9   r-   r   r   r   r9     s    

zAxesDivider.get_anchorc                 C   s
   | j  S rD   )r   r   r-   r   r   r   r     s    zAxesDivider.get_subplotspec)NN)NF)NF)N)r   r   r   r   r   r   r   r   r   rC   r.   r9   r   r   r   r   r   r   r   g  s   
 
 "
r   c	                 C   s"  || }	|| }
t |}|j\}}|j\}}t|d}d|d |df< ||dd df< | |	|  f}tj||^ }}||
kr|
| | }td|| | }|d |d  | }|d \}}|d | | | }tj	
| |||}tj	
| |||}|||j\}}||||fS )Nr   rR   )r   )r   )r7   Tr$   ZdiagrK   ZlinalgZsolverO   r3   r4   rW   rX   rY   )ra   rb   rc   r;   Zsummed_widthsZequal_heightsr_   r`   r   Ztotal_widthZ
max_heightnZeq_relsZeq_abssZsm_relsZsm_abssABZkarrayheightrd   rf   Zh0_relZh0_absrg   rh   ri   rj   rk   r   r   r   _locate	  s(    

r   c                   @   s$   e Zd ZdZdddZdddZdS )	HBoxDividerz
    A `.SubplotDivider` for laying out axes horizontally, while ensuring that
    they have equal heights.

    Examples
    --------
    .. plot:: gallery/axes_grid1/demo_axes_hbox_divider.py
    Nc                 C   s    t | |d|dk	r|n|d dS )a  
        Create a new `.AxesLocator` for the specified cell.

        Parameters
        ----------
        nx, nx1 : int
            Integers specifying the column-position of the
            cell. When *nx1* is None, a single *nx*-th column is
            specified. Otherwise, location of columns spanning between *nx*
            to *nx1* (but excluding *nx1*-th column) is specified.
        r   Nr   rq   )r   rZ   r\   r   r   r   rs   4  s    zHBoxDivider.new_locatorc                 C   s   | j jj| j j \}}| ||\}	}
}}| |}| |}t|	|
|||||||  	\}}}}|d krnd}||| |  || ||  |  }}|| }}t	j
||||S NrR   )r   rS   rT   rU   rJ   r(   r*   r   r9   r3   r4   rW   )r   rZ   r[   r\   r]   r^   r"   r_   r`   ra   rb   rc   r;   Z	summed_wsZequal_hsrj   rk   rd   rg   rl   rm   rn   ro   r   r   r   rp   B  s(    

        &
zHBoxDivider.locate)N)NNNNr   r   r   r   rs   rp   r   r   r   r   r   *  s   	
r   c                   @   s$   e Zd ZdZdddZdddZdS )	VBoxDividerzm
    A `.SubplotDivider` for laying out axes vertically, while ensuring that
    they have equal widths.
    Nc                 C   s    t | d|d|dk	r|n|d S )a  
        Create a new `.AxesLocator` for the specified cell.

        Parameters
        ----------
        ny, ny1 : int
            Integers specifying the row-position of the
            cell. When *ny1* is None, a single *ny*-th row is
            specified. Otherwise, location of rows spanning between *ny*
            to *ny1* (but excluding *ny1*-th row) is specified.
        r   r   Nrq   )r   r[   r]   r   r   r   rs   W  s    zVBoxDivider.new_locatorc                 C   s   | j jj| j j \}}| ||\}	}
}}| |}| |}t|
|	|||||||  	\}}}}|d krnd}|| }}||| |  || ||  |  }}t	j
||||S r   )r   rS   rT   rU   rJ   r*   r(   r   r9   r3   r4   rW   )r   rZ   r[   r\   r]   r^   r"   r_   r`   ra   rb   rc   r;   Z	summed_hsZequal_wsrk   rj   re   rf   rl   rm   rn   ro   r   r   r   rp   e  s(    

        
&zVBoxDivider.locate)N)NNNNr   r   r   r   r   r   Q  s   
r   c                 C   s$   t | }|jddd}| | |S )Nr   r   )r   rs   r   )r^   dividerr   r   r   r   make_axes_locatablet  s    
r   r}   c                 C   s<   |dkrddddg}t | }|dkr(| }|j|||d dS )aG  
    Add auto-adjustable padding around *ax* to take its decorations (title,
    labels, ticks, ticklabels) into account during layout, using
    `.Divider.add_auto_adjustable_area`.

    By default, padding is determined from the decorations of *ax*.
    Pass *use_axes* to consider the decorations of other Axes instead.
    Nrt   ru   rv   rw   )r   r   r   )r   r   )rI   r   r   r   r   r   r   r   make_axes_area_auto_adjustable|  s    
r   )Nr}   N)r   Znumpyr$   Z
matplotlibr   r   Zmatplotlib.gridspecr   Zmatplotlib.transformsZ
transformsr3    r   r~   r   rr   r   r   r   r   r   r   r   r   r   r   r   <module>   s(    ~2* #!'#	     