U
    \	al                     @   s2  d Z ddlm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 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G dd de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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S )%a  
Default legend handlers.

It is strongly encouraged to have read the :doc:`legend guide
</tutorials/intermediate/legend_guide>` before this documentation.

Legend handlers are expected to be a callable object with a following
signature. ::

    legend_handler(legend, orig_handle, fontsize, handlebox)

Where *legend* is the legend itself, *orig_handle* is the original
plot, *fontsize* is the fontsize in pixels, and *handlebox* is a
OffsetBox instance. Within the call, you should create relevant
artists (using relevant properties from the *legend* and/or
*orig_handle*) and add them into the handlebox. The artists needs to
be scaled according to the fontsize (note that the size is in pixel,
i.e., this is dpi-scaled value).

This module includes definition of several legend handler classes
derived from the base class (HandlerBase) with the following method::

    def legend_artist(self, legend, orig_handle, fontsize, handlebox)
    )cycleN)cbookLine2D)	Rectanglec                 C   s(   t t| d }|d k	r$| | d S N)nextiterZget_childrenupdate_from)ZtgtsrcZfirst_child r   =/tmp/pip-unpacked-wheel-wjyw_3jo/matplotlib/legend_handler.pyupdate_from_first_child$   s    r   c                   @   sJ   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dS )HandlerBasea   
    A Base class for default legend handlers.

    The derived classes are meant to override *create_artists* method, which
    has a following signature.::

      def create_artists(self, legend, orig_handle,
                         xdescent, ydescent, width, height, fontsize,
                         trans):

    The overridden method needs to create artists of the given
    transform that fits in the given dimension (xdescent, ydescent,
    width, height) that are scaled by fontsize if necessary.

            Nc                 C   s   || | _ | _|| _d S r   )_xpad_ypad_update_prop_func)selfZxpadZypadZupdate_funcr   r   r   __init__:   s    zHandlerBase.__init__c                 C   s(   | j d kr| || n|  || d S r   )r   _default_update_propr   legend_handleorig_handler   r   r   _update_prop>   s    
zHandlerBase._update_propc                 C   s   | | d S r   )r
   r   r   r   r   r   D   s    z HandlerBase._default_update_propc                 C   s.   |  || || |d  |d  d S r   )r   Z_set_artist_propsset_clip_boxset_clip_pathr   r   r   legendr   r   r   update_propG   s    

zHandlerBase.update_propc                 C   sD   || j |  }|| j|  }|| j |  }|| j|  }||||fS r   )r   r   )r   r   r   xdescentydescentwidthheightfontsizer   r   r   adjust_drawing_areaO   s
    zHandlerBase.adjust_drawing_areac                 C   s^   |  |||j|j|j|j|\}}}}| |||||||| }	|	D ]}
||
 qF|	d S )a-  
        Return the artist that this HandlerBase generates for the given
        original artist/handle.

        Parameters
        ----------
        legend : `~matplotlib.legend.Legend`
            The legend for which these legend artists are being created.
        orig_handle : :class:`matplotlib.artist.Artist` or similar
            The object for which these legend artists are being created.
        fontsize : int
            The fontsize in pixels. The artists being created should
            be scaled according to the given fontsize.
        handlebox : `matplotlib.offsetbox.OffsetBox`
            The box which has been created to hold this legend entry's
            artists. Artists created in the `legend_artist` method must
            be added to this handlebox inside this method.

        r   )r%   r    r!   r"   r#   create_artistsZget_transformZ
add_artist)r   r   r   r$   Z	handleboxr    r!   r"   r#   artistsar   r   r   legend_artistX   s(           zHandlerBase.legend_artistc	           	      C   s   t dd S )NzDerived must override)NotImplementedError)	r   r   r   r    r!   r"   r#   r$   transr   r   r   r&   }   s    zHandlerBase.create_artists)r   r   N)__name__
__module____qualname____doc__r   r   r   r   r%   r)   r&   r   r   r   r   r   *   s   
	%r   c                       s2   e Zd ZdZd
 fdd	Zdd Zdd	 Z  ZS )HandlerNpointszM
    A legend handler that shows *numpoints* points in the legend entry.
    333333?Nc                    s   t  jf | || _|| _dS )a*  
        Parameters
        ----------
        marker_pad : float
            Padding between points in legend entry.

        numpoints : int
            Number of points to show in legend entry.

        Notes
        -----
        Any other keyword arguments are given to `HandlerBase`.
        N)superr   
_numpoints_marker_padr   
marker_pad	numpointskw	__class__r   r   r      s    zHandlerNpoints.__init__c                 C   s   | j d kr|jS | j S d S r   )r3   r7   r   r   r   r   r   get_numpoints   s    
zHandlerNpoints.get_numpointsc                 C   sh   |  |}|dkr@| j| }t| | | | | |}	|	}
n | | | g}	| d|  g}
|	|
fS )N         ?)r<   r4   nplinspace)r   r   r    r!   r"   r#   r$   r7   padxdataxdata_markerr   r   r   	get_xdata   s    

zHandlerNpoints.get_xdata)r1   N)r,   r-   r.   r/   r   r<   rD   __classcell__r   r   r9   r   r0      s   r0   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )HandlerNpointsYoffsetsz
    A legend handler that shows *numpoints* in the legend, and allows them to
    be individually offset in the y-direction.
    Nc                    s    t  jf d|i| || _dS )a^  
        Parameters
        ----------
        numpoints : int
            Number of points to show in legend entry.

        yoffsets : array of floats
            Length *numpoints* list of y offsets for each point in
            legend entry.

        Notes
        -----
        Any other keyword arguments are given to `HandlerNpoints`.
        r7   N)r2   r   	_yoffsets)r   r7   yoffsetsr8   r9   r   r   r      s    zHandlerNpointsYoffsets.__init__c                 C   s*   | j d kr||j }n|t| j  }|S r   rG   Z_scatteryoffsetsr?   asarrayr   r   r    r!   r"   r#   r$   ydatar   r   r   	get_ydata   s    
z HandlerNpointsYoffsets.get_ydata)NN)r,   r-   r.   r/   r   rM   rE   r   r   r9   r   rF      s   rF   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )	HandlerLine2Dz*
    Handler for `.Line2D` instances.
    r1   Nc                    s   t  jf ||d| dS )a-  
        Parameters
        ----------
        marker_pad : float
            Padding between points in legend entry.

        numpoints : int
            Number of points to show in legend entry.

        Notes
        -----
        Any other keyword arguments are given to `HandlerNpoints`.
        r6   r7   Nr2   r   r5   r9   r   r   r      s    zHandlerLine2D.__init__c	                 C   s   |  ||||||\}	}
t|	|| d }t|	|}| ||| |d |d t|
|d t|
 }| ||| |d |j	dkr|
 |j	 }|| ||_|| || ||gS )N   default Noner=   )rD   r?   	full_liker   r   set_drawstyle
set_markerlenset_linestylemarkerscaleget_markersizeset_markersizeZ
_legmarkerset_transform)r   r   r   r    r!   r"   r#   r$   r+   rB   rC   rL   leglinelegline_markernewszr   r   r   r&      s(    
  







zHandlerLine2D.create_artists)r1   Nr,   r-   r.   r/   r   r&   rE   r   r   r9   r   rN      s   rN   c                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )
HandlerPatchz)
    Handler for `.Patch` instances.
    Nc                    s   t  jf | || _dS )a  
        Parameters
        ----------
        patch_func : callable, optional
            The function that creates the legend key artist.
            *patch_func* should have the signature::

                def patch_func(legend=legend, orig_handle=orig_handle,
                               xdescent=xdescent, ydescent=ydescent,
                               width=width, height=height, fontsize=fontsize)

            Subsequently the created artist will have its ``update_prop``
            method called and the appropriate transform will be applied.

        Notes
        -----
        Any other keyword arguments are given to `HandlerBase`.
        N)r2   r   _patch_func)r   Z
patch_funcr8   r9   r   r   r     s    zHandlerPatch.__init__c           	   	   C   s>   | j d kr"t| | f||d}n| j |||||||d}|S )Nxyr"   r#   )r   r   r    r!   r"   r#   r$   )rc   r   	r   r   r   r    r!   r"   r#   r$   pr   r   r   _create_patch  s    
    zHandlerPatch._create_patchc	           
   	   C   s4   |  |||||||}	| |	|| |	| |	gS r   )rh   r   r]   
r   r   r   r    r!   r"   r#   r$   r+   rg   r   r   r   r&   '  s        
zHandlerPatch.create_artists)N)r,   r-   r.   r/   r   rh   r&   rE   r   r   r9   r   rb     s   rb   c                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
HandlerStepPatchzA
    Handler for `~.matplotlib.patches.StepPatch` instances.
    c                    s   t  jf | dS )zI
        Any other keyword arguments are given to `HandlerBase`.
        NrP   )r   r8   r9   r   r   r   4  s    zHandlerStepPatch.__init__c           	      C   s    t | | f| ||d}|S )N)re   colorr"   r#   )r   get_facecolorrf   r   r   r   rh   :  s     zHandlerStepPatch._create_patchc           	      C   sF   t d|g|d |d g| | | d}|d |d |S )Nr   rQ   )rk   Z	linestyleZ	linewidthrR   rS   )r   get_edgecolorget_linestyleZget_linewidthrV   rW   )	r   r   r   r    r!   r"   r#   r$   r^   r   r   r   _create_lineB  s    

zHandlerStepPatch._create_linec	           
   	   C   s`   |  s| d k	r:| |||||||}	| |	|| n| |||||||}	|	| |	gS r   )get_fill	get_hatchrh   r   ro   r]   ri   r   r   r   r&   P  s$            
zHandlerStepPatch.create_artists)	r,   r-   r.   r/   r   rh   ro   r&   rE   r   r   r9   r   rj   0  s
   rj   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	HandlerLineCollectionz2
    Handler for `.LineCollection` instances.
    c                 C   s   | j d kr|jS | j S d S r   r3   Zscatterpointsr;   r   r   r   r<   a  s    
z#HandlerLineCollection.get_numpointsc                 C   sD   |  d }|jd }| d }|| || || d S Nr   )get_linewidthsZ_us_linestylesZ
get_colors	set_colorrY   set_linewidth)r   r   r   ZlwZdashesrk   r   r   r   r   g  s    


z*HandlerLineCollection._default_update_propc	                 C   sT   |  ||||||\}	}
t|	|| d }t|	|}| ||| || |gS )NrQ   )rD   r?   rU   r   r   r]   )r   r   r   r    r!   r"   r#   r$   r+   rB   rC   rL   r^   r   r   r   r&   o  s    
  

z$HandlerLineCollection.create_artistsN)r,   r-   r.   r/   r<   r   r&   r   r   r   r   rr   ]  s   rr   c                       sJ   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	  Z
S )HandlerRegularPolyCollectionz'Handler for `.RegularPolyCollection`\s.Nc                    s    t  jf d|i| || _d S )NrH   )r2   r   _sizes)r   rH   sizesr8   r9   r   r   r     s    z%HandlerRegularPolyCollection.__init__c                 C   s   | j d kr|jS | j S d S r   rs   r;   r   r   r   r<     s    
z*HandlerRegularPolyCollection.get_numpointsc                 C   s   | j d kr| }t|s dg}t||jd  }	t||jd  }
| |}|dk rrd|	|
  |	|
gd | }q|	|
 }|tdd| |
 }n| j }|S )Nr=   rQ      r>   r   )	ry   	get_sizesrX   maxrZ   minr<   r?   r@   )r   r   r   r    r!   r"   r#   r$   Zhandle_sizesZsize_maxZsize_minr7   rz   rngr   r   r   r|     s"    

z&HandlerRegularPolyCollection.get_sizesc                 C   s0   |  || ||j |d  |d  d S r   )r   
set_figurefigurer   r   r   r   r   r   r     s    
z(HandlerRegularPolyCollection.update_propc                 C   s"   t || | |||d}|S )N)Zrotationrz   offsetstransOffset)typeZget_numsidesZget_rotationr   r   rz   r   r   rg   r   r   r   create_collection  s    z.HandlerRegularPolyCollection.create_collectionc	              	   C   sx   |  ||||||\}	}
| ||||||}| |||||||}| j||tt|
||d}| ||| ||_|gS N)r   r   )rD   rM   r|   r   listzipr   Z_transOffset)r   r   r   r    r!   r"   r#   r$   r+   rB   rC   rL   rz   rg   r   r   r   r&     s,    
  
    z+HandlerRegularPolyCollection.create_artists)NN)r,   r-   r.   r/   r   r<   r|   r   r   r&   rE   r   r   r9   r   rx   }  s   		rx   c                   @   s   e Zd ZdZdd ZdS )HandlerPathCollectionzDHandler for `.PathCollection`\s, which are used by `~.Axes.scatter`.c                 C   s"   t || d g|||d}|S )Nr   )rz   r   r   )r   	get_pathsr   r   r   r   r     s    z'HandlerPathCollection.create_collectionNr,   r-   r.   r/   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZdd ZdS )HandlerCircleCollectionz"Handler for `.CircleCollection`\s.c                 C   s   t ||||d}|S r   )r   r   r   r   r   r     s
    z)HandlerCircleCollection.create_collectionNr   r   r   r   r   r     s   r   c                       s2   e Zd ZdZd fdd	Zdd Zd	d
 Z  ZS )HandlerErrorbarzHandler for Errorbars.r>   Nr1   c                    s(   || _ || _t jf ||d| d S )NrO   )
_xerr_size
_yerr_sizer2   r   )r   	xerr_size	yerr_sizer6   r7   r8   r9   r   r   r     s    zHandlerErrorbar.__init__c           	      C   s,   | j | }| jd kr|}n
| j| }||fS r   )r   r   )	r   r   r    r!   r"   r#   r$   r   r   r   r   r   get_err_size  s
    


zHandlerErrorbar.get_err_sizec	                    s  |\}	}
}|  ||||||\}}t||| d }t||}t|}t|d t| }| ||||||\ t||}|	d kr|d |d n\| ||	| |	d |
d | ||	| |d |jdkr| |j }|| g }g }|jr fddt||D }t|}| ||d | || |
rt|  |}t|  |}| ||
d | | ||
d | |
d	 |
d	 || || |jrlfd
dt||D }t|}| ||d | || |
rlt|| }t|| }| ||
d | | ||
d | |
d |
d || || ||||f}|D ]}|| q~|S )NrQ   FrR   rT   r=   c                    s(   g | ] \}}|  |f|  |ffqS r   r   .0xy)r   r   r   
<listcomp>  s   z2HandlerErrorbar.create_artists.<locals>.<listcomp>r   |c                    s(   g | ] \}}||  f||  ffqS r   r   r   )r   r   r   r   .  s   _)rD   r?   rU   r   rJ   rX   r   Zset_visibler   rV   rW   rY   rZ   r[   r\   Zhas_xerrr   mcollLineCollectionappendZhas_yerrr]   )r   r   r   r    r!   r"   r#   r$   r+   Z	plotlinesZcaplinesZbarlinecolsrB   rC   rL   r^   Zydata_markerr_   r`   Zhandle_barlinecolsZhandle_caplinesZvertsZcollZcapline_leftZcapline_rightr'   artistr   )r   r   r   r&     s    

  


  




















   zHandlerErrorbar.create_artists)r>   Nr1   N)r,   r-   r.   r/   r   r   r&   rE   r   r   r9   r   r     s       r   c                       s:   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Z  ZS )HandlerStemz6
    Handler for plots produced by `~.Axes.stem`.
    r1   Nc                    s$   t  jf |||d| || _dS )a  
        Parameters
        ----------
        marker_pad : float, default: 0.3
            Padding between points in legend entry.

        numpoints : int, optional
            Number of points to show in legend entry.

        bottom : float, optional

        yoffsets : array of floats, optional
            Length *numpoints* list of y offsets for each point in
            legend entry.

        Notes
        -----
        Any other keyword arguments are given to `HandlerNpointsYoffsets`.
        )r6   r7   rH   N)r2   r   _bottom)r   r6   r7   bottomrH   r8   r9   r   r   r   K  s    zHandlerStem.__init__c                 C   s2   | j d kr|d|j d  }n|t| j  }|S )Nr>   rI   rK   r   r   r   rM   e  s    
zHandlerStem.get_ydatac	              	      sB  |\}	}
}t |
tj}| ||||||\}}| ||||||}| jd krRd n| j t||d t| }| ||	|  fddt	||D }|rt
j| | jd |D ]}| ||
| qW 5 Q R X n"t	||
D ]\}}| ||| qtt|t|g  g}| ||| |||f}|D ]}|| q,|S )Nr   c                    s"   g | ]\}}t ||g |gqS r   r   r   r   r   r   r     s   z.HandlerStem.create_artists.<locals>.<listcomp>)r   )
isinstancer   r   rD   rM   r   r   rX   r   r   r   Z_setattr_cm_copy_collection_propsr?   r~   r}   r]   )r   r   r   r    r!   r"   r#   r$   r+   Z
markerlineZ	stemlinesZbaselineZusing_linecollrB   rC   rL   Zleg_markerlineZleg_stemlineslineZlmmZleg_baseliner'   r   r   r   r   r&   m  sJ    

  
  

 zHandlerStem.create_artistsc                 C   s(   | | d  || d  dS )zt
        Copy properties from the `.LineCollection` *orig_handle* to the
        `.Line2D` *legend_handle*.
        r   N)rv   Z	get_colorrY   rn   r   r   r   r   r     s    z"HandlerStem._copy_collection_props)r1   NNN)	r,   r-   r.   r/   r   rM   r&   r   rE   r   r   r9   r   r   G  s       /r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )	HandlerTupleal  
    Handler for Tuple.

    Additional kwargs are passed through to `HandlerBase`.

    Parameters
    ----------
    ndivide : int, default: 1
        The number of sections to divide the legend area into. If None,
        use the length of the input tuple.
    pad : float, default: :rc:`legend.borderpad`
        Padding in units of fraction of font size.
    r=   Nc                    s   || _ || _t jf | d S r   )_ndivide_padr2   r   )r   ndividerA   kwargsr9   r   r   r     s    zHandlerTuple.__init__c	                 C   s   |  }	| jd krt|}
n| j}
| jd kr8|j| }n
| j| }|
dkr^|||
d   |
 }t||| t|
  }g }|D ]6}||	|}|	||t
||||||}|| q|S )Nr=   )Zget_legend_handler_mapr   rX   r   Z	borderpadr   r?   ZarangeZget_legend_handlerr&   r   extend)r   r   r   r    r!   r"   r#   r$   r+   Zhandler_mapr   rA   Z	xds_cyclea_listZhandle1handlerZ_a_listr   r   r   r&     s2    



      zHandlerTuple.create_artists)r=   Nra   r   r   r9   r   r     s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )HandlerPolyCollectionza
    Handler for `.PolyCollection` used in `~.Axes.fill_between` and
    `~.Axes.stackplot`.
    c                 C   s   dd }dd }||  |_|| |_| |_| |_|j|_|	||
  |||  |||  ||  d S )Nc                 S   s   | j dkrdS t| d S )Nr   )r   r   r   r   )sizetuple)colorsr   r   r   first_color  s    
z7HandlerPolyCollection._update_prop.<locals>.first_colorc                 S   s   t | r| d S d S d S rt   )rX   )Z
prop_arrayr   r   r   	get_first  s    z5HandlerPolyCollection._update_prop.<locals>.get_first)rl   Z
_facecolorrm   Z
_edgecolorrp   Z_fillrq   Z_hatchZ_hatch_colorrw   ru   rY   Zget_linestylesr]   Zget_transformsr   Z
get_figure)r   r   r   r   r   r   r   r   r     s    

z"HandlerPolyCollection._update_propc	           
      C   s4   t | | f||d}	| |	|| |	| |	gS )Nrd   )r   r   r]   ri   r   r   r   r&     s     
z$HandlerPolyCollection.create_artistsN)r,   r-   r.   r/   r   r&   r   r   r   r   r     s   r   )r/   	itertoolsr   Znumpyr?   Z
matplotlibr   Zmatplotlib.linesr   Zmatplotlib.patchesr   Zmatplotlib.collectionscollectionsr   r   r   r0   rF   rN   rb   rj   rr   rx   r   r   r   r   r   r   r   r   r   r   <module>   s*   Y, 3.- J
k^4