3
ƽhcf                 @   s*  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jZddlj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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|j d }|d k	r$| j| d S )N)nextiterZget_childrenupdate_from)ZtgtsrcZfirst_child r
   ?/tmp/pip-build-7iwl8md4/matplotlib/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 )N)_xpad_ypad_update_prop_func)selfZxpadZypadZupdate_funcr
   r
   r   __init__;   s    zHandlerBase.__init__c             C   s(   | j d kr| j|| n| j || d S )N)r   _default_update_prop)r   legend_handleorig_handler
   r
   r   _update_prop?   s    
zHandlerBase._update_propc             C   s   |j | d S )N)r   )r   r   r   r
   r
   r   r   E   s    z HandlerBase._default_update_propc             C   s.   | j || |j| |jd  |jd  d S )N)r   Z_set_artist_propsset_clip_boxset_clip_path)r   r   r   legendr
   r
   r   update_propH   s    

zHandlerBase.update_propc             C   sD   || j |  }|| j|  }|| j |  }|| j|  }||||fS )N)r   r   )r   r   r   xdescentydescentwidthheightfontsizer
   r
   r   adjust_drawing_areaP   s
    zHandlerBase.adjust_drawing_areac          	   C   sb   | j |||j|j|j|j|\}}}}| j||||||||j }	x|	D ]}
|j|
 qHW |	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_artistY   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               @   s*   e Zd ZdZd
ddZdd Zdd	 ZdS )HandlerNpointszM
    A legend handler that shows *numpoints* points in the legend entry.
    333333?Nc             K   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)r   r   
_numpoints_marker_pad)r   
marker_pad	numpointskwr
   r
   r   r      s    zHandlerNpoints.__init__c             C   s   | j d kr|jS | j S d S )N)r.   r1   )r   r   r
   r
   r   get_numpoints   s    
zHandlerNpoints.get_numpointsc             C   sh   | j |}|dkr@| j| }tj| | | | | |}	|	}
n | | | g}	| d|  g}
|	|
fS )N   g      ?)r3   r/   nplinspace)r   r   r   r   r   r   r    r1   padxdataxdata_markerr
   r
   r   	get_xdata   s    

zHandlerNpoints.get_xdata)r-   N)r(   r)   r*   r+   r   r3   r:   r
   r
   r
   r   r,      s   
r,   c               @   s"   e Zd ZdZdddZdd ZdS )HandlerNpointsYoffsetsz
    A legend handler that shows *numpoints* in the legend, and allows them to
    be individually offset in the y-direction.
    Nc             K   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`.
        r1   N)r,   r   	_yoffsets)r   r1   yoffsetsr2   r
   r
   r   r      s    zHandlerNpointsYoffsets.__init__c             C   s*   | j d kr||j }n|tj| j  }|S )N)r<   _scatteryoffsetsr5   asarray)r   r   r   r   r   r   r    ydatar
   r
   r   	get_ydata   s    
z HandlerNpointsYoffsets.get_ydata)NN)r(   r)   r*   r+   r   rA   r
   r
   r
   r   r;      s   
r;   c               @   s"   e Zd ZdZdddZdd ZdS )	HandlerLine2Dz*
    Handler for `.Line2D` instances.
    333333?Nc             K   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`.
        )r0   r1   N)r,   r   )r   r0   r1   r2   r
   r
   r   r      s    
zHandlerLine2D.__init__c	             C   s   | j ||||||\}	}
tj|	|| d }t|	|}| j||| |jd |jd t|
|d t|
 }| j||| |jd |j	dkr|j
 |j	 }|j| ||_|j| |j| ||gS )N   default Noner4   )r:   r5   	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'   r8   r9   r@   leglinelegline_markernewszr
   r
   r   r"      s"    








zHandlerLine2D.create_artists)rC   N)r(   r)   r*   r+   r   r"   r
   r
   r
   r   rB      s   
rB   c               @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
HandlerPatchz)
    Handler for `.Patch` instances.
    Nc             K   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)r   r   _patch_func)r   
patch_funcr2   r
   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    )rU   r   )	r   r   r   r   r   r   r   r    pr
   r
   r   _create_patch  s    
zHandlerPatch._create_patchc	       
      C   s4   | j |||||||}	| j|	|| |	j| |	gS )N)rY   r   rP   )
r   r   r   r   r   r   r   r    r'   rX   r
   r
   r   r"   )  s
    
zHandlerPatch.create_artists)N)r(   r)   r*   r+   r   rY   r"   r
   r
   r
   r   rT     s   
rT   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 )N)r.   scatterpoints)r   r   r
   r
   r   r3   6  s    
z#HandlerLineCollection.get_numpointsc             C   sD   |j  d }|jd }|j d }|j| |j| |j| d S )Nr   )get_linewidthsZ_us_linestylesZ
get_colors	set_colorrL   set_linewidth)r   r   r   ZlwZdashescolorr
   r
   r   r   <  s    


z*HandlerLineCollection._default_update_propc	             C   sT   | j ||||||\}	}
tj|	|| d }t|	|}| j||| |j| |gS )NrD   )r:   r5   rH   r   r   rP   )r   r   r   r   r   r   r   r    r'   r8   r9   r@   rQ   r
   r
   r   r"   D  s    


z$HandlerLineCollection.create_artistsN)r(   r)   r*   r+   r3   r   r"   r
   r
   r
   r   rZ   2  s   rZ   c               @   sB   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S )HandlerRegularPolyCollectionz'Handler for `.RegularPolyCollection`\s.Nc             K   s    t j| fd|i| || _d S )Nr=   )r;   r   _sizes)r   r=   sizesr2   r
   r
   r   r   U  s    z%HandlerRegularPolyCollection.__init__c             C   s   | j d kr|jS | j S d S )N)r.   r[   )r   r   r
   r
   r   r3   Z  s    
z*HandlerRegularPolyCollection.get_numpointsc             C   s   | j d kr|j }t|s dg}t||jd  }	t||jd  }
| j|}|dk rrd|	|
  |	|
gd | }q|	|
 }|tjdd| |
 }n| j }|S )Nr4   rD      g      ?r   )	ra   	get_sizesrK   maxrM   minr3   r5   r6   )r   r   r   r   r   r   r   r    Zhandle_sizesZsize_maxZsize_minr1   rb   rngr
   r
   r   rd   `  s    

z&HandlerRegularPolyCollection.get_sizesc             C   s0   | j || |j|j |jd  |jd  d S )N)r   
set_figurefigurer   r   )r   r   r   r   r
   r
   r   r   u  s    
z(HandlerRegularPolyCollection.update_propc             C   s"   t ||j |j |||d}|S )N)Zrotationrb   offsetstransOffset)typeZget_numsidesZget_rotation)r   r   rb   rj   rk   rX   r
   r
   r   create_collection~  s    z.HandlerRegularPolyCollection.create_collectionc	             C   sx   | j ||||||\}	}
| j||||||}| j|||||||}| j||tt|
||d}| j||| ||_|gS )N)rj   rk   )r:   rA   rd   rm   listzipr   Z_transOffset)r   r   r   r   r   r   r   r    r'   r8   r9   r@   rb   rX   r
   r
   r   r"     s    



z+HandlerRegularPolyCollection.create_artists)NN)
r(   r)   r*   r+   r   r3   rd   r   rm   r"   r
   r
   r
   r   r`   R  s   
		r`   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 ||j d g|||d}|S )Nr   )rb   rj   rk   )rl   	get_paths)r   r   rb   rj   rk   rX   r
   r
   r   rm     s
    z'HandlerPathCollection.create_collectionN)r(   r)   r*   r+   rm   r
   r
   r
   r   rp     s   rp   c               @   s   e Zd ZdZdd ZdS )HandlerCircleCollectionz"Handler for `.CircleCollection`\s.c             C   s   t ||||d}|S )N)rj   rk   )rl   )r   r   rb   rj   rk   rX   r
   r
   r   rm     s    z)HandlerCircleCollection.create_collectionN)r(   r)   r*   r+   rm   r
   r
   r
   r   rr     s   rr   c               @   s*   e Zd ZdZdddZdd Zd	d
 ZdS )HandlerErrorbarzHandler for Errorbars.      ?N333333?c             K   s(   || _ || _tj| f||d| d S )N)r0   r1   )
_xerr_size
_yerr_sizerB   r   )r   	xerr_size	yerr_sizer0   r1   r2   r
   r
   r   r     s    
zHandlerErrorbar.__init__c       	      C   s,   | j | }| jd kr|}n
| j| }||fS )N)rv   rw   )	r   r   r   r   r   r   r    rx   ry   r
   r
   r   get_err_size  s
    


zHandlerErrorbar.get_err_sizec	                s  |\}	}
}| j ||||||\}}tj||| d }t||}tj|}tj|d t| }| j||||||\ t||}|	d kr|jd |jd n\| j||	| |j	d |j
d | j||	| |jd |jdkr|j |j }|j| g }g }|jr fddt||D }tj|}| j||d | |j| |
rt|  |}t|  |}| j||
d | | j||
d | |j
d	 |j
d	 |j| |j| |jrlfd
dt||D }tj|}| j||d | |j| |
rlt|| }t|| }| j||
d | | j||
d | |j
d |j
d |j| |j| ||||f}x|D ]}|j| qW |S )NrD   FrE   rG   r4   c                s(   g | ] \}}|  |f|  |ffqS r
   r
   ).0xy)rx   r
   r   
<listcomp>  s   z2HandlerErrorbar.create_artists.<locals>.<listcomp>r   |c                s(   g | ] \}}||  f||  ffqS r
   r
   )r{   r|   r}   )ry   r
   r   r~     s   _)r:   r5   rH   r   r?   rK   rz   Zset_visibler   rI   rJ   rL   rM   rN   rO   Zhas_xerrro   mcollLineCollectionappendZhas_yerrrP   )r   r   r   r   r   r   r   r    r'   Z	plotlinesZcaplinesZbarlinecolsr8   r9   r@   rQ   Zydata_markerrR   rS   Zhandle_barlinecolsZhandle_caplinesZvertsZcollZcapline_leftZcapline_rightr#   artistr
   )rx   ry   r   r"     sr    


























zHandlerErrorbar.create_artists)rt   Nru   N)r(   r)   r*   r+   r   rz   r"   r
   r
   r
   r   rs     s
    
rs   c               @   s2   e Zd ZdZdddZdd Zdd	 Zd
d ZdS )HandlerStemz6
    Handler for plots produced by `~.Axes.stem`.
    333333?Nc             K   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`.
        )r0   r1   r=   N)r;   r   _bottom)r   r0   r1   bottomr=   r2   r
   r
   r   r   !  s
    
zHandlerStem.__init__c             C   s2   | j d kr|d|j d  }n|tj| j  }|S )Ng      ?)r<   r>   r5   r?   )r   r   r   r   r   r   r    r@   r
   r
   r   rA   =  s    
zHandlerStem.get_ydatac	                sN  |\}	}
}t |
tj}| j||||||\}}| j||||||}| jd krRd n| j t||d t| }| j||	|  fddt	||D }|rt
j| | jd" x|D ]}| j||
| qW W d Q R X n&x$t	||
D ]\}}| j||| qW ttj|tj|g  g}| j||| |||f}x|D ]}|j| q6W |S )Ng        c                s"   g | ]\}}t ||g |gqS r
   )r   )r{   r|   r}   )r   r
   r   r~   \  s   z.HandlerStem.create_artists.<locals>.<listcomp>)r   )
isinstancer   r   r:   rA   r   r   rK   r   ro   r   Z_setattr_cm_copy_collection_propsr5   rf   re   rP   )r   r   r   r   r   r   r   r    r'   Z
markerlineZ	stemlinesZbaselineZusing_linecollr8   r9   r@   Zleg_markerlineZleg_stemlineslineZlmmZleg_baseliner#   r   r
   )r   r   r"   E  s6    








zHandlerStem.create_artistsc             C   s(   |j |j d  |j|j d  dS )zt
        Copy properties from the `.LineCollection` *orig_handle* to the
        `.Line2D` *legend_handle*.
        r   N)r]   Z	get_colorrL   Zget_linestyle)r   r   r   r
   r
   r   r   t  s    z"HandlerStem._copy_collection_props)r   NNN)r(   r)   r*   r+   r   rA   r"   r   r
   r
   r
   r   r     s    
/r   c               @   s"   e Zd ZdZdddZdd Zd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.
    r4   Nc             K   s   || _ || _tj| f| d S )N)_ndivide_padr   r   )r   ndivider7   kwargsr
   r
   r   r     s    zHandlerTuple.__init__c	          
   C   s   |j  }	| jd krt|}
n| j}
| jd kr8|j| }n
| j| }|
dkr^|||
d   |
 }t||| tj|
  }g }x>|D ]6}|j|	|}|j	||t
||||||}|j| qW |S )Nr4   )Zget_legend_handler_mapr   rK   r   Z	borderpadr   r5   ZarangeZget_legend_handlerr"   r   extend)r   r   r   r   r   r   r   r    r'   Zhandler_mapr   r7   Z	xds_cyclea_listZhandle1handlerZ_a_listr
   r
   r   r"     s$    




zHandlerTuple.create_artists)r4   N)r(   r)   r*   r+   r   r"   r
   r
   r
   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 }t |d|j }|j|| t |d|j }|j|| |j|j  |j|j  |j	||j
  |j||j  |j||j  |j|j  |j|j  d S )Nc             S   s.   | d krd S t j| } t| r&| d S dS d S )Nr   none)mcolorsZto_rgba_arrayrK   )colorsr
   r
   r   first_color  s    
z7HandlerPolyCollection._update_prop.<locals>.first_colorc             S   s   t | r| d S d S d S )Nr   )rK   )Z
prop_arrayr
   r
   r   	get_first  s    z5HandlerPolyCollection._update_prop.<locals>.get_firstZ_original_edgecolorZ_original_facecolor)getattrZget_edgecolorZset_edgecolorZget_facecolorZset_facecolorZset_fillZget_fillZ	set_hatchZ	get_hatchr^   r\   rL   Zget_linestylesrP   Zget_transformsrh   Z
get_figureZ	set_alphaZ	get_alpha)r   r   r   r   r   Z	edgecolorZ	facecolorr
   r
   r   r     s    	

z"HandlerPolyCollection._update_propc	       
      C   s4   t | | f||d}	| j|	|| |	j| |	gS )N)rW   r   r   )r   r   rP   )
r   r   r   r   r   r   r   r    r'   rX   r
   r
   r   r"     s
    

z$HandlerPolyCollection.create_artistsN)r(   r)   r*   r+   r   r"   r
   r
   r
   r   r     s   r   )r+   	itertoolsr   numpyr5   Z
matplotlibr   Zmatplotlib.linesr   Zmatplotlib.patchesr   Zmatplotlib.collectionscollectionsr   Zmatplotlib.colorsr   r   r   r   r,   r;   rB   rT   rZ   r`   rp   rr   rs   r   r   r   r
   r
   r
   r   <module>   s*   

Y, 4. J
l`4