
    G8c                    v   d Z ddlZddlZddlZddlm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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j@                  e!      Z" ejF                  d      d        Z$d Z%d Z& ejN                  d      d        Z(ejR                   ejT                  dgdgddgdgdgdgdgdgdgdgdgdgd       G d d e                    Z+ G d! d"      Z, G d# d$      Z- G d% d&e+e-      Z.ejR                  j_                  e.j`                  j                   '       y)(z)
Classes for including text in a figure.
    N)Real   )_apiartistcbook
_docstring)Artist)FontProperties)FancyArrowPatchFancyBboxPatch	Rectangle)TextPath)Affine2DBboxBboxBaseBboxTransformToIdentityTransform	Transform3.6c                     	 t        |       dz  S # t        t        f$ rX}t        j                  | d      s| Y d}~yt        j                  | d      rY d}~yt        dj                  |             |d}~ww xY w)a*  
    Return *rotation* normalized to an angle between 0 and 360 degrees.

    Parameters
    ----------
    rotation : float or {None, 'horizontal', 'vertical'}
        Rotation angle in degrees. *None* and 'horizontal' equal 0,
        'vertical' equals 90.

    Returns
    -------
    float
    h  
horizontalN        vertical     V@zRrotation is {!r}; expected either 'horizontal', 'vertical', numeric value, or None)float
ValueError	TypeErrorr   
_str_equalformat)rotationerrs     1/usr/lib/python3/dist-packages/matplotlib/text.pyget_rotationr$      sv    
9X$$	" 9Hl3x7Gh
3 B$fX.05899s    A7A2A2A22A7c                 0   g }g }t        j                  | j                               }t               j	                  |       }| j                  |      \  }}}|D ]W  \  }	}
}}|
\  }}|j                  ||f      \  }}||z  }||z   ||z   }}|j                  ||g       |j                  ||g       Y t        |      t        |      }}t        |      |z
  t        |      |z
  }}t               j	                  |      j                  ||f      \  }}||||fS )z
    Calculate the bounding box of the text.

    The bbox position takes text rotation into account, but the width and
    height are those of the unrotated box (unlike `.Text.get_window_extent`).
    )
npdeg2radr$   r   rotate_get_layout	transformextendminmax)textrendererprojected_xsprojected_ysthetatr_partsdtwhxywhxt1yt1xt2yt2xt_boxyt_boxw_boxh_boxx_boxy_boxs                            r#   _get_textboxrG   6   s*    LLJJt((*+E			E6	"B""8,KAua (2q!1<<A'Sq7C!GSS#J'S#J'( &L(9FF|$v-s</@6/I5E:$$U+55vv6FGLE5%%%    c                 b    t        t        j                  |       ||j                         ||      S )zECall ``renderer.get_text_width_height_descent``, caching the results.)!_get_text_metrics_with_cache_implweakrefrefcopy)r/   r.   fontpropismathdpis        r#   _get_text_metrics_with_cacherQ   ]   s-     -HtX]]_fcC CrH   i   c                 2     |        j                  |||      S N)get_text_width_height_descent)renderer_refr.   rN   rO   rP   s        r#   rJ   rJ   e   s     >77hOOrH   cfamilyfontfont_propertieshamanamesizestretchstylevariantvaweight)color
fontfamilyfontpropertieshorizontalalignmentmultialignmentfontnamefontsizefontstretch	fontstylefontvariantverticalalignment
fontweightc                   x    e Zd ZdZdZd Z ej                  dd      	 	 	 	 	 	 	 	 	 	 	 	 dOdd fd	       Z fd
Z	 fdZ
d Zd Zd Zd Zd Zd Zd Z fdZd Zd Zd Zd Zd Z fdZdP fd	Z fdZd Zd Zd Zd Zd  Zd! Z e!jD                  d"        Z#d# Z$d$ Z%d% Z&d& Z'd' Z(d( Z)d) Z*d* Z+d+ Z,d, Z-d- Z.d. Z/ ej`                  d/      dPd0       Z1d1 Z2d2 Z3dQd3Z4d4 Z5d5 Z6d6 Z7d7 Z8d8 Z9d9 Z:d: Z;d; Z<d< Z=d= Z>d> Z?d? Z@d@ ZAdA ZBdB ZCdC ZDdD ZEdE ZFdF ZGdG ZHdH ZIdI ZJdJ ZKdK ZLdL ZMdM ZNdN ZO xZPS )RTextzAHandle storing and drawing of text in window or data coordinates.   c                 h    d| j                   d| j                  dt        | j                        dS )NzText(z, ))_x_yrepr_textselfs    r#   __repr__zText.__repr__   s     %)WWdggtDJJ7GHHrH   r   rc   )r\   N)
parse_mathc                z   t         |           ||c| _        | _        d| _        | j                  |       | j                  ||nt        j                  d          | j                  |       | j                  |       | j                  ||nt        j                  d          | j                  |       | j                  |       | j                  |       || _        | j!                  |	       || _        d| _        d| _        |
d}
| j)                  |
       | j+                  |       | j-                  |       y)a
  
        Create a `.Text` instance at *x*, *y* with string *text*.

        The text is aligned relative to the anchor point (*x*, *y*) according
        to ``horizontalalignment`` (default: 'left') and ``verticalalignment``
        (default: 'bottom'). See also
        :doc:`/gallery/text_labels_and_annotations/text_alignment`.

        While Text accepts the 'label' keyword argument, by default it is not
        added to the handles of a legend.

        Valid keyword arguments are:

        %(Text:kwdoc)s
         Nz
text.colorztext.parse_mathg333333?)super__init__rt   ru   rw   set_text	set_colormplrcParamsset_fontproperties
set_usetexset_parse_mathset_wrapset_verticalalignmentset_horizontalalignment_multialignmentset_rotation_transform_rotates_text_bbox_patch	_rendererset_linespacingset_rotation_modeupdate)ry   r9   r:   r.   rc   rm   rf   rg   re   r!   linespacingrotation_modeusetexwraptransform_rotates_textr{   kwargs	__class__s                    r#   r   zText.__init__   s   B 	a
d&ECLL,F	H/**@JLL):;	=d""#45$$%89-(#'=$K[)}-FrH   c                 
   t        j                  |t              }t               }|j	                  d|      }||ur| j                  |       |j	                  d|      }t        |   |       ||ur| j                  |       y y )Nre   bbox)	r   normalize_kwargsrp   objectpopr   r~   r   set_bbox)ry   r   sentinelre   r   r   s        r#   r   zText.update   sx    ''58$4h?)##N3zz&(+vxMM$  rH   c                 .    t         |          }d |d<   |S )Nr   )r~   __getstate__)ry   r6   r   s     r#   r   zText.__getstate__   s    G "+rH   c                    | j                  |      \  }}|||fS | j                         r| j                  di fS t        j	                  |       }|j
                  |j                  cxk  xr |j                  k  nc xr. |j                  |j                  cxk  xr |j                  k  nc }i }| j                  r)| j                  j                  |      \  }}|xs |}||d<   ||fS )zs
        Return whether the mouse event occurred inside the axis-aligned
        bounding-box of the text.
        F
bbox_patch)_default_containsget_visibler   rp   get_window_extentx0r9   x1y0r:   y1r   contains)ry   
mouseeventinsideinfor   cattrpatch_insidepatch_cattrs           r#   r   zText.contains   s    
 --j94<!T^^%;"9
 %%d+''Z\\4TWW4 9gg88 	  (,(8(8(A(A*(M%L++|F"-E,u}rH   c                 j    | j                         \  }}| j                         j                  ||f      S )zW
        Get the (possibly unit converted) transformed x, y in display coords.
        )get_unitless_positionget_transformr*   ry   r9   r:   s      r#   _get_xy_displayzText._get_xy_display   s4     ))+1!!#--q!f55rH   c                 J    | j                   | j                   S | j                  S rS   )r   _horizontalalignmentrx   s    r#   _get_multialignmentzText._get_multialignment   s&    +''',,,rH   c                     | j                         rI| j                         j                  | j                  g| j	                         g      j                  d      S | j                  S )z3Return the text angle in degrees between 0 and 360.r   )get_transform_rotates_textr   transform_angles	_rotationr   itemrx   s    r#   r$   zText.get_rotation   sY    **,%%'88 4#=#=#?"@BBF$q'J >>!rH   c                     | j                   S )zV
        Return whether rotations of the transform affect the text direction.
        )r   rx   s    r#   r   zText.get_transform_rotates_text  s     +++rH   c                 R    t        j                  g d|       || _        d| _        y)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.
        )anchordefaultN)r   TN)r   check_in_list_rotation_modestale)ry   ms     r#   r   zText.set_rotation_mode  s$     	6aH
rH   c                     | j                   S )zReturn the text rotation mode.)r   rx   s    r#   get_rotation_modezText.get_rotation_mode  s    """rH   c                    t         |   |       |j                  | _        |j                  | _        |j                  | _        |j
                  | _        |j                  j                         | _        |j                  | _        |j                  | _	        |j                  | _
        |j                  | _        |j                  | _        d| _        y )NT)r~   update_from_colorr   _verticalalignmentr   _fontpropertiesrM   _usetexr   r   _picker_linespacingr   )ry   otherr   s     r#   r   zText.update_from  s    E"ll$44"'":":$)$>$>!$4499;}}','D'D$}}!..
rH   c           
         d\  }}| j                         j                  d      }g }g }g }g }t        |d| j                  | j	                         rdnd| j
                  j                        \  }	}
}|
|z
  | j                  z  }t        |      D ]  \  }}| j                  |      \  }}|r3t        ||| j                  || j
                  j                        \  }}}ndx}x}}t        ||
      }t        ||      }|j                  |       |j                  |       ||z
  |z
  }|dk(  r||z
   }n|t        |||z
  | j                  z        z  }|j                  |       |j                  |       ||z  } }t        |      }d}|}d}|d   |z
  }t               j                  | j                               }| j                         }|d	k(  r!t!        ||      D cg c]	  \  }}||f }}}ne|d
k(  r1t!        |||      D cg c]  \  }}}||dz  z   |dz  z
  |f }}}}n/|dk(  r*t!        |||      D cg c]  \  }}}||z   |z
  |f }}}}t#        j$                  ||f||f||f||fg      } |j'                  |       }!|!dddf   j)                         }|!dddf   j                         }|!dddf   j)                         }|!dddf   j                         }||z
  }||z
  }"| j*                  }#| j,                  }$| j/                         }%|%dk7  rM|#d
k(  r	||z   dz  }&n
|#dk(  r|}&n|}&|$d
k(  r	||z   dz  }'n|$dk(  r|}'n|$dk(  r||z   }'n|$dk(  r||"z   dz  z
  }'nr|}'no| d   \  }(})| d   \  }*}+|#d
k(  r	|(|*z   dz  }&n
|#dk(  r|*}&n|(}&|$d
k(  r	|)|+z   dz  }'n#|$dk(  r|+}'n|$dk(  r|+z
  }'n|$dk(  r	|+dz  z
  }'n|)}'|j'                  |&|'f      \  }&}'||&z  }||'z  }t1        j2                  ||||"      },|j'                        |&|'fz
  }-|,t5        t!        |t!        ||      g|-j6                         |fS c c}}w c c}}}w c c}}}w )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   r   
lpTeXF)rO   rP   r   leftcenter   rightNr   r   topbaselinecenter_baselineg       @)get_textsplitrQ   r   
get_usetexfigurerP   r   	enumerate_preprocess_mathr-   appendr   
rotate_degr$   r   zipr&   arrayr*   r,   r   r   r   r   from_boundslistT).ry   r/   thisxthisylineswshsxsysr4   lp_hlp_dmin_dyiline
clean_linerO   r;   r<   r6   r   descentwidthxminxmaxymaxyminMmalignr9   r:   offset_layoutcorners_horizcorners_rotatedheighthalignvalignr   offsetxoffsetyxmin1ymin1xmax1ymax1r   xyss.                                                 r#   r)   zText._get_layout*  s     u%%d+ 5dD00 OO-55dkkooO4 +!2!22 ' 	GAt!%!6!6t!<J6j$*>*>!t{{81a A
 AtAAtAIIaLIIaL AHAva% Va!et/@/@%@AAIIeIIeQJE?	D  B"v J!!$"3"3"56 ))+V03B<1aV<M<x,/BO= =!(Aq  %!)ma!e3Q7 =M =w,/BO= =!(Aq  %i!mQ/ =M = D\D$<$d|DF ++m4q!t$((*q!t$((*q!t$((*q!t$((*t **((..0H$ !$;!+7"!$;!+5:%.,,-(S.8(+LE5(+LE5! 5=C/7"! 5=C/5:%(*,,(S.0 {{GW+=>GWdE6: kk-(GW+==T#eSR[93559:GCCa ===s   P<Q=Q	c                 N   ||j                         }|j                  dd      }|j                  dd      }|d}|d}|| j                         z  }n|d}t        |t              rd|vr|d|z  z  }t        d|t               d	|| _        nd| _        | j                          y)
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padsquare   g333333?z
,pad=%0.2f)r   r   r   r   )r  r*   )	rM   r   get_size
isinstancestrr   r   r   _update_clip_properties)ry   	rectpropspropsr  r  s        r#   r   zText.set_bbox  s    "  NN$EyyT2H))E4(C#;Ct}}&;C(C(U(-BL3..-  K!->-@ KDI KD  $D$$&rH   c                     | j                   S )zf
        Return the bbox Patch, or None if the `.patches.FancyBboxPatch`
        is not made.
        )r   rx   s    r#   get_bbox_patchzText.get_bbox_patch  s    
 rH   c                 v   | j                   r,t        | j                  | j                              }t        | j	                  | j
                              }| j                         j                  ||f      \  }}t        | |      \  }}}}| j                   j                  dd||       | j                   j                  t               j                  | j                               j                  ||z   ||z                |j                  | j!                               }| j                   j#                  |       yy)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.
        r   N)r   r   convert_xunitsrt   convert_yunitsru   r   r*   rG   
set_boundsset_transformr   r   r$   	translatepoints_to_pixelsr  set_mutation_scale)	ry   r/   posxposyrE   rF   rC   rD   fontsize_in_pixels	            r#   update_bbox_position_sizezText.update_bbox_position_size  s     ,,TWW56D,,TWW56D++-77tEJD$)5dH)E&E5%''Bu=**
D--/04%<68 !) 9 9$--/ J//0AB rH   c                     t        | j                  | j                  | j                        }| j                  r| j                  j                  |       y y )N)clip_box	clip_pathclip_on)dictclipbox	_clippath_cliponr   r   )ry   	clippropss     r#   r  zText._update_clip_properties  sD    $,,#'>>!%/	 ##I. rH   c                 D    t         |   |       | j                          y rS   )r~   set_clip_boxr  )ry   r,  r   s     r#   r1  zText.set_clip_box  s    W%$$&rH   c                 F    t         |   ||       | j                          y rS   )r~   set_clip_pathr  )ry   pathr*   r   s      r#   r3  zText.set_clip_path  s    dI.$$&rH   c                 D    t         |   |       | j                          y rS   )r~   set_clip_onr  )ry   br   s     r#   r6  zText.set_clip_on  s    A$$&rH   c                     | j                   S )z'Return whether the text can be wrapped._wraprx   s    r#   get_wrapzText.get_wrap      zzrH   c                     || _         y)a  
        Set whether the text can be wrapped.

        Parameters
        ----------
        wrap : bool

        Notes
        -----
        Wrapping does not work together with
        ``savefig(..., bbox_inches='tight')`` (which is also used internally
        by ``%matplotlib inline`` in IPython/Jupyter). The 'tight' setting
        rescales the canvas to accommodate all content and happens before
        wrapping.
        Nr9  )ry   r   s     r#   r   zText.set_wrap!  s      
rH   c                    | j                         j                  | j                               \  }}| j                         j	                         }| j                         }| j                  d       | j                         }| j                  ||||      }| j                  d|z   dz  |||      }|dk(  r|}|S |dk(  r|}|S dt        ||      z  }|S )zk
        Return the maximum line width for wrapping text based on the current
        orientation.
        r      r   r   r   r   )
r   r*   get_position
get_figurer   get_horizontalalignmentr   r$   _get_dist_to_boxr,   )	ry   r   r   
figure_box	alignmentr!   r   r   
line_widths	            r#   _get_wrap_line_widthzText._get_wrap_line_width3  s    
 ##%//0A0A0CDB__&88:
 002	x($$&$$Xr2zB%%8^s"BJ8 J  '!J  Su--JrH   c                    |dkD  rm|dz
  }|t        j                  t        j                  |            z  }|j                  |z
  t        j                  t        j                  d|z
              z  }nH|dkD  r_|dz
  }|t        j                  t        j                  |            z  }|t        j                  t        j                  d|z
              z  }n|dkD  rl|dz
  }|j                  |z
  t        j                  t        j                  |            z  }|t        j                  t        j                  d|z
              z  }ns|j                  |z
  t        j                  t        j                  |            z  }|j                  |z
  t        j                  t        j                  d|z
              z  }t        ||      S )zr
        Return the distance from the given points to the boundaries of a
        rotated box, in pixels.
        i  Z   r?  )mathcosradiansr   r   r,   )ry   r!   r   r   rD  quadh1h2s           r#   rC  zText._get_dist_to_boxM  sT   
 c>c>Ddhht||D122B--"$b4i1H(IIB^c>Ddhht||D122Bdhht||BI677B]b=D--"$d1C(DDBdhht||BI677B--"$h1G(HHB--"$b8m1L(MMB2r{rH   c                     | j                   j                  || j                         d      \  }}}t        j                  |      S )zE
        Return the width of a given text string, in pixels.
        F)r   rT   get_fontpropertiesrJ  ceil)ry   r.   r;   r<   r6   s        r#   _get_rendered_text_widthzText._get_rendered_text_widthd  s@     ..>>##%1a yy|rH   c           
      ,   | j                         s| j                         S | j                         r| j                         S | j                         }g }| j                         j	                  d      }|D ]  }|j	                  d      }t        |      dkD  s$t        |      dk(  r!|j                  |j                  d             >t        dt        |      dz         D ]  }dj                  |d|       }| j                  |      }||kD  r0|j                  dj                  |d|dz
                ||dz
  d } n7|t        |      k(  sl|j                  dj                  |d|              g } n t        |      dkD  r dj                  |      S )z
        Return a copy of the text string with new lines added so that the text
        is wrapped relative to the parent figure (if `get_wrap` is True).
        r    r   r   r   N)r;  r   r   rG  r   lenr   r   rangejoinrS  )	ry   rF  wrapped_linesunwrapped_linesunwrapped_line	sub_wordsr   r   current_widths	            r#   _get_wrapped_textzText._get_wrapped_textn  s   
 }}==?" ??==?" ..0
 --///5 . 	N&,,S1Ii.1$y>Q&!((q)9:q#i.1"45 A88IbqM2D$($A$A$$GM %z1%,,SXXiQ6G-HI$-a!ef$5	 c)n,%,,SXXim-DE$&	! i.1$		8 yy''rH   c                 L   ||| _         | j                         sy | j                         dk(  ry |j                  d| j	                                | j                  | j                               5  | j                  |      \  }}}| j                         }t        | j                  | j                              }t        | j                  | j                              }|j                  ||f      \  }}t        j                   |      rt        j                   |      st"        j%                  d       	 d d d        y |j'                         \  }}	| j(                  r,| j+                  |       | j(                  j-                  |       |j/                         }
|
j1                  | j3                                |
j5                  | j7                                |
j9                  | j:                         | j=                  |
       | j?                         }|D ]  \  }}}}tA        |      dk(  r| nd }||z   }||z   }|jC                         r|	|z
  }| jE                  |      \  }}| jG                         rddl$m%}  || jG                         |      }n|}| jM                         r#|jO                  |
|||| jP                  ||       |jS                  |
|||| jP                  |||	        	 d d d        
jU                          |jW                  d       d
| _,        y # 1 sw Y   2xY w)Nr}   r.   )r.   z%posx and posy should be finite valuesr   r   )PathEffectRenderer)mtext)rO   ra  F)-r   r   r   
open_groupget_gid_cm_setr^  r)   r   r   r  rt   r  ru   r*   r&   isfinite_logwarningget_canvas_width_heightr   r&  drawnew_gcset_foreground	get_color	set_alpha	get_alphaset_url_url_set_gc_clipr$   rV  flipyr   get_path_effectsmatplotlib.patheffectsr`  r   draw_texr   	draw_textrestoreclose_groupr   )ry   r/   r   r   r   transr#  r$  canvaswcanvashgcangler   r8   r9   r:   ra  r   rO   r`  textrenderers                        r#   ri  z	Text.draw  s    %DN!==?b FDLLN3\\t557\8 3	G"&"2"28"<D$&&(E ,,TWW56D,,TWW56D$6JD$;;t$BKK,=DE3	G 3	G  (??AGW ..x8  %%h/"Bdnn./LL)*JJtyy!b!%%'E"& Gb!Q #D	QDHH>>#!A%)%:%:4%@"
F((*I#5--/$;L $,L??$ ))"aJ*.*>*>05 * 7 !**2q!Z+/+?+?28 + G+G93	Gj 	

V$
o3	G 3	Gs   /CL<F,LL#c                     | j                   S )zReturn the color of the text.)r   rx   s    r#   rl  zText.get_color  s    {{rH   c                     | j                   S )z*Return the `.font_manager.FontProperties`.)r   rx   s    r#   rQ  zText.get_fontproperties  s    ###rH   c                 6    | j                   j                         S )z
        Return the list of font families used for font lookup.

        See Also
        --------
        .font_manager.FontProperties.get_family
        )r   
get_familyrx   s    r#   get_fontfamilyzText.get_fontfamily       ##..00rH   c                 6    | j                   j                         S )z
        Return the font name as a string.

        See Also
        --------
        .font_manager.FontProperties.get_name
        )r   get_namerx   s    r#   get_fontnamezText.get_fontname  s     ##,,..rH   c                 6    | j                   j                         S )z
        Return the font style as a string.

        See Also
        --------
        .font_manager.FontProperties.get_style
        )r   	get_stylerx   s    r#   get_fontstylezText.get_fontstyle  s     ##--//rH   c                 6    | j                   j                         S )z
        Return the font size as an integer.

        See Also
        --------
        .font_manager.FontProperties.get_size_in_points
        )r   get_size_in_pointsrx   s    r#   get_fontsizezText.get_fontsize  s     ##6688rH   c                 6    | j                   j                         S )z
        Return the font variant as a string.

        See Also
        --------
        .font_manager.FontProperties.get_variant
        )r   get_variantrx   s    r#   get_fontvariantzText.get_fontvariant       ##//11rH   c                 6    | j                   j                         S )z
        Return the font weight as a string or a number.

        See Also
        --------
        .font_manager.FontProperties.get_weight
        )r   
get_weightrx   s    r#   get_fontweightzText.get_fontweight!  r  rH   c                 6    | j                   j                         S )z
        Return the font stretch as a string or a number.

        See Also
        --------
        .font_manager.FontProperties.get_stretch
        )r   get_stretchrx   s    r#   r  zText.get_stretch+  r  rH   c                     | j                   S )zs
        Return the horizontal alignment as a string.  Will be one of
        'left', 'center' or 'right'.
        )r   rx   s    r#   rB  zText.get_horizontalalignment5  s    
 (((rH   c                     t        | j                  | j                              }t        | j                  | j                              }||fS )z0Return the (x, y) unitless position of the text.)r   r  rt   r  ru   r   s      r#   r   zText.get_unitless_position<  s?     $%%dgg./$%%dgg./!trH   c                 2    | j                   | j                  fS )z'Return the (x, y) position of the text.)rt   ru   rx   s    r#   r@  zText.get_positionD  s     wwrH   z3.5c                    | j                         \  }}|xs | j                  }||| j                         | j                  | j                  | j
                  t        | j                        | j                  | j                  | j                  | j                  j                  t        j                  |      | 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   r   r   r   r   r   hashr   r   r   r   r   rP   rK   rL   r   ry   r/   r9   r:   s       r#   get_prop_tupzText.get_prop_tupK  s     ))+1-t~~1dmmot{{'')B)BT))* 3 3,,X!6!! 	rH   c                     | j                   S )zReturn the text string.)rw   rx   s    r#   r   zText.get_text_  r<  rH   c                     | j                   S )z
        Return the vertical alignment as a string.  Will be one of
        'top', 'center', 'bottom', 'baseline' or 'center_baseline'.
        )r   rx   s    r#   get_verticalalignmentzText.get_verticalalignmentc  s    
 &&&rH   c                 <   | j                         st        j                         S || j                  j                  }| j                         dk(  rVt        j                  | j                  |      5  | j                         \  }}t        j                  ||dd      cddd       S ||| _
        | j                  | j                  j                         | _
        | j                  t        d      t        j                  | j                  |      5  | j                  | j                        \  }}}| j                         \  }}	| j                         j!                  ||	f      \  }}	|j#                  ||	      }|cddd       S # 1 sw Y   xY w# 1 sw Y   yxY w)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 calling
            `~.Figure.draw_without_rendering` or ``plt.show()``.

        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.
        Nr}   )rP   r   zoCannot get window extent of text w/o renderer. You likely want to call 'figure.draw_without_rendering()' first.)r   r   unitr   rP   r   r   _setattr_cmr   r   r   _get_rendererRuntimeErrorr)   r   r   r*   
translated)
ry   r/   rP   txtyr   r   r   r9   r:   s
             r#   r   zText.get_window_extentj  sm   , !99;;++//C==?b ""4;;C8 6--/B''B156 6 %DN>>!![[668DN>>!HI I t{{4 	"&"2"24>>"BD$--/DAq%%'111a&9DAq??1a(D	 	6 6	 	s   1+FA*FFFc                     | j                   | j                  t        ||             n%| j                   j                  t        |             | j	                          d| _        y)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)	facecolor	edgecolor)r  T)r   r   r+  r   r  r   ry   rc   s     r#   set_backgroundcolorzText.set_backgroundcolor  sO     #MM$%@A##D5$9:$$&
rH   c                     t        j                  |d      s t        j                  j	                  |       	 t        |       || _        d| _	        y# t        $ r t        |      }Y %w xY w)zs
        Set the foreground color of the text

        Parameters
        ----------
        color : color
        auto)rc   TN)
r   r   r   colors_check_color_liker  r   tupler   r   r  s     r#   r   zText.set_color  s_     v.JJ((u(5	!K 
  	!%LE	!s   A A)(A)c                 R    t        j                  g d|       || _        d| _        y)z
        Set the horizontal alignment relative to the anchor point.

        See also :doc:`/gallery/text_labels_and_annotations/text_alignment`.

        Parameters
        ----------
        align : {'left', 'center', 'right'}
        r   r   r   alignTN)r   r   r   r   ry   r  s     r#   r   zText.set_horizontalalignment  s$     	6eD$)!
rH   c                 R    t        j                  g d|       || _        d| _        y)al  
        Set the text alignment for multiline texts.

        The layout of the bounding box of all the lines is determined by the
        horizontalalignment and verticalalignment properties. This property
        controls the alignment of the text lines within that box.

        Parameters
        ----------
        align : {'left', 'right', 'center'}
        r  r  TN)r   r   r   r   r  s     r#   set_multialignmentzText.set_multialignment  s$     	6eD$
rH   c                 V    t        j                  t        |       || _        d| _        y)z
        Set the line spacing as a multiple of the font size.

        The default line spacing is 1.2.

        Parameters
        ----------
        spacing : float (multiple of font size)
        )spacingTN)r   check_isinstancer   r   r   )ry   r  s     r#   r   zText.set_linespacing  s#     	dG4#
rH   c                 H    | j                   j                  |       d| _        y)a  
        Set the font family.  Can 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.

        If a `Text` instance is constructed with ``fontfamily=None``, then the
        font is set to :rc:`font.family`, and the
        same is done when `set_fontfamily()` is called on an existing
        `Text` instance.

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

        See Also
        --------
        .font_manager.FontProperties.set_family
        TN)r   
set_familyr   ry   rh   s     r#   set_fontfamilyzText.set_fontfamily  s    * 	''1
rH   c                 H    | j                   j                  |       d| _        y)z
        Set the font variant.

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

        See Also
        --------
        .font_manager.FontProperties.set_variant
        TN)r   set_variantr   )ry   r`   s     r#   set_fontvariantzText.set_fontvariant  s     	((1
rH   c                 H    | j                   j                  |       d| _        y)z
        Set the font style.

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

        See Also
        --------
        .font_manager.FontProperties.set_style
        TN)r   	set_styler   )ry   rk   s     r#   set_fontstylezText.set_fontstyle  s     	&&y1
rH   c                 H    | j                   j                  |       d| _        y)a  
        Set the font size.

        Parameters
        ----------
        fontsize : float or {'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'}
            If a float, the fontsize in points. The string values denote sizes
            relative to the default font size.

        See Also
        --------
        .font_manager.FontProperties.set_size
        TN)r   set_sizer   )ry   ri   s     r#   set_fontsizezText.set_fontsize$  s     	%%h/
rH   c                 6    | j                   j                         S )z
        Return the font family name for math text rendered by Matplotlib.

        The default value is :rc:`mathtext.fontset`.

        See Also
        --------
        set_math_fontfamily
        )r   get_math_fontfamilyrx   s    r#   r  zText.get_math_fontfamily6  s     ##7799rH   c                 :    | j                   j                  |       y)a  
        Set the font family for math text rendered by Matplotlib.

        This does only affect Matplotlib's own math renderer. It has no effect
        when rendering with TeX (``usetex=True``).

        Parameters
        ----------
        fontfamily : str
            The name of the font family.

            Available font families are defined in the
            :ref:`matplotlibrc.template file
            <customizing-with-matplotlibrc-files>`.

        See Also
        --------
        get_math_fontfamily
        N)r   set_math_fontfamily)ry   rd   s     r#   r  zText.set_math_fontfamilyB  s    ( 	00<rH   c                 H    | j                   j                  |       d| _        y)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)r   
set_weightr   )ry   rb   s     r#   set_fontweightzText.set_fontweightX  s     	''/
rH   c                 H    | j                   j                  |       d| _        y)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)r   set_stretchr   )ry   r^   s     r#   set_fontstretchzText.set_fontstretchi  s     	((1
rH   c                 T    | j                  |d          | j                  |d          y)z}
        Set the (*x*, *y*) position of the text.

        Parameters
        ----------
        xy : (float, float)
        r   r   N)set_xset_y)ry   xys     r#   set_positionzText.set_positionz  s$     	

2a5

2a5rH   c                      || _         d| _        y)zl
        Set the *x* position of the text.

        Parameters
        ----------
        x : float
        TN)rt   r   )ry   r9   s     r#   r  z
Text.set_x       
rH   c                      || _         d| _        y)zl
        Set the *y* position of the text.

        Parameters
        ----------
        y : float
        TN)ru   r   )ry   r:   s     r#   r  z
Text.set_y  r  rH   c                    t        |t              rt        |      dz  | _        d| _        yt	        j
                  |d      s|d| _        d| _        yt	        j
                  |d      rd| _        d| _        yt        d|       )	a"  
        Set the rotation of the text.

        Parameters
        ----------
        s : float or {'vertical', 'horizontal'}
            The rotation angle in degrees in mathematically positive direction
            (counterclockwise). 'horizontal' equals 0, 'vertical' equals 90.
        r   r   Nr   r   r   z;rotation must be 'vertical', 'horizontal' or a number, not T)r  r   r   r   r   r   r   r   ry   ss     r#   r   zText.set_rotation  s     a"1X^DN 
 a.!)DN 
 a, DN 
  ../S2 3 3rH   c                      || _         d| _        y)z
        Whether rotations of the transform affect the text direction.

        Parameters
        ----------
        t : bool
        TN)r   r   )ry   r7   s     r#   set_transform_rotates_textzText.set_transform_rotates_text  s     ()$
rH   c                 R    t        j                  g d|       || _        d| _        y)a
  
        Set the vertical alignment relative to the anchor point.

        See also :doc:`/gallery/text_labels_and_annotations/text_alignment`.

        Parameters
        ----------
        align : {'bottom', 'baseline', 'center', 'center_baseline', 'top'}
        )r   bottomr   r   r   r  TN)r   r   r   r   r  s     r#   r   zText.set_verticalalignment  s)     	F	 #(
rH   c                 Z    |d}|| j                   k7  rt        |      | _         d| _        yy)a1  
        Set the text string *s*.

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

        Parameters
        ----------
        s : object
            Any object gets converted to its `str` representation, except for
            ``None`` which is converted to an empty string.
        Nr}   T)rw   r  r   r  s     r#   r   zText.set_text  s0     9A

?QDJDJ rH   c                     | j                         r|dk(  rd}|dfS | j                         s|dfS t        j                  |      r|dfS |j	                  dd      dfS )a  
        Return the string *s* after mathtext preprocessing, and the kind of
        mathtext support needed.

        - If *self* is configured to use TeX, return *s* unchanged except that
          a single space gets escaped, and the flag "TeX".
        - Otherwise, if *s* is mathtext (has an even number of unescaped dollar
          signs) and ``parse_math`` is not set to False, return *s* and the
          flag True.
        - Otherwise, return *s* with dollar signs unescaped, and the flag
          False.
        rU  z\ r   FTz\$$)r   get_parse_mathr   is_math_textreplacer  s     r#   r   zText._preprocess_math  se     ??Cxe8O$$&e8O"d7N99UC(%//rH   c                 b    t        j                  |      j                         | _        d| _        y)ar  
        Set the font properties that control the text.

        Parameters
        ----------
        fp : `.font_manager.FontProperties` or `str` or `pathlib.Path`
            If a `str`, it is interpreted as a fontconfig pattern parsed by
            `.FontProperties`.  If a `pathlib.Path`, it is interpreted as the
            absolute path to a font file.
        TN)r
   	_from_anyrM   r   r   )ry   fps     r#   r   zText.set_fontproperties  s'      .77;@@B
rH   c                 v    | t         j                  d   | _        d| _        yt        |      | _        d| _        y)z
        Parameters
        ----------
        usetex : bool or None
            Whether to render using TeX, ``None`` means to use
            :rc:`text.usetex`.
        Nztext.usetexT)r   r   r   boolr   )ry   r   s     r#   r   zText.set_usetex  s6     ><<6DL 
  <DL
rH   c                     | j                   S )z9Return whether this `Text` object uses TeX for rendering.)r   rx   s    r#   r   zText.get_usetex  s    ||rH   c                 $    t        |      | _        y)a0  
        Override switch to disable any mathtext parsing for this `Text`.

        Parameters
        ----------
        parse_math : bool
            If False, this `Text` will never use mathtext.  If True, mathtext
            will be used if there is an even number of unescaped dollar signs.
        N)r  _parse_math)ry   r{   s     r#   r   zText.set_parse_math  s      
+rH   c                     | j                   S )z>Return whether mathtext parsing is considered for this `Text`.)r  rx   s    r#   r  zText.get_parse_math!  s    rH   c                 $    | j                  |      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  r  s     r#   set_fontnamezText.set_fontname%  s      x((rH   )r   r   r}   Nr   r   NNNNNNFFrS   NN)Q__name__
__module____qualname____doc__zorderrz   r   make_keyword_onlyr   r   r   r   r   r   r$   r   r   r   r   r)   r   r  r&  r  r1  r3  r6  r;  r   rG  rC  rS  r^  r   allow_rasterizationri  rl  rQ  r  r  r  r  r  r  r  rB  r   r@  
deprecatedr  r   r  r   r  r   r   r  r   r  r  r  r  r  r  r  r  r  r  r  r   r  r   r   r   r   r   r   r   r  r  __classcell__r   s   @r#   rp   rp   l   s     LFI TE0 "#-%+ $ $!#(-6 !6 16p :6-",#UDn&'P C./'
'
'
$4.1(f C  CJ$1/09212)  T__U &'-^(* 0$
:=,""			*	 $00
, )rH   rp   c                   0    e Zd ZdZddZd Zd Zd Zd Zy)	
OffsetFromz4Callable helper class for working with `Annotation`.c                 B    || _         || _        | j                  |       y)ab  
        Parameters
        ----------
        artist : `.Artist` or `.BboxBase` or `.Transform`
            The object to compute the offset from.

        ref_coord : (float, float)
            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'}, default: 'points'
            The screen units to use (pixels or points) for the offset input.
        N)_artist
_ref_coordset_unit)ry   r   	ref_coordr  s       r#   r   zOffsetFrom.__init__;  s    $ #drH   c                 D    t        j                  ddg|       || _        y)z
        Set the unit for input to the transform used by ``__call__``.

        Parameters
        ----------
        unit : {'points', 'pixels'}
        pointspixels)r  N)r   r   _unit)ry   r  s     r#   r  zOffsetFrom.set_unitQ  s      	Hh/d;
rH   c                     | j                   S )z@Return the unit for input to the transform used by ``__call__``.)r	  rx   s    r#   get_unitzOffsetFrom.get_unit\  r<  rH   c                 P    | j                         }|dk(  ry|j                  d      S )Nr  g      ?)r  r!  )ry   r/   r  s      r#   
_get_scalezOffsetFrom._get_scale`  s)    }}8,,R00rH   c                    t        | j                  t              rc| j                  j                  |      }| j                  \  }}|j
                  |j                  |z  z   }|j                  |j                  |z  z   }nt        | j                  t              rT| j                  }| j                  \  }}|j
                  |j                  |z  z   }|j                  |j                  |z  z   }nNt        | j                  t              r)| j                  j                  | j                        \  }}nt        d      | j                  |      }t               j                  |      j!                  ||      }|S )aL  
        Return the offset transform.

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

        Returns
        -------
        `Transform`
            Maps (x, y) in pixel or point units to screen units
            relative to the given artist.
        zunknown type)r  r  r	   r   r  r   r   r   r  r   r   r*   r  r  r   scaler   )	ry   r/   r   xfyfr9   r:   scr3   s	            r#   __call__zOffsetFrom.__call__g  s    dllF+<<11(;D__FB$**r/)A$++**Ah/<<D__FB$**r/)A$++**Ai0<<))$//:DAq~..__X&Zb!++Aq1	rH   N)r  )	r  r  r  r  r   r  r  r  r   rH   r#   r   r   8  s    >,	1!rH   r   c                   L    e Zd Z	 	 ddZd Zd Zd Zd Zd Zd Z	dd	Z
dd
Zy)_AnnotationBaseNc                 P    || _         || _        | j                  |       d | _        y rS   )r  xycoordsset_annotation_clip
_draggable)ry   r  r  annotation_clips       r#   r   z_AnnotationBase.__init__  s'    
    1rH   c                     t        |t              r|\  }}n||}}|dk(  rt        | j                  |            }|dk(  rt        | j	                  |            }| j                  ||      j                  ||f      S )Ndata)r  r  r   r  r  _get_xy_transformr*   )ry   r/   r9   r:   r  s1s2s          r#   _get_xyz_AnnotationBase._get_xy  sx    aFBB<d))!,-A<d))!,-A%%h2<<aVDDrH   c                    t        |t              r:|\  }}ddlm} | j	                  ||      }| j	                  ||      } |||      }|S t        |      r@ ||      }t        |t              rt        |      S t        |t              r|S t        d      t        |t              r|j                  |      }	t        |	      S t        |t              rt        |      S t        |t              r|S t        |t              st        d|      |dk(  r| j                  j                  S |dk(  r1ddlm}
 |
j#                         }|| j                  j                  z   }|S |j%                         }t'        |      dk7  rt)        |d	      d
\  }}|\  }}|dk(  r| j*                  j,                  }n7|dk(  r| j*                  j.                  }n|dk(  r| j                  j.                  }||j0                  }n|dk(  r| j3                  |      }||\  }}|dk(  r3| j*                  j4                  dz  }t7               j9                  |      }n|dk(  rt7               }n|dk(  rF| j;                         }|| j*                  j4                  z  dz  }t7               j9                  |      }n=|dk(  r*|j<                  \  }}t7               j9                  ||      }nt)        |d      |j?                  ||      S t)        |d	      )Nr   )blended_transform_factoryzUnknown return typezUnknown coordinate type: r  polar)	PolarAxesr   z is not a recognized coordinater  r   	subfigureaxesoffsetr  H   r  ri   fractionz is not a recognized unit) r  r  matplotlib.transformsr#  r  callabler   r   r   r  r	   r   r  r'  	transDatamatplotlib.projectionsr%  PolarTransformr   rV  r   r   figbboxr   p0_get_ref_xyrP   r   r  r  r]   r   )ry   r/   r  r  r   r#  tr1tr2r3   r   r%  ry  s_bbox0xy0	bbox_namer  ref_xref_ydppri   r;   r<   s                          r#   r  z!_AnnotationBase._get_xy_transform  s   aFBG((26C((26C*34BIa[8B"h'&r**B	*	"#8996"&&x0D"4((8$"1%%9%HAs#!:1%@AA;99&&&'\8))+B,,,ELWWYr7a<u$CDEE
s	4 KK''E+%KK$$E& IINNE ((C("""8,C?LE5xkkoo*Z%%c*!Z#==?025Z%%c*#zz1Z%%a+ D8+D!EFF<<u-- u$CDEErH   c                 T     | j                   |g| j                  | j                   S )z{
        Return x, y (in display coordinates) that is to be used for a reference
        of any offset coordinate.
        )r!  r  r  ry   r/   s     r#   r2  z_AnnotationBase._get_ref_xy  s'    
 t||H>tww>>>rH   c                     || _         y)a  
        Set the annotation's clipping behavior.

        Parameters
        ----------
        b : bool or None
            - True: The annotation will be clipped when ``self.xy`` is
              outside the axes.
            - False: The annotation will always be drawn.
            - None: The annotation will be clipped when ``self.xy`` is
              outside the axes and ``self.xycoords == "data"``.
        N_annotation_clip)ry   r7  s     r#   r  z#_AnnotationBase.set_annotation_clip  s     !"rH   c                     | j                   S )z
        Return the annotation's clipping behavior.

        See `set_annotation_clip` for the meaning of return values.
        r?  rx   s    r#   get_annotation_clipz#_AnnotationBase.get_annotation_clip  s     $$$rH   c                 \    | j                   \  }}| j                  |||| j                        S )z1Return the pixel position of the annotated point.)r  r!  r  r  s       r#   _get_position_xyz _AnnotationBase._get_position_xy  s(    ww1||HaDMM::rH   c                     || j                   j                         }| j                         }|s|;| j                  dk(  r,| j	                  |      }| j
                  j                  |      S y)z;Check whether the annotation at *xy_pixel* should be drawn.r  T)r   r  rB  r  rD  r'  contains_point)ry   r/   r7  xy_pixels       r#   	_check_xyz_AnnotationBase._check_xy#  sb    {{002H$$&t}}6,,X6H99++H55rH   c                     ddl m} | j                  du}|| }|r&| j                   || |      | _        | j                  S | j                  | j                  j                          d| _        | j                  S )a  
        Set whether the annotation is draggable with the mouse.

        Parameters
        ----------
        state : bool or None
            - True or False: set the draggability.
            - None: toggle the draggability.

        Returns
        -------
        DraggableAnnotation or None
            If the annotation is draggable, the corresponding
            `.DraggableAnnotation` helper is returned.
        r   )DraggableAnnotationN)matplotlib.offsetboxrJ  r  
disconnect)ry   stateuse_blitrJ  is_draggables        r#   	draggablez_AnnotationBase.draggable.  sx      	=d2 =$$E&"5dH"E 	 ***,"DOrH   )r  NrS   )NF)r  r  r  r   r!  r  r2  r  rB  rD  rH  rP  r  rH   r#   r  r    s;     !!%		ERFh?""%;
	rH   r  c                       e Zd ZdZd Z	 	 	 	 	 ddZd Zed        Zej                  d        Zed        Z
e
j                  d        Z
d	 Zd
 Z eeed      Zd Zd Zej"                  d        ZddZd fd	Z xZ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                 Z    d| j                   d   | j                   d   | j                  fz  S )NzAnnotation(%g, %g, %r)r   r   )r  rw   rx   s    r#   __str__zAnnotation.__str___  s(    '4771:twwqz4::*NNNrH   c                    t         j                  | |||       ||||k7  rt        j                  d       || j                  }|| _        || j                  }|\  }	}
|| _        |V|j                         }d|v r|j                  dd      | _
        ndD ]  }|j                  |d        t        di || _        nd| _        t        j                  | |	|
|fi | y)	a  
        Annotate the point *xy* with text *text*.

        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
        ----------
        text : str
            The text of the annotation.

        xy : (float, float)
            The point *(x, y)* to annotate. The coordinate system is determined
            by *xycoords*.

        xytext : (float, float), default: *xy*
            The position *(x, y)* to place the text at. The coordinate system
            is determined by *textcoords*.

        xycoords : single or two-tuple of str or `.Artist` or `.Transform` or callable, default: 'data'

            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
              'subfigure points'   Points from the lower left of the subfigure
              'subfigure pixels'   Pixels from the lower left of the subfigure
              'subfigure fraction' Fraction of subfigure 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
              ==================== ============================================

              Note that 'subfigure pixels' and 'figure pixels' are the same
              for the parent figure, so users who want code that is usable in
              a subfigure can use 'subfigure pixels'.

            - An `.Artist`: *xy* is interpreted as a fraction of the artist's
              `~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.

        textcoords : single or two-tuple of str or `.Artist` or `.Transform` or callable, default: value of *xycoords*
            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
            =================   =========================================

        arrowprops : dict, optional
            The properties used to draw a `.FancyArrowPatch` arrow between the
            positions *xy* and *xytext*.  Defaults to None, i.e. no arrow is
            drawn.

            For historical reasons there are two different ways to specify
            arrows, "simple" and "fancy":

            **Simple arrow:**

            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`
            ==========   ======================================================

            The arrow is attached to the edge of the text box, the exact
            position (corners or centers) depending on where it's pointing to.

            **Fancy arrow:**

            This is used if 'arrowstyle' is provided in the *arrowprops*.

            Valid keys are the following `~matplotlib.patches.FancyArrowPatch`
            parameters:

            ===============  ==================================================
            Key              Description
            ===============  ==================================================
            arrowstyle       the arrow style
            connectionstyle  the connection style
            relpos           see below; 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`
            ===============  ==================================================

            The exact starting point position of the arrow is defined by
            *relpos*. It's a tuple of relative coordinates of the text box,
            where (0, 0) is the lower left corner and (1, 1) is the upper
            right corner. Values <0 and >1 are supported and specify points
            outside the text box. By default (0.5, 0.5), so the starting point
            is centered in the text box.

        annotation_clip : bool or None, default: None
            Whether to clip (i.e. not draw) the annotation when the annotation
            point *xy* is outside the axes area.

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

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

        Returns
        -------
        `.Annotation`

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

        )r  r  NzgYou have used the `textcoords` kwarg, but not the `xytext` kwarg.  This can lead to surprising results.
arrowstylerelpos)      ?rX  )r   	headwidth
headlengthshrinkfrac)r  )r   r   )r  r   r   warn_externalr  _textcoordsr  
arrowpropsrM   r   _arrow_relposr   arrow_patchrp   )ry   r.   r  xytextr  
textcoordsr_  r  r   r9   r:   keys               r#   r   zAnnotation.__init__b  s   Z 	  !#*21@ 	! 	B
 N&h&  5 6
 J% >WWF1$!#*Jz)%/^^Hj%I"N .CNN3-.  /LLD#D 	dAq$1&1rH   c                     | j                  |      \  }}|||fS t        j                  | |      \  }}| j                  $| j                  j                  |      \  }}|xs |}||fS rS   )r   rp   r   ra  )ry   eventr   r   r   tinfoin_patchr4   s           r#   r   zAnnotation.contains6  st    --e44<--e4%'**33E:KHa+8HrH   c                     | j                   S rS   )	_xycoordsrx   s    r#   r  zAnnotation.xycoords@  s    ~~rH   c                     d }t        |t              rt        t        ||            s ||      rt	        d      || _        y )Nc                 H    t        | t              xr | j                  d      S )Nr(  )r  r  
startswith)r  s    r#   	is_offsetz&Annotation.xycoords.<locals>.is_offsetF  s    a%@!,,x*@@rH   z'xycoords cannot be an offset coordinate)r  r  anymapr   rj  )ry   r  rn  s      r#   r  zAnnotation.xycoordsD  s=    	A x'CIx0H,IX&FGG!rH   c                 "    | j                         S )zQ
        The text position.

        See also *xytext* in `.Annotation`.
        )r@  rx   s    r#   xyannzAnnotation.xyannN  s       ""rH   c                 &    | j                  |       y rS   )r  )ry   rb  s     r#   rr  zAnnotation.xyannW  s    &!rH   c                     | j                   S )z}
        Return the coordinate system to use for `.Annotation.xyann`.

        See also *xycoords* in `.Annotation`.
        r^  rx   s    r#   get_anncoordszAnnotation.get_anncoords[  s     rH   c                     || _         y)zz
        Set the coordinate system to use for `.Annotation.xyann`.

        See also *xycoords* in `.Annotation`.
        Nru  )ry   coordss     r#   set_anncoordszAnnotation.set_anncoordsc  s     "rH   z>
        The coordinate system to use for `.Annotation.xyann`.)docc                 ~    | j                   | j                   j                  |       t        j                  | |       y rS   )ra  
set_figurer	   )ry   figs     r#   r|  zAnnotation.set_figuren  s2    ''',$$rH   c                 ^   | j                  | j                  || j                               | j                  }|yt        j                  | |      }| j                  |      x}\  |j                  d| j                               }| j                  j                  |       d|vr|j                  dd      }|j                  dd      }|j                  dd	      }d
|v rt        j                  d       |j                  dd	      }	t        |	|z  ||z  ||z        }
 | j                  j                  di |
 |j                  df|j                  |j                   z   dz  df|j                   dfg}|j"                  df|j"                  |j$                  z   dz  df|j$                  dfg}t'        |fd      \  }}t'        |fd      \  }}||f| _        t+        j,                  |z
  |z
        }||z  |j/                  d      z  }|x| j                  _        | j                  _        |j4                  |j6                  | j(                  z  z   }| j                  j9                  ||       d|v r|d   }n| j:                  r| j:                  }n{| j=                         dk(  rd}ne|j/                  d      }t?        |j                  |dz  z
  |j"                  |dz  z
  f|j@                  |z   |jB                  |z   tE               d      }| j                  jG                  |       y)zX
        Update the pixel positions of the annotation text and the arrow patch.
        Nmutation_scalerV  r[  r   r   r  rY     r\  zh'frac' option in 'arrowprops' is no longer supported; use 'headlength' to set the head length in points.rZ  )head_length
head_width
tail_widthr   r   rX  r   c                 &    t        | d   z
        S Nr   abs)vr   s    r#   <lambda>z-Annotation.update_positions.<locals>.<lambda>      QqTBY rH   )rd  c                 &    t        | d   z
        S r  r  )r  r   s    r#   r  z-Annotation.update_positions.<locals>.<lambda>  r  rH   patchAr}   F)r  r   r  r*   r*  )simple)$r  r  	anncoordsr_  rp   r   rD  getr  ra  r"  r   r]  r+  set_arrowstyler   r   r   r   r,   r`  r&   hypotr!  shrinkAshrinkBr1  r]   set_positionsr   r   r   r   r  r   
set_patchA)ry   r/   r_  r   	arrow_endmsr[  r   rY  rZ  stylekwxposyposr9   relposxr:   relposyr
shrink_ptsarrow_beginr  r  r   r   s                         @@r#   update_positionszAnnotation.update_positionst  s   
 	411(DNNKL__
%%dH5!228<<	FB^^,dmmo>++B/z)^^Hc2FNN7A.E"{B7I#""JK $b9J zB&/"n&+bj2G ,D++@@ WWaLDGGdgg$5#:C"@477A,ODWWaLDGGdgg$5#:C"@477A,ODT'?@JAwT'?@JAw")7!3DRR(A!h&?&?&BBJBLLD$t'7'7'? gg		D,>,> >> 	&&{I>z!)F%%F]]_"F++A.CGGcAg%twwq'89jj3&t{{S/@+-u>F 	##F+rH   c                    ||| _         | j                         r| j                  |      sy | j                  |       | j	                  |       | j
                  X| j
                  j                  '| j                  | j                  | j
                  _        | j
                  j                  |       t        j                  | |       y rS   )	r   r   rH  r  r&  ra  r   ri  rp   r=  s     r#   ri  zAnnotation.draw  s     %DN!)A 	h'&&x0'&&.4;;3J*.++  '!!(+ 			$!rH   c                    | j                         r| j                  |      st        j                         S ||| _        | j                  | j
                  j                         | _        | j                  t        d      | j                  | j                         t        j                  |       }|g}| j                  )|j                  | j                  j                                t        j                  |      S )Nz%Cannot get window extent w/o renderer)r   rH  r   r  r   r   r  r  r  rp   r   ra  r   union)ry   r/   	text_bboxbboxess       r#   r   zAnnotation.get_window_extent  s     !)A99;%DN>>!![[668DN>>!FGGdnn-**40	'MM$**<<>?zz&!!rH   c                 l    | j                  |      st        j                         S t        |   |      S rS   )rH  r   nullr~   get_tightbbox)ry   r/   r   s     r#   r  zAnnotation.get_tightbbox  s+    ~~h'99;w$X..rH   )Nr  NNNrS   )r  r  r  r  rT  r   r   propertyr  setterrr  rv  ry  r  r|  r  r   r  ri  r   r  r  r  s   @r#   rR  rR  P  s    O    !%R2h   __" " # # \\" " "  <A BI%C,J "  "$"./ /rH   rR  )rR  )1r  	functoolsloggingrJ  numbersr   rK   numpyr&   
matplotlibr   r}   r   r   r   r   r	   font_managerr
   patchesr   r   r   textpathr   
transformsr   r   r   r   r   r   	getLoggerr  rf  r  r$   rG   rQ   	lru_cacherJ   interpddefine_aliasesrp   r   r  rR  r   r   r  rH   r#   <module>r     ss          - -  ( ? ? M M w" 9 96$&NC TP P U*01 6f;;* z)6 z) z)z%P PfB BJW/ W/t     Z%8%8%@%@  ArH   