U
    \	ad                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ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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)SubplotBase)SubplotSpecGridSpec   )	axes_sizec                   @   s   e Zd ZdZd4ddZdd Zdd	 Zd
d Zedd Z	e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d5d!d"Zd#d$ Zd%d& Zd'd( Zd)d* Zd6d+d,Zd7d-d.Zd/d0 Zd8d2d3ZdS )9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   s:   || _ || _|| _|| _|| _|| _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 : {'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_aspect
_xrefindex
_yrefindex_locator)selffigpos
horizontalverticalaspectanchor r   H/tmp/pip-unpacked-wheel-wjyw_3jo/mpl_toolkits/axes_grid1/axes_divider.py__init__   s    zDivider.__init__c                    s    fdd|   D S )Nc                    s   g | ]}|  qS r   get_size.0srendererr   r   
<listcomp>8   s     z0Divider.get_horizontal_sizes.<locals>.<listcomp>)get_horizontalr   r#   r   r"   r   get_horizontal_sizes7   s    zDivider.get_horizontal_sizesc                    s    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>)get_verticalr&   r   r"   r   get_vertical_sizes:   s    zDivider.get_vertical_sizesc                 C   s$   t |  }t |  }||fS N)SizeZAddListr(   r%   )r   ZvsizeZhsizer   r   r   get_vsize_hsize=   s    zDivider.get_vsize_hsizec                 C   sF   d\}}| D ]\}}||7 }||7 }q|dkr>|| | }|S dS d S )N)        r-   r-   r   )lZ
total_sizeZrs_sumZas_sum_rs_askr   r   r   _calc_kB   s    
zDivider._calc_kc                 C   s2   dg}| D ]"\}}| |d ||  |  q
|S Nr-   )append)r.   r1   offsetsr/   r0   r   r   r   _calc_offsetsQ   s    zDivider._calc_offsetsc                 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_positionX   s    	zDivider.set_positionc                 C   s   | j S )z%Return the position of the rectangle.r8   r   r   r   r   get_positionc   s    zDivider.get_positionc                 C   s(   t |dkrtjtjj|d || _dS )a  
        Parameters
        ----------
        anchor : {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
            anchor position

          =====  ============
          value  description
          =====  ============
          'C'    Center
          'SW'   bottom left
          'S'    bottom
          'SE'   bottom right
          'E'    right
          'NE'   top right
          'N'    top
          'NW'   top left
          'W'    left
          =====  ============

           )r   N)lenr   check_in_listmtransformsBboxZcoefsr   )r   r   r   r   r   
set_anchorg   s    zDivider.set_anchorc                 C   s   | j S )zReturn the anchor.)r   r:   r   r   r   
get_anchor   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_horizontal   s    zDivider.set_horizontalc                 C   s   | j S )zReturn horizontal sizes.rC   r:   r   r   r   r%      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_vertical   s    zDivider.set_verticalc                 C   s   | j S )zReturn vertical sizes.rF   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.rI   r:   r   r   r   
get_aspect   s    zDivider.get_aspectc                 C   s
   || _ d S r*   r   )r   r   r   r   r   set_locator   s    zDivider.set_locatorc                 C   s   | j S r*   rM   r:   r   r   r   get_locator   s    zDivider.get_locatorc                 C   s$   | j d kr|  S |  ||jS d S r*   )r   r;   bounds)r   axr#   r   r   r   get_position_runtime   s    
zDivider.get_position_runtimec                 C   s  | j  \}}| ||\}	}
}}| |}| |}| ||| }| ||| }|  rt||}| ||}| ||}|d |d  | }|d |d  | }t	j
|	|
||}t	j
|	|
||}||  |}|j|j }}n"| ||}| ||}|	|
 }}|dkr |d }|dkr2|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 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
        r4   r   Nr   )r
   get_size_inchesrR   r'   r)   r2   rL   minr7   r?   r@   from_boundsanchoredrB   x0y0)r   nxnynx1ny1axesr#   figWfigHxywrD   ZhsizesZvsizesZk_hZk_vr1   oxoywwhhpbpb1pb1_anchoredrW   rX   x1w1y1h1r   r   r   locate   s4    





&&zDivider.locatec                 C   s   t | ||||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.
        AxesLocator)r   rY   rZ   r[   r\   r   r   r   new_locator   s    zDivider.new_locatorc                 C   s   |dkr&| j d| |  jd7  _nh|dkr<| j | nR|dkrb| jd| |  jd7  _n,|dkrx| j| ntjddddg|d d S )Nleftr   r   rightbottomtopposition)r   insertr   r5   r   r   r   r>   )r   rw   sizer   r   r   append_size   s    zDivider.append_size皙?c                 C   s^   |d krddddg}ddl m}m}m} |D ],}|||}||}	||	|}
| ||
 q,d S )Nrr   rs   rt   ru   r   )PaddedSizeFromFuncGetExtentHelper)r   r|   r}   r~   rz   )r   use_axespadadjust_dirsr|   r}   r~   dhelperry   Zpadded_sizer   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,   staticmethodr2   r7   r9   r;   rA   rB   rE   r%   rH   r(   rK   rL   rN   rO   rR   rn   rq   rz   r   r   r   r   r   r      s8      


		

2
r   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
rp   z|
    A simple callable object, initialized with AxesDivider class,
    returns the position and size of the given cell.
    Nc                 C   s`   || _ |j}|j}|| ||  | _| _|dkr8|d }|dkrH|d }|| | _|| | _dS )a  
        Parameters
        ----------
        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_ny_nx1_ny1)r   Zaxes_dividerrY   rZ   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 r*   )r   r   r   rn   r   r   r   r   )r   r]   r#   r   r   r   r   r   __call__4  s    zAxesLocator.__call__c                 C   s   t | jdr| j S d S d S Nget_subplotspec)hasattrr   r   r:   r   r   r   r   @  s    
zAxesLocator.get_subplotspec)NN)r   r   r   r   r   r   r   r   r   r   r   rp     s   
rp   c                       s   e Zd ZdZddddd fdd
Zdd Zed	ed
d Z	ed	dd Z
ejd	ddddd Zejd	dddd Zdd Zdd Z  ZS )SubplotDividerT
    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   L  s      zSubplotDivider.__init__c                 C   s   |   | jjS )z%Return the bounds of the subplot box.)r   r;   r   rP   r:   r   r   r   r;   c  s    zSubplotDivider.get_positionz3.4c                 C   s   |   | jS r*   )r   r;   r   r:   r   r   r   figboxg  s    zSubplotDivider.figboxc                 C   s   d S r*   r   r:   r   r   r   update_paramsl  s    zSubplotDivider.update_paramsr   z1(get_subplotspec returns a SubplotSpec instance.))alternativeZaddendumc                 C   s"   |    \}}}}|||d fS )z*Get the subplot geometry, e.g., (2, 2, 3).r   )r   get_geometry)r   ZrowscolsZnum1Znum2r   r   r   r   p  s    zSubplotDivider.get_geometryr   )r   c                 C   s,   t |||d  | _|   | | j dS )z;Change subplot geometry, e.g., from (1, 1, 1) to (2, 2, 3).r   N)r   _subplotspecr   r9   r   )r   ZnumrowsZnumcolsnumr   r   r   change_geometryx  s    zSubplotDivider.change_geometryc                 C   s   | j S )zGet the SubplotSpec instance.)r   r:   r   r   r   r     s    zSubplotDivider.get_subplotspecc                 C   s   || _ | || j dS )zSet the SubplotSpec instance.N)r   r9   r;   r   )r   Zsubplotspecr   r   r   r     s    zSubplotDivider.set_subplotspec)r   r   r   r   r   r;   r   
deprecatedpropertyr   r   r   r   r   r   __classcell__r   r   r   r   r   G  s*    
 

r   c                       sn   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Zdd Z	dd Z
dd Zdd Z  ZS )AxesDividerz1
    Divider based on the pre-existing 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     s      zAxesDivider.__init__)
axes_classc                K   sB   | j }|d kr(t|tr |j}nt|}|| |jddf|S NT)original)r   
isinstancer   Z_axes_class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dd |rdt|tjs6tj|| jd}|rX| 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 )	a  
        Add a new axes on the right (or left) side of the main axes.

        Parameters
        ----------
        size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            A width of the axes. If float or string is given, *from_any*
            function is used to create the size, with *ref_size* set to AxesX
            instance of the current axes.
        pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            Pad between the axes. It takes same argument as *size*.
        pack_start : bool
            If False, the new axes is appended at the end
            of the list, i.e., it became the right-most axes. If True, it is
            inserted at the start of the list, and becomes the left-most axes.
        **kwargs
            All extra keywords arguments are passed to the created axes.
            If *axes_class* is given, the new axes will be created as an
            instance of the given class. Otherwise, the same class of the
            main axes will be used.
        N3.2zrIn a future version, 'pad' will default to rcParams['figure.subplot.wspace'].  Set pad=0 to keep the old behavior.messageZfraction_refr   r   rY   rZ   )r   warn_deprecatedr   r+   _Basefrom_anyr   r   rx   r   r5   rq   r   r=   r   set_axes_locatorr   ry   r   
pack_startr   locatorrQ   r   r   r   new_horizontal  s4      
zAxesDivider.new_horizontalc                 K   s   |dkrt jddd |rdt|tjs6tj|| jd}|rX| 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 )	a  
        Add a new axes on the top (or bottom) side of the main axes.

        Parameters
        ----------
        size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            A height of the axes. If float or string is given, *from_any*
            function is used to create the size, with *ref_size* set to AxesX
            instance of the current axes.
        pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
            Pad between the axes. It takes same argument as *size*.
        pack_start : bool
            If False, the new axes is appended at the end
            of the list, i.e., it became the right-most axes. If True, it is
            inserted at the start of the list, and becomes the left-most axes.
        **kwargs
            All extra keywords arguments are passed to the created axes.
            If *axes_class* is given, the new axes will be created as an
            instance of the given class. Otherwise, the same class of the
            main axes will be used.
        Nr   zrIn a future version, 'pad' will default to rcParams['figure.subplot.hspace'].  Set pad=0 to keep the old behavior.r   r   r   r   r   )r   r   r   r+   r   r   r   r   rx   r   r5   rq   r   r=   r   r   r   r   r   r   new_vertical  s4      
zAxesDivider.new_verticalTc                 K   s   |dkr"| j ||fddi|}n||dkrD| j ||fddi|}nZ|dkrf| j||fddi|}n8|dkr| j||fddi|}ntjddddg|d |r| j| |S )	z
        Create an axes at the given *position* with the same height
        (or width) of the main axes.

         *position*
           ["left"|"right"|"bottom"|"top"]

         *size* and *pad* should be axes_grid.axes_size compatible.
        rr   r   Trs   Frt   ru   rv   )r   r   r   r>   r
   Zadd_axes)r   rw   ry   r   Zadd_to_figurer   rQ   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   rL   rJ   r   r   r   rL   *  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;   rP   )r   Zbboxr   r   r   r;   4  s    
zAxesDivider.get_positionc                 C   s   | j d kr| j S | j S d S r*   )r   r   rB   r:   r   r   r   rB   ;  s    

zAxesDivider.get_anchorc                 C   s   t | jdr| j S d S d S r   )r   r   r   r:   r   r   r   r   A  s    
zAxesDivider.get_subplotspec)NN)NF)NF)NT)r   r   r   r   r   r   r   r   r   rL   r;   rB   r   r   r   r   r   r   r     s   

1
1

r   c                   @   s@   e Zd Zedd Zedd ZdddZdd	 Zdd
dZdS )HBoxDividerc                 C   s   t | }t| j\}}t|j\}}t|d |d f}	t|d }
t|	d |d |f | d|	d |df< ||	dd df< | |
d |< |t| |
d< tj|	|
}|d d }|d }||kr|| | }|S )Nr   r4   )	r=   npZasarrayTzerosZfill_diagonalsumZlinalgZsolve)equivalent_sizesappended_sizesmax_equivalent_sizetotal_appended_sizenZeq_rsZeq_asZap_rsZap_asABZkarray_HkarrayHr   r   r   _determine_karrayJ  s     zHBoxDivider._determine_karrayc                 C   s<   dg}t | |D ]&\\}}}||d ||  |  q|S r3   )zipr5   )r   r   r6   rar1   r   r   r   r7   b  s    zHBoxDivider._calc_offsetsNc                 C   s   t | |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.
        ny, ny1 : int
            Same as *nx* and *nx1*, but for row positions.
        r   Nro   )r   rY   r[   r   r   r   rq   i  s    zHBoxDivider.new_locatorc	                 C   s   |}	|}
|| }|| }|  |	|
||}| |
|}|d |d  | }|	d }|d |d  |d  | }tj||||}tj||||}||  |}|j|j }}||||fS )Nr4   r   r   )	r   r7   r?   r@   rU   rV   rB   rW   rX   )r   r`   ra   rb   rD   y_equivalent_sizesx_appended_sizesr^   r_   r   r   r   r   r   rc   re   Zref_hrf   rg   rh   ri   rW   rX   r   r   r   _locatey  s"    zHBoxDivider._locatec              
   C   s   | j  \}}| ||\}	}
}}| |}| |}| |	|
||||||\}}}}|dkrf|d }||| |  || ||  |  }}|| }}tj||||S a  
        Parameters
        ----------
        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.
        axes
        renderer
        Nr   )	r
   rS   rR   r)   r'   r   r?   r@   rU   )r   rY   rZ   r[   r\   r]   r#   r^   r_   r`   ra   rb   rD   r   r   rW   rX   rc   rf   rj   rk   rl   rm   r   r   r   rn     s    

  &
zHBoxDivider.locate)N)NNNN)	r   r   r   r   r   r7   rq   r   rn   r   r   r   r   r   H  s   


r   c                   @   s$   e Zd ZdZdddZdddZdS )	VBoxDividerr   Nc                 C   s   t | d|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   Nro   )r   rZ   r\   r   r   r   rq     s    zVBoxDivider.new_locatorc              
   C   s   | j  \}}| ||\}	}
}}| |}| |}| |
|	||||||\}}}}|dkrf|d }|| }}||| |  || ||  |  }}tj||||S r   )	r
   rS   rR   r'   r)   r   r?   r@   rU   )r   rY   rZ   r[   r\   r]   r#   r^   r_   r`   ra   rb   rD   Zx_equivalent_sizesZy_appended_sizesrX   rW   rd   re   rj   rk   rl   rm   r   r   r   rn     s    

  
&zVBoxDivider.locate)N)NNNN)r   r   r   r   rq   rn   r   r   r   r   r     s   
r   c                 C   s$   t | }|jddd}| | |S )Nr   r   )r   rq   r   )r]   dividerr   r   r   r   make_axes_locatable  s    
r   r{   c                 C   s<   |d krddddg}t | }|d kr(| }|j|||d d S )Nrr   rs   rt   ru   )r   r   r   )r   r   )rQ   r   r   r   r   r   r   r   make_axes_area_auto_adjustable  s    r   )Nr{   N)r   Znumpyr   Z
matplotlibr   Zmatplotlib.axesr   Zmatplotlib.gridspecr   r   Zmatplotlib.transformsZ
transformsr?    r   r+   r   rp   r   r   r   r   r   r   r   r   r   r   <module>   s(     4B @j5	    