B
    ]”t\? ã               @   s¶  d Z ddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZmZ ddl	mZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZmZmZmZmZmZ e e ¡Z!d,dd„Z"ej#dd„ ƒZ$dd„ Z%dd„ Z&e
 'dgdgdgdgdgdgdgdgdgdgdgdœ¡G dd „ d eƒƒZ(ej)j*e	 +e(¡d! e ,e(j-¡ G d"d#„ d#e(ƒZ.ej)j*e	 +e.¡d$ G d%d&„ d&e/ƒZ0G d'd(„ d(e/ƒZ1G d)d*„ d*e(e1ƒZ2ej)j*e2j-j d+ dS )-z)
Classes for including text in a figure.
é    Né   )ÚartistÚcbookÚ	docstringÚrcParams)ÚArtist)ÚFontProperties)ÚLine2D)ÚFancyArrowPatchÚFancyBboxPatchÚ	Rectangle)ÚTextPath)ÚAffine2DÚBboxÚBboxBaseÚBboxTransformToÚIdentityTransformÚ	Transformc             K   s    |dk	r|   |¡ |   |¡ | S )z@Return an override dict.  See `~pyplot.text' docstring for info.N)Úupdate)ÚoverrideZfontdictÚkwargs© r   ú.lib/python3.7/site-packages/matplotlib/text.pyÚ_process_text_args   s    

r   c          	   c   sB   |   ¡ r8|  ¡ }z|  |  ¡ ¡ | V  W d|  |¡ X n| V  dS )zLTemporarily inserts newlines to the text if the wrap option is enabled.
    N)Úget_wrapÚget_textÚset_textÚ_get_wrapped_text)ÚtextobjZold_textr   r   r   Ú
_wrap_text$   s    
r   c          	   C   s`   yt | ƒd S  ttfk
rZ   t | d¡s4| dkr8dS t | d¡rHdS td | ¡ƒ‚Y nX dS )z“
    Return the text angle as float between 0 and 360 degrees.

    *rotation* may be 'horizontal', 'vertical', or a numeric value in degrees.
    ih  Z
horizontalNg        Zverticalg     €V@zRrotation is {!r}; expected either 'horizontal', 'vertical', numeric value, or None)ÚfloatÚ
ValueErrorÚ	TypeErrorr   Z
_str_equalÚformat)Úrotationr   r   r   Úget_rotation4   s    r%   c             C   sì   g }g }t  |  ¡ ¡}tƒ  | ¡}|  |¡\}}}xd|D ]\\}	}
}}|
\}}| ||f¡\}}||8 }|| ||  }}| ||g¡ | ||g¡ q:W t|ƒt|ƒ }}t	|ƒ| t	|ƒ|  }}tƒ  |¡ ||f¡\}}||||fS )z®
    Calculate the bounding box of the text. Unlike
    :meth:`matplotlib.text.Text.get_extents` method, The bbox size of
    the text before the rotation is calculated.
    )
ÚnpÚdeg2radr%   r   ÚrotateÚ_get_layoutÚtransform_pointÚextendÚminÚmax)ÚtextÚrendererZprojected_xsZprojected_ysÚthetaÚtrÚ_ÚpartsÚdÚtÚwhÚxÚyÚwÚhZxt1Zyt1Zxt2Zyt2Zxt_boxZyt_boxÚw_boxÚh_boxÚx_boxÚy_boxr   r   r   Ú_get_textboxG   s     r?   ZfamilyZfont_propertiesZhaZmaÚnameÚsizeÚstretchZstyleÚvariantZvaÚweight)Z
fontfamilyÚfontpropertiesÚhorizontalalignmentÚmultialignmentÚfontnameÚfontsizeZfontstretchÚ	fontstyleZfontvariantÚverticalalignmentZ
fontweightc                   sR  e Zd ZdZdZe d¡Zdd„ ZdŒdd„Z	‡ fdd„Z
‡ f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d$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Z‡ fd,d-„Zd‡ fd.d/„	Z‡ fd0d1„Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Z d<d=„ Z!e"j#d>d?„ ƒZ$d@dA„ Z%dBdC„ Z&dDdE„ Z'dFdG„ Z(dHdI„ Z)dJdK„ Z*dLdM„ Z+dNdO„ Z,dPdQ„ Z-dRdS„ Z.dTdU„ Z/dVdW„ Z0dŽdXdY„Z1dZd[„ Z2d\d]„ Z3dd^d_„Z4d`da„ Z5dbdc„ Z6ddde„ Z7dfdg„ Z8dhdi„ Z9djdk„ Z:dldm„ Z;dndo„ Z<dpdq„ Z=drds„ Z>dtdu„ Z?dvdw„ Z@dxdy„ ZAdzd{„ ZBd|d}„ ZCd~d„ ZDd€d„ ZEeFdd‚dƒ„ƒZGd„d…„ ZHd†d‡„ ZIdˆd‰„ ZJdŠd‹„ ZK‡  ZLS )‘ÚTextzAHandle storing and drawing of text in window or data coordinates.é   é2   c             C   s   d| j | jt| jƒf S )NzText(%s, %s, %s))Ú_xÚ_yÚreprÚ_text)Úselfr   r   r   Ú__repr__€   s    zText.__repr__r   Ú NÚbaselineÚleftFc             K   sÔ   t  | ¡ || | _| _|dkr(td }|dkr8tƒ }nt|tƒrJt|ƒ}d| _|  	|¡ |  
|¡ |  |¡ |  |¡ |  |¡ |  |¡ || _|	| _|| _d| _d| _|
dkr¶d}
|
| _|  |¡ |  |¡ dS )zv
        Create a `.Text` instance at *x*, *y* with string *text*.

        Valid kwargs are
        %(Text)s
        Nz
text.colorrU   g333333ó?)r   Ú__init__rO   rP   r   r   Ú
isinstanceÚstrrR   r   Ú	set_colorÚ
set_usetexÚset_wrapÚset_verticalalignmentÚset_horizontalalignmentÚ_multialignmentÚ	_rotationÚ_fontpropertiesÚ_bbox_patchÚ	_rendererÚ_linespacingÚset_rotation_moder   )rS   r7   r8   r.   ÚcolorrK   rF   rG   rE   r$   ÚlinespacingÚrotation_modeÚusetexÚwrapr   r   r   r   rX   ƒ   s2    








zText.__init__c                s4   t ƒ }| d|¡}tƒ  |¡ ||k	r0|  |¡ dS )z6
        Update properties from a dictionary.
        ÚbboxN)ÚobjectÚpopÚsuperr   Úset_bbox)rS   r   Úsentinelrl   )Ú	__class__r   r   r   ´   s
    zText.updatec                s   t ƒ  ¡ }d |d< |S )Nrd   )ro   Ú__getstate__)rS   r4   )rr   r   r   rs   ¿   s    
zText.__getstate__c             C   sÄ   t | jƒr|  | |¡S |  ¡ r(| jdkr0di fS |  ¡ j\}}}}|| ||  }}|j|j }}	||  kot|kn  o||	  koŒ|kn  }
i }| jr¼| j 	|¡\}}|
p²|}
||d< |
|fS )zäTest whether the mouse event occurred in the patch.

        In the case of text, a hit is true anywhere in the
        axis-aligned bounding-box containing the text.

        Returns
        -------
        bool : bool
        NFZ
bbox_patch)
ÚcallableZ	_containsÚget_visiblerd   Úget_window_extentÚboundsr7   r8   rc   Úcontains)rS   Z
mouseeventÚlÚbr9   r:   Úrr5   r7   r8   ZinsideZcattrZpatch_insideZpatch_cattrr   r   r   rx   Å   s    

0zText.containsc             C   s   |   ¡ \}}|  ¡  ||f¡S )zW
        Get the (possibly unit converted) transformed x, y in display coords.
        )Úget_unitless_positionÚget_transformr*   )rS   r7   r8   r   r   r   Ú_get_xy_displayå   s    zText._get_xy_displayc             C   s   | j d k	r| j S | jS d S )N)r`   Ú_horizontalalignment)rS   r   r   r   Ú_get_multialignmentì   s    
zText._get_multialignmentc             C   s
   t | jƒS )z*Return the text angle as float in degrees.)r%   ra   )rS   r   r   r   r%   ò   s    zText.get_rotationc             C   s2   |dks|dkr|| _ ntdt|ƒ ƒ‚d| _dS )aW  
        Set text rotation mode.

        Parameters
        ----------
        m : {None, 'default', 'anchor'}
            If ``None`` or ``"default"``, the text will be first rotated, then
            aligned according to their horizontal and vertical alignments.  If
            ``"anchor"``, then alignment occurs before rotation.
        N)ÚanchorÚdefaultzUnknown rotation_mode : %sT)Ú_rotation_moder!   rQ   Ústale)rS   Úmr   r   r   rf   ö   s    zText.set_rotation_modec             C   s   | j S )zGet the text rotation mode.)rƒ   )rS   r   r   r   Úget_rotation_mode  s    zText.get_rotation_modec             C   sZ   t  | |¡ |j| _|j| _|j| _|j| _|j ¡ | _|j| _|j	| _	|j
| _
d| _dS )z#Copy properties from other to self.TN)r   Úupdate_fromÚ_colorr`   Ú_verticalalignmentr   rb   Úcopyra   Z_pickerre   r„   )rS   Úotherr   r   r   r‡     s    zText.update_fromc       /      C   sÈ  | j |d}|| jkr | j| S g }d\}}d\}}d\}}	|  ¡  d¡}
t t|
ƒdf¡}t t|
ƒdf¡}|jd| jdd\}}}|| | j	 }d	}xºt
|
ƒD ]®\}}|  ||  ¡ ¡\}}|rÜ|j|| j|d\}}}n
d
\}}}t||ƒ}t||ƒ}||f||< || | }|t||| | j	 ƒ8 }||||f||< ||8 }t||ƒ}|}q¢W |d d }|d	 d |d	 d  }|| }	|| }tƒ  |  ¡ ¡}t t|
ƒdf¡}|dd…d	d…f |dd…< t|
ƒdkrJ|  ¡ }|dkr|dd…d	f  |d |dd…df d  7  < n2|dkrJ|dd…d	f  ||dd…df  7  < t ||f||f||f||fgt¡}|dd…df  |8  < | |¡}|dd…d	f } |dd…df }!|  ¡ |  ¡  }}|! ¡ |! ¡  }}|| }|| }	| j}"| j}#|  ¡ }$|$dkr˜|"dkr||d  }%n|"dkr.|| }%n|}%|#dkrJ||	d  }nL|#dkr^||	 }n8|#dkrv||	 | }n |#dkr’||	 |d  }n|}n²|d	 \}&}'|d \}(})|"dkrÈ|&|( d }%n|"dkrØ|(}%n|&}%|#dkrô|'|) d }nD|#dkr|)}n4|#dkr|)| }n |#dkr4|'|) | d }n|'}| |%|f¡\}%}||%8 }||8 }t ||||	¡}*| |¡}+|+|%|f8 }+|+dd…d	f |+dd…df  },}-|*tt|
||,|-ƒƒ|f}.|.| j|< |.S )zµ
        return the extent (bbox) of the text together with
        multiple-alignment information. Note that it returns an extent
        of a rotated text when necessary.
        )r/   )g        g        Ú
é   é   ZlpF)Úismathr   )r   r   r   éÿÿÿÿr   rM   NÚcenterg       @Úrightr   ÚtoprV   Úcenter_baseline)Úget_prop_tupÚ_cachedr   Úsplitr&   ZzerosÚlenÚget_text_width_height_descentrb   re   Ú	enumerateÚis_math_textÚ
get_usetexr-   r   Z
rotate_degr%   r€   Úarrayr    Ú	transformr,   r   r‰   r†   r*   r   Úfrom_boundsÚlistÚzip)/rS   r/   ÚkeyZhorizLayoutZthisxZthisyZxminZyminÚwidthÚheightÚlinesZwhsZtmpZlp_hZlp_blZoffsetyrV   ÚiÚlineÚ
clean_liner   r9   r:   r4   ÚdescentZymaxZxmaxÚMZoffsetLayoutZmalignZcornersHorizZcornersRotatedZtxsZtysZhalignZvalignri   ZoffsetxZxmin1Zymin1Zxmax1Zymax1rl   ZxysZxsZysZretr   r   r   r)     sÄ    






2
( 

















"
zText._get_layoutc             C   s²   |dk	r |  ¡ }| dd¡}| dd¡}|dkrNd}|dkr@d}||  ¡  }n|dkrZd}t|tƒrxd|krx|d| 7 }| dd¡}td||tƒ dœ|—Ž| _nd| _|  ¡  dS )a  
        Draw a bounding box around self.

        Parameters
        ----------
        rectprops : dict with properties for `.patches.FancyBboxPatch`
             The default boxstyle is 'square'. The mutation
             scale of the `.patches.FancyBboxPatch` is set to the fontsize.

        Examples
        --------
        ::

            t.set_bbox(dict(facecolor='red', alpha=0.5))
        NÚboxstyleÚpadZsquarerŽ   g333333Ó?z
,pad=%0.2fÚbbox_transmuter©g        g        ç      ð?)r«   r­   rž   )r®   r¯   r¯   )	rŠ   rn   Úget_sizerY   rZ   r   r   rc   Ú_update_clip_properties)rS   Z	rectpropsÚpropsr«   r¬   r­   r   r   r   rp   ±  s.     zText.set_bboxc             C   s   | j S )zf
        Return the bbox Patch, or None if the `.patches.FancyBboxPatch`
        is not made.
        )rc   )rS   r   r   r   Úget_bbox_patchá  s    zText.get_bbox_patchc             C   s¼   | j r¸|  ¡ }t|  | j¡ƒ}t|  | j¡ƒ}| ||f¡\}}t| |ƒ\}}}}| j  	dd||¡ t
 |  ¡ ¡}	tƒ  |	¡}
|
 || || ¡}
| j  |
¡ | |  ¡ ¡}| j  |¡ dS )zÈ
        Update the location and the size of the bbox.

        This method should be used when the position and size of the bbox needs
        to be updated before actually drawing the bbox.
        g        N)rc   r}   r    Úconvert_xunitsrO   Úconvert_yunitsrP   r*   r?   Ú
set_boundsr&   r'   r%   r   r(   Ú	translateÚset_transformÚpoints_to_pixelsr°   Úset_mutation_scale)rS   r/   ÚtransÚposxÚposyr=   r>   r;   r<   r0   r1   Úfontsize_in_pixelr   r   r   Úupdate_bbox_position_sizeè  s    zText.update_bbox_position_sizec             C   sˆ   t | |ƒ\}}}}| j dd||¡ t |  ¡ ¡}tƒ  |¡}	|	 || || ¡}	| j 	|	¡ | 
|  ¡ ¡}
| j |
¡ | j |¡ dS )zi
        Update the location and size of the bbox (`.patches.FancyBboxPatch`),
        and draw.
        g        N)r?   rc   r¶   r&   r'   r%   r   r(   r·   r¸   r¹   r°   rº   Údraw)rS   r/   r¼   r½   r=   r>   r;   r<   r0   r1   r¾   r   r   r   Ú
_draw_bbox  s    zText._draw_bboxc             C   s*   t | j| j| jd}| jr&| j |¡}d S )N)Zclip_boxZ	clip_pathZclip_on)ÚdictÚclipboxZ	_clippathZ_cliponrc   r   )rS   Z	clippropsrl   r   r   r   r±     s
    
zText._update_clip_propertiesc                s   t ƒ  |¡ |  ¡  dS )z’
        Set the artist's clip `~.transforms.Bbox`.

        Parameters
        ----------
        clipbox : `matplotlib.transforms.Bbox`
        N)ro   Úset_clip_boxr±   )rS   rÃ   )rr   r   r   rÄ     s    zText.set_clip_boxc                s   t ƒ  ||¡ |  ¡  dS )aÍ  
        Set the artist's clip path, which may be:

          * a `~matplotlib.patches.Patch` (or subclass) instance

          * a `~matplotlib.path.Path` instance, in which case
             an optional `~matplotlib.transforms.Transform`
             instance may be provided, which will be applied to the
             path before using it for clipping.

          * *None*, to remove the clipping path

        For efficiency, if the path happens to be an axis-aligned
        rectangle, this method will set the clipping box to the
        corresponding rectangle and set the clipping path to *None*.

        ACCEPTS: { (`.path.Path`, `.transforms.Transform`),
                  `.patches.Patch`, None }
        N)ro   Úset_clip_pathr±   )rS   Úpathrž   )rr   r   r   rÅ   &  s    zText.set_clip_pathc                s   t ƒ  |¡ |  ¡  dS )zÛ
        Set whether artist uses clipping.

        When False, artists will be visible outside of the axes, which can lead
        to unexpected results.

        Parameters
        ----------
        b : bool
        N)ro   Úset_clip_onr±   )rS   rz   )rr   r   r   rÇ   =  s    zText.set_clip_onc             C   s   | j S )z'Return the wrapping state for the text.)Ú_wrap)rS   r   r   r   r   K  s    zText.get_wrapc             C   s
   || _ dS )zhSet the wrapping state for the text.

        Parameters
        ----------
        wrap : bool
        N)rÈ   )rS   rk   r   r   r   r]   O  s    zText.set_wrapc       	      C   s’   |   ¡  |  ¡ ¡\}}|  ¡  ¡ }|  ¡ }|  d¡ |  ¡ }|  ||||¡}|  d| d |||¡}|dkrr|}n|dkr€|}ndt	||ƒ }|S )zk
        Return the maximum line width for wrapping text based on the current
        orientation.
        r   é´   ih  rW   r’   r   )
r}   rž   Úget_positionÚ
get_figurerv   Úget_horizontalalignmentrf   r%   Ú_get_dist_to_boxr,   )	rS   Úx0Úy0Ú
figure_boxZ	alignmentr$   rW   r’   Ú
line_widthr   r   r   Ú_get_wrap_line_widthX  s    
zText._get_wrap_line_widthc             C   s  |dkrD|d }|t  t  |¡¡ }|j| t  t  d| ¡¡ }nº|dkr‚|d }|t  t  |¡¡ }|t  t  d| ¡¡ }n||dkrÆ|d }|j| t  t  |¡¡ }|t  t  d| ¡¡ }n8|j| t  t  |¡¡ }|j| t  t  d| ¡¡ }t||ƒS )zr
        Return the distance from the given points to the boundaries of a
        rotated box, in pixels.
        i  éZ   rÉ   )ÚmathÚcosZradiansÚx1Úy1r,   )rS   r$   rÎ   rÏ   rÐ   ZquadZh1Zh2r   r   r   rÍ   r  s     zText._get_dist_to_boxc             C   s$   | j  ||  ¡ d¡\}}}t |¡S )zE
        Return the width of a given text string, in pixels.
        F)rd   r™   Úget_fontpropertiesrÔ   Zceil)rS   r.   r9   r:   r4   r   r   r   Ú_get_rendered_text_width‰  s
    zText._get_rendered_text_widthc             C   s¸   |   ¡ r|  ¡ S |  ¡ }d}d}xŽ|  ¡  d¡D ]|}| d¡}xltt|ƒƒD ]\}|  |d ||  ¡}||ksv|dkr†||d 7 }d}|dkr˜|| }qL|d||  7 }qLW q0W || S )z„
        Return a copy of the text with new lines added, so that
        the text is wrapped relative to the parent figure.
        rU   ú rŒ   r   )rœ   r   rÒ   r—   Úranger˜   rÙ   )rS   rÑ   Zwrapped_strr§   ZwordZ	sub_wordsr¦   Zcurrent_widthr   r   r   r   “  s"    

zText._get_wrapped_textc             C   s
  |dk	r|| _ |  ¡ sdS |  ¡ dkr*dS | d|  ¡ ¡ t| ƒ¤}| |¡\}}}| ¡ }t| 	|j
¡ƒ}t| |j¡ƒ}| ||f¡\}}t |¡r¤t |¡s²t d¡ dS | ¡ \}	}
|jrÒ| |||¡ | ¡ }| | ¡ ¡ | | ¡ ¡ | |j¡ | |¡ | ¡ }xÎ|D ]Æ\}}}}t|ƒdkr8|nd}|| }|| }| ¡ r^|
| }|  ||  !¡ ¡\}}| "¡ r˜ddl#m$} || "¡ |ƒ}n|}| !¡ rÂ|j%|||||j&||d n|j'|||||j&|||d	 qW W dQ R X | (¡  | )d¡ d
| _*dS )zC
        Draws the `.Text` object to the given *renderer*.
        NrU   r.   z%posx and posy should be finite valuesr   r   )ÚPathEffectRenderer)Úmtext)r   rÝ   F)+rd   ru   r   Z
open_groupZget_gidr   r)   r}   r    r´   rO   rµ   rP   r*   r&   ZisfiniteÚ_logZwarningZget_canvas_width_heightrc   rÁ   Znew_gcZset_foregroundÚ	get_colorZ	set_alphaZ	get_alphaZset_urlZ_urlZ_set_gc_clipr%   r˜   Zflipyr›   rœ   Zget_path_effectsZmatplotlib.patheffectsrÜ   Zdraw_texrb   Z	draw_textZrestoreZclose_groupr„   )rS   r/   r   rl   Úinfor©   r»   r¼   r½   ZcanvaswZcanvashÚgcÚangler§   r6   r7   r8   rÝ   r¨   r   rÜ   Ztextrendererr   r   r   rÀ   ¶  s`    






z	Text.drawc             C   s   | j S )zReturn the color of the text)rˆ   )rS   r   r   r   rß   ü  s    zText.get_colorc             C   s   | j S )z0Return the `.font_manager.FontProperties` object)rb   )rS   r   r   r   rØ      s    zText.get_fontpropertiesc             C   s
   | j  ¡ S )zš
        Return the list of font families used for font lookup

        See Also
        --------
        .font_manager.FontProperties.get_family
        )rb   Z
get_family)rS   r   r   r   Úget_fontfamily  s    zText.get_fontfamilyc             C   s
   | j  ¡ S )z
        Return the font name as string

        See Also
        --------
        .font_manager.FontProperties.get_name
        )rb   Zget_name)rS   r   r   r   Úget_fontname  s    zText.get_fontnamec             C   s
   | j  ¡ S )zƒ
        Return the font style as string

        See Also
        --------
        .font_manager.FontProperties.get_style
        )rb   Z	get_style)rS   r   r   r   Úget_fontstyle  s    zText.get_fontstylec             C   s
   | j  ¡ S )zŒ
        Return the font size as integer

        See Also
        --------
        .font_manager.FontProperties.get_size_in_points
        )rb   Zget_size_in_points)rS   r   r   r   Úget_fontsize"  s    zText.get_fontsizec             C   s
   | j  ¡ S )z‰
        Return the font variant as a string

        See Also
        --------
        .font_manager.FontProperties.get_variant
        )rb   Zget_variant)rS   r   r   r   Úget_fontvariant,  s    zText.get_fontvariantc             C   s
   | j  ¡ S )zŒ
        Get the font weight as string or number

        See Also
        --------
        .font_manager.FontProperties.get_weight
        )rb   Z
get_weight)rS   r   r   r   Úget_fontweight6  s    zText.get_fontweightc             C   s
   | j  ¡ S )z
        Get the font stretch as a string or number

        See Also
        --------
        .font_manager.FontProperties.get_stretch
        )rb   Úget_stretch)rS   r   r   r   ré   @  s    zText.get_stretchc             C   s   | j S )zq
        Return the horizontal alignment as string.  Will be one of
        'left', 'center' or 'right'.
        )r   )rS   r   r   r   rÌ   J  s    zText.get_horizontalalignmentc             C   s(   t |  | j¡ƒ}t |  | j¡ƒ}||fS )z>Return the unitless position of the text as a tuple (*x*, *y*))r    r´   rO   rµ   rP   )rS   r7   r8   r   r   r   r|   Q  s    zText.get_unitless_positionc             C   s   | j | jfS )z5Return the position of the text as a tuple (*x*, *y*))rO   rP   )rS   r   r   r   rÊ   Y  s    zText.get_positionc             C   sR   |   ¡ \}}|p| j}|||  ¡ | j| j| jt| jƒ| j| j	| j
jt |¡| jfS )z÷
        Return a hashable tuple of properties.

        Not intended to be human readable, but useful for backends who
        want to cache derived information about text (e.g., layouts) and
        need to know if the text has changed.
        )r|   rd   r   rˆ   r‰   r   Úhashrb   ra   rƒ   ÚfigureÚdpiÚweakrefÚrefre   )rS   r/   r7   r8   r   r   r   r•   _  s    
zText.get_prop_tupc             C   s   | j S )zGet the text as string)rR   )rS   r   r   r   r   q  s    zText.get_textc             C   s   | j S )z{
        Return the vertical alignment as string.  Will be one of
        'top', 'center', 'bottom' or 'baseline'.
        )r‰   )rS   r   r   r   Úget_verticalalignmentu  s    zText.get_verticalalignmentc             C   sØ   |   ¡ st ¡ S |dk	r(| jj}|| j_|  ¡ dkrP|  ¡ \}}t ||dd¡S |dk	r^|| _| jdkrr| jj	| _| jdkr„t
dƒ‚|  | j¡\}}}|  ¡ \}	}
|  ¡  |	|
f¡\}	}
| |	|
¡}|dk	rÔ|| j_|S )a€  
        Return the `Bbox` bounding the text, in display units.

        In addition to being used internally, this is useful for specifying
        clickable regions in a png file on a web page.

        Parameters
        ----------
        renderer : Renderer, optional
            A renderer is needed to compute the bounding box.  If the artist
            has already been drawn, the renderer is cached; thus, it is only
            necessary to pass this argument when calling `get_window_extent`
            before the first `draw`.  In practice, it is usually easier to
            trigger a draw first (e.g. by saving the figure).

        dpi : float, optional
            The dpi value for computing the bbox, defaults to
            ``self.figure.dpi`` (*not* the renderer dpi); should be set e.g. if
            to match regions with a figure saved with a custom dpi value.
        NrU   r   z%Cannot get window extent w/o renderer)ru   r   Úunitrë   rì   r   r~   rŸ   rd   Ú_cachedRendererÚRuntimeErrorr)   r|   r}   r*   Z
translated)rS   r/   rì   Zdpi_origZtxZtyrl   rà   r©   r7   r8   r   r   r   rv   |  s*    


zText.get_window_extentc             C   sB   | j dkr|  t||d¡ n| j  t|d¡ |  ¡  d| _dS )zë
        Set the background color of the text by updating the bbox.

        Parameters
        ----------
        color : color

        See Also
        --------
        .set_bbox : To change the position of the bounding box
        N)Ú	facecolorZ	edgecolor)ró   T)rc   rp   rÂ   r   r±   r„   )rS   rg   r   r   r   Úset_backgroundcolorª  s
    
zText.set_backgroundcolorc             C   s:   yt |ƒ W n tk
r(   t|ƒ}Y nX || _d| _dS )zs
        Set the foreground color of the text

        Parameters
        ----------
        color : color
        TN)rê   r"   Útuplerˆ   r„   )rS   rg   r   r   r   r[   ¾  s    	zText.set_colorc             C   s,   d}||krt dt|ƒ ƒ‚|| _d| _dS )z‹
        Set the horizontal alignment to one of

        Parameters
        ----------
        align : {'center', 'right', 'left'}
        )r‘   r’   rW   z&Horizontal alignment must be one of %sTN)r!   rZ   r   r„   )rS   ÚalignÚlegalr   r   r   r_   Î  s    zText.set_horizontalalignmentc             C   s,   d}||krt dt|ƒ ƒ‚|| _d| _dS )aS  
        Set the alignment for multiple lines layout.  The layout of the
        bounding box of all the lines is determined bu the horizontalalignment
        and verticalalignment properties, but the multiline text within that
        box can be

        Parameters
        ----------
        align : {'left', 'right', 'center'}
        )r‘   r’   rW   z&Horizontal alignment must be one of %sTN)r!   rZ   r`   r„   )rS   rö   r÷   r   r   r   Úset_multialignmentÝ  s    zText.set_multialignmentc             C   s   || _ d| _dS )zµ
        Set the line spacing as a multiple of the font size.
        Default is 1.2.

        Parameters
        ----------
        spacing : float (multiple of font size)
        TN)re   r„   )rS   Zspacingr   r   r   Úset_linespacingï  s    	zText.set_linespacingc             C   s   | j  |¡ d| _dS )a   
        Set the font family.  May be either a single string, or a list of
        strings in decreasing priority.  Each string may be either a real font
        name or a generic font class name.  If the latter, the specific font
        names will be looked up in the corresponding rcParams.

        Parameters
        ----------
        fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'}

        See Also
        --------
        .font_manager.FontProperties.set_family
        TN)rb   Ú
set_familyr„   )rS   rH   r   r   r   Úset_fontfamilyû  s    zText.set_fontfamilyc             C   s   | j  |¡ d| _dS )zî
        Set the font variant, either 'normal' or 'small-caps'.

        Parameters
        ----------
        variant : {'normal', 'small-caps'}

        See Also
        --------
        .font_manager.FontProperties.set_variant
        TN)rb   Zset_variantr„   )rS   rC   r   r   r   Úset_fontvariant  s    zText.set_fontvariantc             C   s   | j  |¡ d| _dS )zÒ
        Set the font style.

        Parameters
        ----------
        fontstyle : {'normal', 'italic', 'oblique'}

        See Also
        --------
        .font_manager.FontProperties.set_style
        TN)rb   Z	set_styler„   )rS   rJ   r   r   r   Úset_fontstyle  s    zText.set_fontstylec             C   s   | j  |¡ d| _dS )aw  
        Set the font size.  May be either a size string, relative to
        the default font size, or an absolute font size in points.

        Parameters
        ----------
        fontsize : {size in points, 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'}

        See Also
        --------
        .font_manager.FontProperties.set_size
        TN)rb   Zset_sizer„   )rS   rI   r   r   r   Úset_fontsize,  s    zText.set_fontsizec             C   s   | j  |¡ d| _dS )ab  
        Set the font weight.

        Parameters
        ----------
        weight : {a numeric value in range 0-1000, 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black'}

        See Also
        --------
        .font_manager.FontProperties.set_weight
        TN)rb   Z
set_weightr„   )rS   rD   r   r   r   Úset_fontweight=  s    zText.set_fontweightc             C   s   | j  |¡ d| _dS )a  
        Set the font stretch (horizontal condensation or expansion).

        Parameters
        ----------
        stretch : {a numeric value in range 0-1000, 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded'}

        See Also
        --------
        .font_manager.FontProperties.set_stretch
        TN)rb   Zset_stretchr„   )rS   rB   r   r   r   Úset_fontstretchN  s    zText.set_fontstretchc             C   s    |   |d ¡ |  |d ¡ dS )z}
        Set the (*x*, *y*) position of the text.

        Parameters
        ----------
        xy : (float, float)
        r   r   N)Úset_xÚset_y)rS   Úxyr   r   r   Úset_position_  s    zText.set_positionc             C   s   || _ d| _dS )zl
        Set the *x* position of the text.

        Parameters
        ----------
        x : float
        TN)rO   r„   )rS   r7   r   r   r   r  j  s    z
Text.set_xc             C   s   || _ d| _dS )zl
        Set the *y* position of the text.

        Parameters
        ----------
        y : float
        TN)rP   r„   )rS   r8   r   r   r   r  u  s    z
Text.set_yc             C   s   || _ d| _dS )z
        Set the rotation of the text.

        Parameters
        ----------
        s : {angle in degrees, 'vertical', 'horizontal'}
        TN)ra   r„   )rS   Úsr   r   r   Úset_rotation€  s    zText.set_rotationc             C   s,   d}||krt dt|ƒ ƒ‚|| _d| _dS )zž
        Set the vertical alignment

        Parameters
        ----------
        align : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
        )r“   Zbottomr‘   rV   r”   z$Vertical alignment must be one of %sTN)r!   rZ   r‰   r„   )rS   rö   r÷   r   r   r   r^   ‹  s    zText.set_verticalalignmentc             C   s,   |dkrd}|| j kr(d|f | _ d| _dS )zâ
        Set the text string *s*.

        It may contain newlines (``\n``) or math in LaTeX syntax.

        Parameters
        ----------
        s : string or object castable to string (but ``None`` becomes ``''``)
        NrU   z%sT)rR   r„   )rS   r  r   r   r   r   ›  s
    

zText.set_textc             C   sN   |dkrt d }|r(| dkr d} | dfS t | ¡r:| dfS |  dd¡d	fS dS )
aS  
        Returns a cleaned string and a boolean flag.
        The flag indicates if the given string *s* contains any mathtext,
        determined by counting unescaped dollar signs. If no mathtext
        is present, the cleaned string has its dollar signs unescaped.
        If usetex is on, the flag always has the value "TeX".
        Nztext.usetexrÚ   z\ ZTeXTz\$ú$F)r   r   r›   Úreplace)r  rj   r   r   r   r›   «  s    
zText.is_math_textc             C   s&   t |tƒrt|ƒ}| ¡ | _d| _dS )z“
        Set the font properties that control the text.

        Parameters
        ----------
        fp : `.font_manager.FontProperties`
        TN)rY   rZ   r   rŠ   rb   r„   )rS   Úfpr   r   r   Úset_fontpropertiesÂ  s    

zText.set_fontpropertiesc             C   s(   |dkrt d | _n
t|ƒ| _d| _dS )z«
        Parameters
        ----------
        usetex : bool or None
            Whether to render using TeX, ``None`` means to use
            :rc:`text.usetex`.
        Nztext.usetexT)r   Ú_usetexÚboolr„   )rS   rj   r   r   r   r\   Ï  s    
zText.set_usetexc             C   s   | j dkrtd S | j S dS )z«
        Return whether this `Text` object uses TeX for rendering.

        If the user has not manually set this value, it defaults to
        :rc:`text.usetex`.
        Nztext.usetex)r  r   )rS   r   r   r   rœ   Ý  s    
zText.get_usetexc             C   s
   |   |¡S )a-  
        alias for `.set_family`

        One-way alias only: the getter differs.

        Parameters
        ----------
        fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'}

        See Also
        --------
        .font_manager.FontProperties.set_family

        )rú   )rS   rH   r   r   r   Úset_fontnameé  s    zText.set_fontname)r   r   rU   NrV   rW   NNNNNNF)N)N)NN)N)MÚ__name__Ú
__module__Ú__qualname__Ú__doc__Zzorderr   Úmaxdictr–   rT   rX   r   rs   rx   r~   r€   r%   rf   r†   r‡   r)   rp   r³   r¿   rÁ   r±   rÄ   rÅ   rÇ   r   r]   rÒ   rÍ   rÙ   r   r   Úallow_rasterizationrÀ   rß   rØ   rã   rä   rå   ræ   rç   rè   ré   rÌ   r|   rÊ   r•   r   rï   rv   rô   r[   r_   rø   rù   rû   rü   rý   rþ   rÿ   r   r  r  r  r  r^   r   Ústaticmethodr›   r
  r\   rœ   r  Ú__classcell__r   r   )rr   r   rL   m   s    
          
&  0	
#F








.rL   )rL   c               @   sÚ   e Zd ZdZdZ dd„ Zd9dd„Zdd„ Zdd„ Zd:dd„Zdd„ Z	d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%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ ZdS )<ÚTextWithDashab  
    This is basically a :class:`~matplotlib.text.Text` with a dash
    (drawn with a :class:`~matplotlib.lines.Line2D`) before/after
    it. It is intended to be a drop-in replacement for
    :class:`~matplotlib.text.Text`, and should behave identically to
    it when *dashlength* = 0.0.

    The dash always comes between the point specified by
    :meth:`~matplotlib.text.Text.set_position` and the text. When a
    dash exists, the text alignment arguments (*horizontalalignment*,
    *verticalalignment*) are ignored.

    *dashlength* is the length of the dash in canvas units.
    (default = 0.0).

    *dashdirection* is one of 0 or 1, where 0 draws the dash after the
    text and 1 before.  (default = 0).

    *dashrotation* specifies the rotation of the dash, and should
    generally stay *None*. In this case
    :meth:`~matplotlib.text.TextWithDash.get_dashrotation` returns
    :meth:`~matplotlib.text.Text.get_rotation`.  (i.e., the dash takes
    its rotation from the text's rotation). Because the text center is
    projected onto the dash, major deviations in the rotation cause
    what may be considered visually unappealing results.
    (default = *None*)

    *dashpad* is a padding length to add (or subtract) space
    between the text and the dash, in canvas units.
    (default = 3)

    *dashpush* "pushes" the dash and text away from the point
    specified by :meth:`~matplotlib.text.Text.set_position` by the
    amount in canvas units.  (default = 0)

    .. note::

        The alignment of the two objects is based on the bounding box
        of the :class:`~matplotlib.text.Text`, as obtained by
        :meth:`~matplotlib.artist.Artist.get_window_extent`.  This, in
        turn, appears to depend on the font metrics as given by the
        rendering backend. Hence the quality of the "centering" of the
        label text with respect to the dash varies depending on the
        backend used.

    .. note::

        I'm not sure that I got the
        :meth:`~matplotlib.text.TextWithDash.get_window_extent` right,
        or whether that's sufficient for providing the object bounding
        box.

    Ztextwithdashc             C   s   d| j | j| jf S )NzTextWithDash(%g, %g, %r))rO   rP   rR   )rS   r   r   r   Ú__str__8  s    zTextWithDash.__str__r   rU   Nr‘   ç        rM   c             C   sp   t j| |||||||||	|
d t||f||fddd| _t|ƒ| _t|ƒ| _|| _|| _|| _	|| _
|| _d S )N)
r7   r8   r.   rg   rK   rF   rG   rE   r$   rh   Úkú-)ZxdataZydatarg   Z	linestyle)rL   rX   r	   Údashliner    Ú_dashxÚ_dashyÚ_dashlengthÚ_dashdirectionÚ_dashrotationÚ_dashpadÚ	_dashpush)rS   r7   r8   r.   rg   rK   rF   rG   rE   r$   rh   Ú
dashlengthÚdashdirectionÚdashrotationÚdashpadÚdashpushr   r   r   rX   ;  s$    


zTextWithDash.__init__c             C   s(   t |  | j¡ƒ}t |  | j¡ƒ}||fS )z>Return the unitless position of the text as a tuple (*x*, *y*))r    r´   r  rµ   r  )rS   r7   r8   r   r   r   r|   f  s    z"TextWithDash.get_unitless_positionc             C   s   | j | jfS )z5Return the position of the text as a tuple (*x*, *y*))r  r  )rS   r   r   r   rÊ   n  s    zTextWithDash.get_positionc          	   C   sF   dd„ t j| |dD ƒ}| | j| j| j| j| j| j| j	g¡ t
|ƒS )z÷
        Return a hashable tuple of properties.

        Not intended to be human readable, but useful for backends who
        want to cache derived information about text (e.g., layouts) and
        need to know if the text has changed.
        c             S   s   g | ]}|‘qS r   r   )Ú.0Úpr   r   r   ú
<listcomp>|  s    z-TextWithDash.get_prop_tup.<locals>.<listcomp>)r/   )rL   r•   r+   rO   rP   r  r  r   r!  r"  rõ   )rS   r/   r²   r   r   r   r•   t  s
    
zTextWithDash.get_prop_tupc             C   s8   |   |¡ t | |¡ |  ¡ dkr.| j |¡ d| _dS )zP
        Draw the :class:`TextWithDash` object to the given *renderer*.
        g        FN)Úupdate_coordsrL   rÀ   Úget_dashlengthr  r„   )rS   r/   r   r   r   rÀ   ‚  s
    
zTextWithDash.drawc       !   	   C   s,  |   ¡ \}}|  ¡ }|dkr.|| | _| _dS |  ¡ }|  ¡ }|  ¡ }|  ¡ }t|ƒ}	t	j
|	d | d  }
t	 |
¡t	 |
¡ }}|  ¡ }| ||f¡}t	 ||g¡}|||  }||| |  }| ¡ }| t|ƒ¡\}}| t|ƒ¡\}}| j ||f||f¡ tj| |d}|j|j }}|dkr4|}d}nJ|dkrHd}|}n6|| }|}|| }||ksr|| k r~|}|| }t	 ||g¡d }|d|t	 t	 ||¡¡  9 }||d d |  }| t|ƒ¡\}} ||  | _| _tj| |d}| ¡ | _| j t	 |g¡d¡ t | d¡ t | d¡ dS )	zò
        Computes the actual *x*, *y* coordinates for text based on the
        input *x*, *y* and the *dashlength*. Since the rotation is
        with respect to the actual canvas's coordinates we need to map
        back and forth.
        g        Ng     €f@r   )r/   r   Fr‘   )r|   r,  rO   rP   Úget_dashrotationÚget_dashdirectionÚget_dashpadÚget_dashpushr%   r&   ZpirÕ   Zsinr}   r*   r   Úinvertedrõ   r  Úset_datarL   rv   r£   r¤   ZsqrtÚdotÚfrozenÚ_twd_window_extentZupdate_from_data_xyr_   r^   )!rS   r/   ZdashxZdashyr#  r%  r$  r&  r'  râ   r0   Z	cos_thetaZ	sin_thetarž   ZcxyZcdZc1Zc2ZinverserÖ   r×   Úx2Úy2Zwer9   r:   ZdxZdyZ	tan_thetaÚcwdZcwZnewxZnewyr   r   r   r+  Œ  sZ    


zTextWithDash.update_coordsc             C   s.   |   |¡ |  ¡ dkr$tj| |dS | jS dS )ao  
        Return a :class:`~matplotlib.transforms.Bbox` object bounding
        the text, in display units.

        In addition to being used internally, this is useful for
        specifying clickable regions in a png file on a web page.

        *renderer* defaults to the _renderer attribute of the text
        object.  This is not assigned until the first execution of
        :meth:`draw`, so you must use this kwarg if you want
        to call :meth:`get_window_extent` prior to the first
        :meth:`draw`.  For getting web page regions, it is
        simpler to call the method after saving the figure.
        g        )r/   N)r+  r,  rL   rv   r5  )rS   r/   r   r   r   rv   à  s    
zTextWithDash.get_window_extentc             C   s   | j S )z-
        Get the length of the dash.
        )r  )rS   r   r   r   r,  õ  s    zTextWithDash.get_dashlengthc             C   s   || _ d| _dS )zx
        Set the length of the dash, in canvas units.

        Parameters
        ----------
        dl : float
        TN)r  r„   )rS   Zdlr   r   r   Úset_dashlengthû  s    zTextWithDash.set_dashlengthc             C   s   | j S )zO
        Get the direction dash.  1 is before the text and 0 is after.
        )r  )rS   r   r   r   r.    s    zTextWithDash.get_dashdirectionc             C   s   || _ d| _dS )a9  
        Set the direction of the dash following the text.  1 is before the text
        and 0 is after. The default is 0, which is what you'd want for the
        typical case of ticks below and on the left of the figure.

        Parameters
        ----------
        dd : int (1 is before, 0 is after)
        TN)r  r„   )rS   Zddr   r   r   Úset_dashdirection  s    
zTextWithDash.set_dashdirectionc             C   s   | j dkr|  ¡ S | j S dS )z:
        Get the rotation of the dash in degrees.
        N)r   r%   )rS   r   r   r   r-    s    
zTextWithDash.get_dashrotationc             C   s   || _ d| _dS )zu
        Set the rotation of the dash, in degrees.

        Parameters
        ----------
        dr : float
        TN)r   r„   )rS   Zdrr   r   r   Úset_dashrotation"  s    zTextWithDash.set_dashrotationc             C   s   | j S )zW
        Get the extra spacing between the dash and the text, in canvas units.
        )r!  )rS   r   r   r   r/  -  s    zTextWithDash.get_dashpadc             C   s   || _ d| _dS )zÁ
        Set the "pad" of the TextWithDash, which is the extra spacing
        between the dash and the text, in canvas units.

        Parameters
        ----------
        dp : float
        TN)r!  r„   )rS   Údpr   r   r   Úset_dashpad3  s    	zTextWithDash.set_dashpadc             C   s   | j S )zr
        Get the extra spacing between the dash and the specified text
        position, in canvas units.
        )r"  )rS   r   r   r   r0  ?  s    zTextWithDash.get_dashpushc             C   s   || _ d| _dS )zÐ
        Set the "push" of the TextWithDash, which is the extra spacing between
        the beginning of the dash and the specified position.

        Parameters
        ----------
        dp : float
        TN)r"  r„   )rS   r<  r   r   r   Úset_dashpushF  s    	zTextWithDash.set_dashpushc             C   s    |   |d ¡ |  |d ¡ dS )zŽ
        Set the (*x*, *y*) position of the :class:`TextWithDash`.

        Parameters
        ----------
        xy : (float, float)
        r   r   N)r  r  )rS   r  r   r   r   r  R  s    zTextWithDash.set_positionc             C   s   t |ƒ| _d| _dS )z}
        Set the *x* position of the :class:`TextWithDash`.

        Parameters
        ----------
        x : float
        TN)r    r  r„   )rS   r7   r   r   r   r  ]  s    
zTextWithDash.set_xc             C   s   t |ƒ| _d| _dS )z}
        Set the *y* position of the :class:`TextWithDash`.

        Parameters
        ----------
        y : float
        TN)r    r  r„   )rS   r8   r   r   r   r  h  s    
zTextWithDash.set_yc             C   s"   t  | |¡ | j |¡ d| _dS )z»
        Set the :class:`matplotlib.transforms.Transform` instance used
        by this artist.

        Parameters
        ----------
        t : matplotlib.transforms.Transform
        TN)rL   r¸   r  r„   )rS   r5   r   r   r   r¸   s  s    	zTextWithDash.set_transformc             C   s   | j S )z0return the figure instance the artist belongs to)rë   )rS   r   r   r   rË   €  s    zTextWithDash.get_figurec             C   s   t  | |¡ | j |¡ dS )zŽ
        Set the figure instance the artist belongs to.

        Parameters
        ----------
        fig : matplotlib.figure.Figure
        N)rL   Ú
set_figurer  )rS   Úfigr   r   r   r?  „  s    zTextWithDash.set_figure)r   r   rU   Nr‘   r‘   NNNNr  r   NrM   r   )N)N)r  r  r  r  r  rX   r|   rÊ   r•   rÀ   r+  rv   r,  r9  r.  r:  r-  r;  r/  r=  r0  r>  r  r  r  r¸   rË   r?  r   r   r   r   r     sL   5            


T
	r  )r  c               @   s:   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )Ú
OffsetFromz3Callable helper class for working with `Annotation`Úpointsc             C   s   || _ || _|  |¡ dS )aY  
        Parameters
        ----------
        artist : `Artist`, `BboxBase`, or `Transform`
            The object to compute the offset from.

        ref_coord : length 2 sequence
            If `artist` is an `Artist` or `BboxBase`, this values is
            the location to of the offset origin in fractions of the
            `artist` bounding box.

            If `artist` is a transform, the offset origin is the
            transform applied to this value.

        unit : {'points, 'pixels'}
            The screen units to use (pixels or points) for the offset
            input.

        N)Ú_artistÚ
_ref_coordÚset_unit)rS   r   Z	ref_coordrð   r   r   r   rX   ”  s    zOffsetFrom.__init__c             C   s   |dkrt dƒ‚|| _dS )z•
        The unit for input to the transform used by ``__call__``

        Parameters
        ----------
        unit : {'points', 'pixels'}
        )rB  Úpixelsz-'unit' must be one of [ 'points' | 'pixels' ]N)r!   Ú_unit)rS   rð   r   r   r   rE  ¬  s    zOffsetFrom.set_unitc             C   s   | j S )z8The unit for input to the transform used by ``__call__``)rG  )rS   r   r   r   Úget_unit¸  s    zOffsetFrom.get_unitc             C   s"   |   ¡ }|dkrdS | d¡S d S )NrF  g      ð?)rH  r¹   )rS   r/   rð   r   r   r   Ú
_get_scale¼  s    zOffsetFrom._get_scalec             C   sÚ   t | jtƒrL| j |¡}|j\}}}}| j\}}|||  |||   }	}
njt | jtƒrŽ| jj\}}}}| j\}}|||  |||   }	}
n(t | jtƒr®| j | j¡\}	}
nt	dƒ‚|  
|¡}tƒ  ||¡ |	|
¡}|S )aX  
        Return the offset transform.

        Parameters
        ----------
        renderer : `RendererBase`
            The renderer to use to compute the offset

        Returns
        -------
        transform : `Transform`
            Maps (x, y) in pixel or point units to screen units
            relative to the given artist.
        zunknown type)rY   rC  r   rv   rw   rD  r   r   r*   rò   rI  r   Úscaler·   )rS   r/   rl   ry   rz   r9   r:   ZxfZyfr7   r8   Zscr1   r   r   r   Ú__call__Ã  s    


zOffsetFrom.__call__N)rB  )	r  r  r  r  rX   rE  rH  rI  rK  r   r   r   r   rA  ’  s   
rA  c               @   sX   e 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d„ Z
ddd„ZdS )Ú_AnnotationBaseÚdataNc             C   s    || _ || _|  |¡ d | _d S )N)r  ÚxycoordsÚset_annotation_clipÚ
_draggable)rS   r  rN  Úannotation_clipr   r   r   rX   ç  s    
z_AnnotationBase.__init__c       
      C   sp   t |tƒr|\}}n
|| }}|dkr4t|  |¡ƒ}|dkrJt|  |¡ƒ}|  ||¡}| ||f¡\}}	||	fS )NrM  )rY   rõ   r    r´   rµ   Ú_get_xy_transformr*   )
rS   r/   r7   r8   r  Ús1Ús2r1   rÖ   r×   r   r   r   Ú_get_xyò  s    


z_AnnotationBase._get_xyc             C   st  t |tƒrD|\}}ddlm} |  ||¡}|  ||¡}|||ƒ}|S t|ƒr~||ƒ}t |tƒrft|ƒS t |tƒrt|S t	dƒ‚nRt |t
ƒrš| |¡}	t|	ƒS t |tƒr¬t|ƒS t |tƒrº|S t |tƒsÐt	d| ƒ‚|dkrà| jjS |dkrddlm}
 |
 ¡ }|| jj }|S | ¡ }t|ƒdkr0td	| ƒ‚d
\}}|\}}|dkrT| jj}n|dkrf| jj}|d k	r€|jd d… }n|dkr”|  |¡}|d k	rd|\}}ddlm} |dkrÚ| j ¡ d }|ƒ  ||¡}n~|dkrì|ƒ }nl|dkr |  ¡ }|| j ¡  d }|ƒ  ||¡}n8|dkrL|jdd … \}}|ƒ  ||¡}ntd	| ƒ‚| ||¡S td	| ƒ‚d S )Nr   )Úblended_transform_factoryzunknown return type ...zunknown coordinate type : %srM  Zpolar)Ú	PolarAxesr   z!%s is not a recognized coordinate)NNrë   ÚaxesÚoffset)r   rB  g      R@rF  rI   Zfraction)rY   rõ   Zmatplotlib.transformsrV  rR  rt   r   r   r   rò   r   rv   rZ   rX  Z	transDataZmatplotlib.projectionsrW  ZPolarTransformr—   r˜   r!   rë   rl   rw   Ú_get_ref_xyr   Zget_dpirJ  r°   r·   )rS   r/   r  rS  rT  rV  Ztr1Ztr2r1   rl   rW  r»   Zs_Zbbox0Zxy0Z	bbox_namerð   Zref_xZref_yr   ZdpprI   r9   r:   r   r   r   rR    sz    





















z!_AnnotationBase._get_xy_transformc             C   s¤   dd„ }t | jtƒrp| j\}}||ƒs.||ƒr6tdƒ‚| j\}}|  ||||¡\}}|  ||||¡\}	}
||
fS || jƒr„tdƒ‚n| j\}}|  |||| j¡S dS )zy
        return x, y (in display coordinate) that is to be used for a reference
        of any offset coordinate
        c             S   s   t | tƒo|  ¡ d dkS )Nr   rY  )rY   rZ   r—   )r  r   r   r   Ú	is_offsetY  s    z._AnnotationBase._get_ref_xy.<locals>.is_offsetz+xycoords should not be an offset coordinateN)rY   rN  rõ   r!   r  rU  )rS   r/   r[  rS  rT  r7   r8   rÖ   r×   r6  r7  r   r   r   rZ  T  s    




z_AnnotationBase._get_ref_xyc             C   s
   || _ dS )aK  
        set *annotation_clip* attribute.

          * True: the annotation will only be drawn when self.xy is inside
                  the axes.
          * False: the annotation will always be drawn regardless of its
                   position.
          * None: the self.xy will be checked only if *xycoords* is "data"
        N)Ú_annotation_clip)rS   rz   r   r   r   rO  u  s    
z#_AnnotationBase.set_annotation_clipc             C   s   | j S )z
        Return *annotation_clip* attribute.
        See :meth:`set_annotation_clip` for the meaning of return values.
        )r\  )rS   r   r   r   Úget_annotation_clip  s    z#_AnnotationBase.get_annotation_clipc             C   s   | j \}}|  |||| j¡S )z1Return the pixel position of the annotated point.)r  rU  rN  )rS   r/   r7   r8   r   r   r   Ú_get_position_xyˆ  s    
z _AnnotationBase._get_position_xyc             C   s2   |   ¡ }|s|dkr.| jdkr.| j |¡s.dS dS )zb
        given the xy pixel coordinate, check if the annotation need to
        be drawn.
        NrM  FT)r]  rN  rX  Zcontains_point)rS   r/   Úxy_pixelrz   r   r   r   Ú	_check_xy  s
    z_AnnotationBase._check_xyFc             C   s`   ddl m} | jdk	}|dkr$| }|r@| jdkrZ|| |ƒ| _n| jdk	rT| j ¡  d| _| jS )ac  
        Set the draggable state -- if state is

          * None : toggle the current state

          * True : turn draggable on

          * False : turn draggable off

        If draggable is on, you can drag the annotation on the canvas with
        the mouse.  The DraggableAnnotation helper instance is returned if
        draggable is on.
        r   )ÚDraggableAnnotationN)Zmatplotlib.offsetboxra  rP  Z
disconnect)rS   ÚstateZuse_blitra  Zis_draggabler   r   r   Ú	draggableœ  s    



z_AnnotationBase.draggable)rM  N)NF)r  r  r  rX   rU  rR  rZ  rO  r]  r^  r`  rc  r   r   r   r   rL  æ  s    
S!rL  c               @   sÒ   e Zd ZdZdd„ Zd#dd„Zdd	„ Zed
d„ ƒZej	dd„ ƒZedd„ ƒZ
e
j	dd„ ƒZ
e
jZde_e
jZde_dd„ Zdd„ Zdd„ Zejdd„ ƒZd$dd„Zeejddddd „ ƒe d¡d!d „ ƒd"ZdS )%Ú
Annotationa`  
    An `.Annotation` is a `.Text` that can refer to a specific position *xy*.
    Optionally an arrow pointing from the text to *xy* can be drawn.

    Attributes
    ----------
    xy
        The annotated position.
    xycoords
        The coordinate system for *xy*.
    arrow_patch
        A `.FancyArrowPatch` to point from *xytext* to *xy*.
    c             C   s   d| j d | j d | jf S )NzAnnotation(%g, %g, %r)r   r   )r  rR   )rS   r   r   r   r  Ë  s    zAnnotation.__str__NrM  c             K   sì   t j| |||d |dkr4|dk	r4||kr4t d¡ |dkrB| j}|| _|dkrV| j}|\}	}
tj| |	|
|f|Ž || _|dk	râd|kr¢| j 	¡ }| 
dd¡| _n2d}tƒ }x&| j ¡ D ]\}}||kr¸|||< q¸W td
|Ž| _nd| _dS )a]  
        Annotate the point *xy* with text *s*.

        In the simplest form, the text is placed at *xy*.

        Optionally, the text can be displayed in another position *xytext*.
        An arrow pointing from the text to the annotated point *xy* can then
        be added by defining *arrowprops*.

        Parameters
        ----------
        s : str
            The text of the annotation.

        xy : (float, float)
            The point *(x,y)* to annotate.

        xytext : (float, float), optional
            The position *(x,y)* to place the text at.
            If *None*, defaults to *xy*.

        xycoords : str, `.Artist`, `.Transform`, callable or tuple, optional

            The coordinate system that *xy* is given in. The following types
            of values are supported:

            - One of the following strings:

              =================   =============================================
              Value               Description
              =================   =============================================
              'figure points'     Points from the lower left of the figure
              'figure pixels'     Pixels from the lower left of the figure
              'figure fraction'   Fraction of figure from lower left
              'axes points'       Points from lower left corner of axes
              'axes pixels'       Pixels from lower left corner of axes
              'axes fraction'     Fraction of axes from lower left
              'data'              Use the coordinate system of the object being
                                  annotated (default)
              'polar'             *(theta,r)* if not native 'data' coordinates
              =================   =============================================

            - An `.Artist`: *xy* is interpreted as a fraction of the artists
              `~matplotlib.transforms.Bbox`. E.g. *(0, 0)* would be the lower
              left corner of the bounding box and *(0.5, 1)* would be the
              center top of the bounding box.

            - A `.Transform` to transform *xy* to screen coordinates.

            - A function with one of the following signatures::

                def transform(renderer) -> Bbox
                def transform(renderer) -> Transform

              where *renderer* is a `.RendererBase` subclass.

              The result of the function is interpreted like the `.Artist` and
              `.Transform` cases above.

            - A tuple *(xcoords, ycoords)* specifying separate coordinate
              systems for *x* and *y*. *xcoords* and *ycoords* must each be
              of one of the above described types.

            See :ref:`plotting-guide-annotation` for more details.

            Defaults to 'data'.

        textcoords : str, `.Artist`, `.Transform`, callable or tuple, optional
            The coordinate system that *xytext* is given in.

            All *xycoords* values are valid as well as the following
            strings:

            =================   =========================================
            Value               Description
            =================   =========================================
            'offset points'     Offset (in points) from the *xy* value
            'offset pixels'     Offset (in pixels) from the *xy* value
            =================   =========================================

            Defaults to the value of *xycoords*, i.e. use the same coordinate
            system for annotation point and text position.

        arrowprops : dict, optional
            The properties used to draw a
            `~matplotlib.patches.FancyArrowPatch` arrow between the
            positions *xy* and *xytext*.

            If *arrowprops* does not contain the key 'arrowstyle' the
            allowed keys are:

            ==========   ======================================================
            Key          Description
            ==========   ======================================================
            width        The width of the arrow in points
            headwidth    The width of the base of the arrow head in points
            headlength   The length of the arrow head in points
            shrink       Fraction of total length to shrink from both ends
            ?            Any key to :class:`matplotlib.patches.FancyArrowPatch`
            ==========   ======================================================

            If *arrowprops* contains the key 'arrowstyle' the
            above keys are forbidden.  The allowed values of
            ``'arrowstyle'`` are:

            ============   =============================================
            Name           Attrs
            ============   =============================================
            ``'-'``        None
            ``'->'``       head_length=0.4,head_width=0.2
            ``'-['``       widthB=1.0,lengthB=0.2,angleB=None
            ``'|-|'``      widthA=1.0,widthB=1.0
            ``'-|>'``      head_length=0.4,head_width=0.2
            ``'<-'``       head_length=0.4,head_width=0.2
            ``'<->'``      head_length=0.4,head_width=0.2
            ``'<|-'``      head_length=0.4,head_width=0.2
            ``'<|-|>'``    head_length=0.4,head_width=0.2
            ``'fancy'``    head_length=0.4,head_width=0.4,tail_width=0.4
            ``'simple'``   head_length=0.5,head_width=0.5,tail_width=0.2
            ``'wedge'``    tail_width=0.3,shrink_factor=0.5
            ============   =============================================

            Valid keys for `~matplotlib.patches.FancyArrowPatch` are:

            ===============  ==================================================
            Key              Description
            ===============  ==================================================
            arrowstyle       the arrow style
            connectionstyle  the connection style
            relpos           default is (0.5, 0.5)
            patchA           default is bounding box of the text
            patchB           default is None
            shrinkA          default is 2 points
            shrinkB          default is 2 points
            mutation_scale   default is text size (in points)
            mutation_aspect  default is 1.
            ?                any key for :class:`matplotlib.patches.PathPatch`
            ===============  ==================================================

            Defaults to None, i.e. no arrow is drawn.

        annotation_clip : bool or None, optional
            Whether to draw the annotation when the annotation point *xy* is
            outside the axes area.

            - If *True*, the annotation will only be drawn when *xy* is
              within the axes.
            - If *False*, the annotation will always be drawn.
            - If *None*, the annotation will only be drawn when *xy* is
              within the axes and *xycoords* is 'data'.

            Defaults to *None*.

        **kwargs
            Additional kwargs are passed to `~matplotlib.text.Text`.

        Returns
        -------
        annotation : `.Annotation`

        See Also
        --------
        :ref:`plotting-guide-annotation`.

        )rN  rQ  NzgYou have used the `textcoords` kwarg, but not the `xytext` kwarg.  This can lead to surprising results.Ú
arrowstyleÚrelpos)g      à?g      à?)r£   Ú	headwidthÚ
headlengthÚshrinkÚfrac©r   r   ©r   r   )rk  rl  )rL  rX   ÚwarningsÚwarnrN  Ú_textcoordsr  rL   Ú
arrowpropsrŠ   rn   Ú_arrow_relposrÂ   Úitemsr
   Úarrow_patch)rS   r  r  ÚxytextrN  Z
textcoordsrp  rQ  r   r7   r8   Z	shapekeysr¢   Úvalr   r   r   rX   Î  s:     -


zAnnotation.__init__c             C   s:   t  | |¡\}}| jd k	r2| j |¡\}}|p0|}||fS )N)rL   rx   rs  )rS   Zeventrx   ZtinfoZin_patchr2   r   r   r   rx   ¥  s
    
zAnnotation.containsc             C   s   |   ¡ S )zU
        The the text position.

        See also *xytext* in `.Annotation`.
        )rÊ   )rS   r   r   r   Úxyann­  s    zAnnotation.xyannc             C   s   |   |¡ d S )N)r  )rS   rt  r   r   r   rv  ¶  s    c             C   s   | j S )z5The coordinate system to use for `.Annotation.xyann`.)ro  )rS   r   r   r   Ú	anncoordsº  s    zAnnotation.anncoordsc             C   s
   || _ d S )N)ro  )rS   Zcoordsr   r   r   rw  ¿  s    zq
    Return the coordinate system to use for `.Annotation.xyann`.

    See also *xycoords* in `.Annotation`.
    zn
    Set the coordinate system to use for `.Annotation.xyann`.

    See also *xycoords* in `.Annotation`.
    c             C   s&   | j d k	r| j  |¡ t | |¡ d S )N)rs  r?  r   )rS   r@  r   r   r   r?  Ñ  s    
zAnnotation.set_figurec             C   s   |   |¡}|  ||¡ dS )z?Update the pixel positions of the annotated point and the text.N)r^  Ú_update_position_xytext)rS   r/   r_  r   r   r   Úupdate_positionsÖ  s    
zAnnotation.update_positionsc       "         sð  |   |  || j¡¡ |  ¡ \}}|\}}| jdk	rì|\‰ ‰t | |¡j\}}}	}
||	 }||
 }d||  }d||  }| j ¡ }| 	d|  
¡ ¡}| j |¡ d|krÈ| 	dd¡}| 	dd¡}| 	d	d
¡}| 	dd¡}|dk	rìt d¡ | 	dd
¡}t|| || || d}| jjd|Ž |df|df|dff}|df|df|dff}t‡ fdd„|D ƒƒ\}\}}t‡fdd„|D ƒƒ\}\}}||f| _t |ˆ |ˆ  ¡}|| | d¡ }|| j_|| j_| j}t | |¡} | j| j|d   }| j| j|d   }| j ||f||f¡ d|kr6| j | 	d¡¡ n¶| jrN| j | j¡ nž| d¡}!|  ¡ dkrv| j d¡ dS t | |¡} | j\}}}	}
||!d 8 }||!d 8 }|	|!7 }	|
|!7 }
t ||f|	|
d}|  t!ƒ ¡ | "d¡ | j |¡ dS )zX
        Update the pixel positions of the annotation text and the arrow patch.
        Ng      à?Zmutation_scalere  ri  g        r£   rŽ   rg  é   rj  zh'frac' option in 'arrowprops' is no longer supported; use 'headlength' to set the head length in points.rh  )Zhead_lengthZ
head_widthZ
tail_widthÚsimpler   r   c             3   s"   | ]}t |d  ˆ  ƒ|fV  qdS )r   N)Úabs)r(  ru  )rÎ   r   r   ú	<genexpr>	  s    z5Annotation._update_position_xytext.<locals>.<genexpr>c             3   s"   | ]}t |d  ˆ  ƒ|fV  qdS )r   N)r|  )r(  ru  )rÏ   r   r   r}  	  s    ZpatchArU   g       @)r  r£   r¤   F)r{  )#r¸   rR  rw  r~   rp  rL   rv   rw   rŠ   rn   r°   rs  rº   rm  rn  rÂ   Zset_arrowstyler,   rq  r&   Zhypotr¹   ZshrinkAZshrinkBrÎ   r£   rÏ   r¤   Zset_positionsZ
set_patchArc   r   r   r   rÇ   )"rS   r/   r_  Zox0Zoy0Zox1Zoy1ry   rz   r9   r:   r{   r5   ZxcZycr4   Zmsri  r£   rg  rj  rh  ZstylekwZxposZyposr2   r7   Zrelposxr8   ZrelposyZ
shrink_ptsrf  rl   r¬   r   )rÎ   rÏ   r   rx  Û  sx    





z"Annotation._update_position_xytextc             C   s   |dk	r|| _ |  ¡ sdS |  |¡}|  ||¡s4dS |  ||¡ |  |¡ | jdk	r€| jjdkrt| jdk	rt| j| j_| j |¡ t	 | |¡ dS )zN
        Draw the :class:`Annotation` object to the given *renderer*.
        N)
rd   ru   r^  r`  rx  r¿   rs  rë   rÀ   rL   )rS   r/   r_  r   r   r   rÀ   @	  s    



zAnnotation.drawc             C   s„   |   ¡ st ¡ S |dk	r|| _| jdkr2| jj| _| jdkrDtdƒ‚|  | j¡ t 	| ¡}|g}| j
dk	rz| | j
 	¡ ¡ t |¡S )a  
        Return the `Bbox` bounding the text and arrow, in display units.

        Parameters
        ----------
        renderer : Renderer, optional
            A renderer is needed to compute the bounding box.  If the artist
            has already been drawn, the renderer is cached; thus, it is only
            necessary to pass this argument when calling `get_window_extent`
            before the first `draw`.  In practice, it is usually easier to
            trigger a draw first (e.g. by saving the figure).
        Nz%Cannot get window extent w/o renderer)ru   r   rð   rd   rë   rñ   rò   ry  rL   rv   rs  ÚappendÚunion)rS   r/   Z	text_bboxZbboxesr   r   r   rv   [	  s    




zAnnotation.get_window_extentz3.0z[arrow was deprecated in Matplotlib 3.0 and will be removed in 3.2. Use arrow_patch instead.)Úmessagec             C   s   d S )Nr   )rS   r   r   r   Ú<lambda>€	  s    zAnnotation.<lambda>c             C   s   d S )Nr   )rS   Úvaluer   r   r   r  	  s    )ÚfgetÚfset)NrM  NNN)N)r  r  r  r  r  rX   rx   Úpropertyrv  Úsetterrw  rƒ  Zget_anncoordsr„  Zset_anncoordsr?  ry  rx  r   r  rÀ   rv   r   Z
deprecatedZarrowr   r   r   r   rd  ¼  s4       
 S	e
"rd  )rd  )N)3r  Ú
contextlibZloggingrÔ   rm  rí   Znumpyr&   rU   r   r   r   r   r   Zfont_managerr   r¥   r	   Zpatchesr
   r   r   Ztextpathr   Z
transformsr   r   r   r   r   r   Z	getLoggerr  rÞ   r   Úcontextmanagerr   r%   r?   Z_define_aliasesrL   Zinterpdr   ZkwdocZdedent_interpdrX   r  rm   rA  rL  rd  r   r   r   r   Ú<module>   sn    


&            T W   K