rL iJdZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z mZmZddlmZdZd ZGd d ZGd d eZej,ej.ej.gZGddeZGddeZGddeZGddeZGddeZGddeZGddeZGddeZ GddeZ!Gd d!Z"Gd"d#e"eZ#Gd$d%e"eZ$d&Z%Gd'd(eZ&Gd)d*eZ'd+Z(Gd,d-eZ)Gd.d/eZ*e jVd0Gd1d2e*Z,Gd3d4eZ-Gd5d6eZ.Gd7d8eZ/Gd9d:eZ0Gd;de1Z2dDd?Z3d@Z4dEdAZ5dBZ6dFdCZ7y)GaT Matplotlib includes a framework for arbitrary geometric transformations that is used to determine the final position of all elements drawn on the canvas. Transforms are composed into trees of `TransformNode` objects whose actual value depends on their children. When the contents of children change, their parents are automatically invalidated. The next time an invalidated transform is accessed, it is recomputed to reflect those changes. This invalidation/caching approach prevents unnecessary recomputations of transforms, and contributes to better interactive performance. For example, here is a graph of the transform tree used to plot data to the figure: .. graphviz:: /api/transforms.dot :alt: Diagram of transform tree from data to figure coordinates. The framework can be used for both affine and non-affine transformations. However, for speed, we want to use the backend renderers to perform affine transformations whenever possible. Therefore, it is possible to perform just the affine or non-affine part of a transformation on a set of data. The affine is always assumed to occur after the non-affine. For any transform:: full transform == non-affine part + affine part The backends are not expected to handle non-affine transformations themselves. See the tutorial :ref:`transforms_tutorial` for examples of how to use transforms. N)inv)_api)affine_transformcount_bboxes_overlapping_bboxupdate_path_extents)PathFcjtjtjddfdS)a+ Generate a ``__str__`` method for a `.Transform` subclass. After :: class T: __str__ = _make_str_method("attr", key="other") ``str(T(...))`` will be .. code-block:: text {type(T).__name__}( {self.attr}, key={self.other}) z )prefixcNt|tr t|St|SN) isinstancestrrepr)xs [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/matplotlib/transforms.pystrreprz!_make_str_method..strreprIsjC&847Dc!fDctjdzdjgfdDfdjDzdzS)N(,c 3TK|]}dt|z!yw) Ngetattr).0argindentselfrs r z5_make_str_method....Ls/'TGGD#,>$??@'s%(c 3fK|](\}}d|zdzt|z*yw)r=Nr)rkrrrrs rr z5_make_str_method....Ns;4 !STAX^ggdC6H.IIJ4s.1))type__name__joinitems)rargsrkwargsrs`rz"_make_str_method..Jsd T c! ((5'!%'54$*LLN45 6 6   r) functoolspartialtextwrapr)r)r*rrs``@@r_make_str_methodr/7s("  xw ?FD rceZdZdZed\ZZZdZe jde jdZ dZ ddZerdZd Zd Zd Zd Zd ZdZdZy) TransformNodea' The base class for anything that participates in the transform tree and needs to invalidate its parents or be invalidated. This includes classes that are not really transforms, such as bounding boxes, since some transforms depend on bounding boxes to compute their values. F3.9cyNFclss rr+zTransformNode.erNcJi|_|j|_|xsd|_y)a Parameters ---------- shorthand_name : str A string representing the "name" of the transform. The name carries no significance other than to improve the readability of ``str(transform)`` when DEBUG=True. N)_parents _INVALID_FULL_invalid_shorthand_name)rshorthand_names r__init__zTransformNode.__init__ms% ** -3rc4|jxs t|Sr )r?rrs r__str__zTransformNode.__str__|s''54: 5rc i|jd|jjDcic] \}}||c}}iScc}}w)Nr<)__dict__r<r()rr#vs r __getstate__zTransformNode.__getstate__sJH$--H 0C0C0EF1QVFH HFsA c ||_|jjDcic]6\}}|/|tj||jj |fd8c}}|_ycc}}w)Nc||Sr r6_popr#s rr+z,TransformNode.__setstate__..s CFr)rFr<r(weakrefrefrM)r data_dictr#rGs r __setstate__zTransformNode.__setstate__sa!  ++-@1 w{{1DMM,=,=JK K@ @s;A*cLt|}|j|}|jj|ji|_t |j D]?\}}t|tst||jvs/|j|A|Sr ) r%__new__rFupdater<varsr(rr1id set_children)rr8otherkeyvals r__copy__zTransformNode.__copy__s4j C  dmm,T ((* (HC#}-"T(cll2J""3' ( rcx|j|jr|j|S|j|S)z Invalidate this `TransformNode` and triggers an invalidation of its ancestors. Should be called any time the transform changes. levelinvalidating_node)_invalidate_internal is_affine_INVALID_AFFINE_ONLYr=rCs r invalidatezTransformNode.invalidatesI ((/3~~$++")$ $CGCUCU")$ $rc||jkr |jsy||_t|jj D]}|}| |j ||!y)z Called by :meth:`invalidate` and subsequently ascends the transform stack calling each TransformNode's _invalidate_internal method. Nr])r> pass_throughlistr<valuesr`)rr^r_parents rr`z"TransformNode._invalidate_internalse DMM !$*;*;  4==//12 QFXF!++%4+P Qrct|}|D]?}tj||jj|fd}||j|<Ay)z Set the children of the transform, to let the invalidation system know which transforms can invalidate this transform. Should be called from the constructor of any transforms that depend on other transforms. c||Sr r6rKs rr+z,TransformNode.set_children..s 3q6rN)rVrNrOr<rM)rchildrenid_selfchildrOs rrWzTransformNode.set_childrensOT( *E++ENN$6$6'IKC&)ENN7 #  *rc|S)a Return a frozen copy of this transform node. The frozen copy will not be updated when its children change. Useful for storing a previously known state of a transform where ``copy.deepcopy()`` might normally be used. r6rCs rfrozenzTransformNode.frozens  rr )r& __module__ __qualname____doc__range_VALIDrbr=rar deprecated classpropertyis_bboxrerADEBUGrDrHrQr[rcr`rWror6rrr1r1Ss38(/F -I$odooe$%7T%7%78I%JKGL 4  6H @ $ Q*&rr1c eZdZdZej dej dZdZe re dZ dZ e je _dZedZed Zed Zed Zed Zed ZedZedZedZedZedZedZedZedZedZedZedZ edZ!edZ"dZ#dZ$dZ%dZ&dZ'd Z(d!Z)d"Z*d#Z+d$Z,d%d&d'd(d)d*d+d,d-d. Z-d/Z.d0Z/d>d2Z0d3Z1d4Z2d5Z3d6Z4d7Z5d?d8Z6d9Z7d:Z8d;Z9e d<Z:e d=Z;y1)@BboxBasea` The base class of all bounding boxes. This class is immutable; `Bbox` is a mutable subclass. The canonical representation is as two points, with no restrictions on their ordering. Convenience properties are provided to get the left, bottom, right and top edges and width and height, but these are not stored explicitly. r3cy)NTr6r7s rr+zBboxBase.r9rTc t|tjjrt j dtj |}t|dddf|dddfz dk(rt j dyy)NzBbox bounds are a masked array.rrzSingular Bbox.)rnpma MaskedArrayr warn_externalasarrayany)pointss r_checkzBboxBase._checksi&"%%"3"34""#DEZZ'FF1a4L6!Q$</A56""#347rcPt|jjSr )Bbox get_pointscopyrCs rrozBboxBase.frozensDOO%**,--rc"|jSr rrr)r*s r __array__zBboxBase.__array__s  rc(|jdS)z The first of the pair of *x* coordinates that define the bounding box. This is not guaranteed to be less than :attr:`x1` (for that, use :attr:`xmin`). rrrrCs rx0z BboxBase.x0 &&rc(|jdS)z The first of the pair of *y* coordinates that define the bounding box. This is not guaranteed to be less than :attr:`y1` (for that, use :attr:`ymin`). rrrrCs ry0z BboxBase.y0rrc(|jdS)z The second of the pair of *x* coordinates that define the bounding box. This is not guaranteed to be greater than :attr:`x0` (for that, use :attr:`xmax`). rrrrCs rx1z BboxBase.x1rrc(|jdS)z The second of the pair of *y* coordinates that define the bounding box. This is not guaranteed to be greater than :attr:`y0` (for that, use :attr:`ymax`). rrrrCs ry1z BboxBase.y1rrc(|jdS)z The first pair of (*x*, *y*) coordinates that define the bounding box. This is not guaranteed to be the bottom-left corner (for that, use :attr:`min`). rrrCs rp0z BboxBase.p0 ##rc(|jdS)z The second pair of (*x*, *y*) coordinates that define the bounding box. This is not guaranteed to be the top-right corner (for that, use :attr:`max`). rrrCs rp1z BboxBase.p1"rrcVtj|jdddfS)z"The left edge of the bounding box.Nrr}minrrCs rxminz BboxBase.xmin,#vvdoo'1-..rcVtj|jdddfS)z$The bottom edge of the bounding box.NrrrCs ryminz BboxBase.ymin1rrcVtj|jdddfS)z#The right edge of the bounding box.Nrr}maxrrCs rxmaxz BboxBase.xmax6rrcVtj|jdddfS)z!The top edge of the bounding box.NrrrCs rymaxz BboxBase.ymax;rrcLtj|jdS)z+The bottom-left corner of the bounding box.raxisrrCs rrz BboxBase.min@vvdoo'a00rcLtj|jdS)z)The top-right corner of the bounding box.rrrrCs rrz BboxBase.maxErrc0|jdddfS)z The pair of *x* coordinates that define the bounding box. This is not guaranteed to be sorted from left to right. NrrrCs r intervalxzBboxBase.intervalxJ A&&rc0|jdddfS)z The pair of *y* coordinates that define the bounding box. This is not guaranteed to be sorted from bottom to top. NrrrCs r intervalyzBboxBase.intervalySrrc8|j}|d|dz S)z'The (signed) width of the bounding box.rrrrrs rwidthzBboxBase.width\#"d|fTl**rc8|j}|d|dz S)z(The (signed) height of the bounding box.rrrrs rheightzBboxBase.heightbrrc8|j}|d|dz S)z2The (signed) width and height of the bounding box.rrrrs rsizez BboxBase.sizehs#"ay6!9$$rcL|j\\}}\}}||||z ||z fS)z?Return (:attr:`x0`, :attr:`y0`, :attr:`width`, :attr:`height`).rrrrrrs rboundszBboxBase.boundsns4"__.R(2rBRb))rc>|jjS)z8Return (:attr:`x0`, :attr:`y0`, :attr:`x1`, :attr:`y1`).)rflattenrCs rextentszBboxBase.extentsts ((**rctr NotImplementedErrorrCs rrzBboxBase.get_pointsys!!rcd|j\}}||cxkxr|kncxs||cxk\xr|k\ScS)zX Return whether *x* is in the closed (:attr:`x0`, :attr:`x1`) interval. rrrrrs r containsxzBboxBase.containsx|1BQ}"}-a 2 - -rcd|j\}}||cxkxr|kncxs||cxk\xr|k\ScS)zX Return whether *y* is in the closed (:attr:`y0`, :attr:`y1`) interval. rryrrs r containsyzBboxBase.containsyrrcJ|j|xr|j|S)zR Return whether ``(x, y)`` is in the bounding box or on its edge. )rrrrrs rcontainszBboxBase.containss!~~a 6T^^A%66rc|j\}}}}|j\}}}} ||kr||}}||kr||}}||kr||}}| |kr|| }} ||kxr||kxr || kxr||kS)z Return whether this bounding box overlaps with the other bounding box. Parameters ---------- other : `.BboxBase` r rrXax1ay1ax2ay2bx1by1bx2by2s roverlapszBboxBase.overlapss"\\S#s"]]S#s 9CC 9CC 9CC 9CCczFcSjFSCZFC3JFrcd|j\}}||cxkxr|kncxs||cxkDxr|kDScS)zV Return whether *x* is in the open (:attr:`x0`, :attr:`x1`) interval. rrs rfully_containsxzBboxBase.fully_containsx1BA{{)b1krk)k)rcd|j\}}||cxkxr|kncxs||cxkDxr|kDScS)zV Return whether *y* is in the open (:attr:`y0`, :attr:`y1`) interval. rrs rfully_containsyzBboxBase.fully_containsyrrcJ|j|xr|j|S)zV Return whether ``x, y`` is in the bounding box, but not on its edge. )rrrs rfully_containszBboxBase.fully_containss%##A&B4+?+?+BBrc|j\}}}}|j\}}}} ||kr||}}||kr||}}||kr||}}| |kr|| }} ||kxr||kxr || kxr||kS)z Return whether this bounding box overlaps with the other bounding box, not including the edges. Parameters ---------- other : `.BboxBase` rrs rfully_overlapszBboxBase.fully_overlapss"\\S#s"]]S#s 9CC 9CC 9CC 9CCSyBS3YB39BsBrc |j}|jtj|d|d|dg|d|dgg\}}}t ||d|dggS)zX Construct a `Bbox` by statically transforming this one by *transform*. rrrrrr)r transformr}arrayr)rrptsllullrs r transformedzBboxBase.transformedswoo(( Vc$iT+c$iT-C D*FG BR"Q%A())r)?rr)rr)?r)rr)rr)rr)rr)rr) CSWSSEENENNWWc|j\}}}}|j\}}} } t|tr|j|n|\} } t |j || || z zz|z || || z zz|z gzS)a Return a copy of the `Bbox` anchored to *c* within *container*. Parameters ---------- c : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', ...} Either an (*x*, *y*) pair of relative coordinates (0 is left or bottom, 1 is right or top), 'C' (center), or a cardinal direction ('SW', southwest, is bottom left, etc.). container : `Bbox` The box within which the `Bbox` is positioned. See Also -------- .Axes.set_anchor )rrrcoefsr_points) rc containerlbwhLBrHcxcys ranchoredzBboxBase.anchoreds"%% 1a[[ 1a",Q"4A!BDLL"A,&!+"A,&!+--. .rc|j\}}t|jd|jd||z||zgzgS)a Return a copy of the `Bbox`, shrunk by the factor *mx* in the *x* direction and the factor *my* in the *y* direction. The lower left corner of the box remains unchanged. Normally *mx* and *my* will be less than 1, but this is not enforced. r)rrr)rmxmyrrs rshrunkzBboxBase.shrunksJyy1T\\!_\\!_QQ'779: :rNc|dks|dkr td||}|j\}}||z|z }||kr|}n ||z|z }|}t|jd|jd||fzgS)a Return a copy of the `Bbox`, shrunk so that it is as large as it can be while having the desired aspect ratio, *box_aspect*. If the box coordinates are relative (i.e. fractions of a larger box such as a figure) then the physical aspect ratio of that figure is specified with *fig_aspect*, so that *box_aspect* can also be given as a ratio of the absolute dimensions, not the relative dimensions. rz.'box_aspect' and 'fig_aspect' must be positive) ValueErrorrrr)r box_aspectr fig_aspectrrrrs rshrunk_to_aspectzBboxBase.shrunk_to_aspects ?jAoMN N  I~~1 NZ ' 6AJ+AAT\\!_\\!_1v-/0 0rc dg|d}|j\}}}}||z }tj|D cgc]"\}} t|||zz|g|| |zz|gg$c} }Scc} }w)z Return a list of new `Bbox` objects formed by splitting the original one with vertical lines at fractional positions given by *args*. rrr itertoolspairwiser) rr)xfrrrrrxf0xf1s rsplitxzBboxBase.splitxs ]$]]BB G ) 2 22 68CrC!G|R(2a<*<=>8 88'A!c dg|d}|j\}}}}||z }tj|D cgc]"\}} t||||zzg||| |zzgg$c} }Scc} }w)z Return a list of new `Bbox` objects formed by splitting the original one with horizontal lines at fractional positions given by *args*. rrr) rr)yfrrrrryf0yf1s rsplityzBboxBase.splity&s ]$]]BB G ) 2 22 68Cr2a<(2rC!G|*<=>8 88rct|dk(rytj|}tjd5|j|k||j kzj djcdddS#1swYyxYw)z Count the number of vertices contained in the `Bbox`. Any vertices with a non-finite x or y value are ignored. Parameters ---------- vertices : (N, 2) array rignore)invalidrrN)lenr}rerrstaterrallsum)rverticess rcount_containszBboxBase.count_contains1sp x=A ::h' [[ * ?hh))+,/CQCK ? ? ?s =BB c t|tj|Dcgc]}tj|c}Scc}w)z Count the number of bounding boxes that overlap this one. Parameters ---------- bboxes : sequence of `.BboxBase` )rr} atleast_3dr)rbboxesrs rcount_overlapszBboxBase.count_overlapsAs7- "--f =! =>@ @ =sAc|j}|j}||z|z dz }||z|z dz }tj| | g||gg}t |j |zS)zr Construct a `Bbox` by expanding this one around its center by the factors *sw* and *sh*. g@)rrr}rrr)rswshrrdeltawdeltahas rexpandedzBboxBase.expandedLsq  u*u$+v+&#- HHw(66*:; <DLL1$%%rcV|j}||}t|| | g||ggzS)z Construct a `Bbox` by padding this one on all four sides. Parameters ---------- w_pad : float Width pad h_pad : float, optional Height pad. Defaults to *w_pad*. )rr)rw_padh_padrs rpaddedzBboxBase.paddedXs<" =EFvv.??@@rc6t|j||fzS)z>wGyy{    > rct|s tdtj|Dcgc]}|jc}}tj |Dcgc]}|j c}}tj|Dcgc]}|jc}}tj |Dcgc]}|jc}}t||g||ggScc}wcc}wcc}wcc}w)z8Return a `Bbox` that contains all of the given *bboxes*.z'bboxes' cannot be empty) r%rr}rrrrrrr)r-rHrrrrs runionzBboxBase.unions6{78 8 VV624TYY2 3 VV624TYY2 3 VV624TYY2 3 VV624TYY2 3b"XBx()) 3222sCC!C&1C+ctj|j|j}tj|j|j}tj|j |j }tj|j |j }||kr||krt||g||ggSdS)zr Return the intersection of *bbox1* and *bbox2* if they intersect, or None if they don't. N)r}maximumrminimumrrrr)bbox1bbox2rrrrs r intersectionzBboxBase.intersections ZZ EJJ / ZZ EJJ / ZZ EJJ / ZZ EJJ /-/2X"(tb"XBx()LLr)Nrr )r@rIrKrQr6rrrzrzs %odooe$%7T%7%78H%IJGI  5  5."**FN!''''''''$$$$////////1111''''++ ++ %% ** ++"..7 G(**C C** E.0 :00 8 8? @ &A"-B ** M MrrzczeZdZdZfdZer eZdZfdZfdZe dZ e dZ e dZ e d d d Z d Zd ZdZdZd)dZd*dZd*dZd)dZej.j0dZej2j0dZej4j0dZej6j0dZej8j0dZej:j0dZej<j0dZej>j0dZej@j0dZ e!dZ"e"j0dZ"e!dZ#e#j0d Z#e!d!Z$e$j0d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*xZ+S)+ra A mutable bounding box. Examples -------- **Create from known bounds** The default constructor takes the boundary "points" ``[[xmin, ymin], [xmax, ymax]]``. >>> Bbox([[1, 1], [3, 7]]) Bbox([[1.0, 1.0], [3.0, 7.0]]) Alternatively, a Bbox can be created from the flattened points array, the so-called "extents" ``(xmin, ymin, xmax, ymax)`` >>> Bbox.from_extents(1, 1, 3, 7) Bbox([[1.0, 1.0], [3.0, 7.0]]) or from the "bounds" ``(xmin, ymin, width, height)``. >>> Bbox.from_bounds(1, 1, 2, 6) Bbox([[1.0, 1.0], [3.0, 7.0]]) **Create from collections of points** The "empty" object for accumulating Bboxs is the null bbox, which is a stand-in for the empty set. >>> Bbox.null() Bbox([[inf, inf], [-inf, -inf]]) Adding points to the null bbox will give you the bbox of those points. >>> box = Bbox.null() >>> box.update_from_data_xy([[1, 1]]) >>> box Bbox([[1.0, 1.0], [1.0, 1.0]]) >>> box.update_from_data_xy([[2, 3], [3, 2]], ignore=False) >>> box Bbox([[1.0, 1.0], [3.0, 3.0]]) Setting ``ignore=True`` is equivalent to starting over from a null bbox. >>> box.update_from_data_xy([[1, 1]], ignore=True) >>> box Bbox([[1.0, 1.0], [1.0, 1.0]]) .. warning:: It is recommended to always specify ``ignore`` explicitly. If not, the default value of ``ignore`` can be changed at any time by code with access to your Bbox, for example using the method `~.Bbox.ignore`. **Properties of the ``null`` bbox** .. note:: The current behavior of `Bbox.null()` may be surprising as it does not have all of the properties of the "empty set", and as such does not behave like a "zero" object in the mathematical sense. We may change that in the future (with a deprecation period). The null bbox is the identity for intersections >>> Bbox.intersection(Bbox([[1, 1], [3, 7]]), Bbox.null()) Bbox([[1.0, 1.0], [3.0, 7.0]]) except with itself, where it returns the full space. >>> Bbox.intersection(Bbox.null(), Bbox.null()) Bbox([[-inf, -inf], [inf, inf]]) A union containing null will always return the full space (not the other set!) >>> Bbox.union([Bbox([[0, 0], [0, 0]]), Bbox.null()]) Bbox([[-inf, -inf], [inf, inf]]) c t|di|tj|t}|j dk7r t d||_tj|_ d|_ |jj|_ y)z Parameters ---------- points : `~numpy.ndarray` A (2, 2) array of the form ``[[x0, y0], [x1, y1]]``. rWz7Bbox points must be of the form "[[x0, y0], [x1, y1]]".TNr6) superrAr}rfloatshaperr_default_minposr_minpos_ignore _points_orig)rrr* __class__s rrAz Bbox.__init__sx "6"FE* <<6 !78 8 &++-  !LL--/rc L|j||j|fi|yr )r ___init__)rrr*s rrAz Bbox.__init__s! KK  DNN6 ,V ,rcX|j|jt| yr )rrrXrc)rr_s rrczBbox.invalidates KK % G  rcbt|}|jj|_|Sr )rXrominposrr\)r frozen_bboxr_s rroz Bbox.frozen s*gn& "kk..0 rc$tddgddggS)z/Create a new unit `Bbox` from (0, 0) to (1, 1).rr)rr6rrrDz Bbox.unitsaVaV$%%rcttjtjgtj tj ggS)z9Create a new null `Bbox` from (inf, inf) to (-inf, -inf).)rr}infr6rrnullz Bbox.nulls2bffbff%"&&'9:;;rc>tj||||z||zS)z{ Create a new `Bbox` from *x0*, *y0*, *width* and *height*. *width* and *height* may be negative. )r from_extents)rrrrs r from_boundszBbox.from_boundss#  ReR&[AArN)rdcfttj|d}|||jdd|S)a Create a new Bbox from *left*, *bottom*, *right* and *top*. The *y*-axis increases upwards. Parameters ---------- left, bottom, right, top : float The four extents of the bounding box. minpos : float or None If this is supplied, the Bbox will have a minimum positive value set. This is useful when dealing with logarithmic scales and other scales where negative bounds result in floating point errors. rVN)rr}reshaper\)rdr)rHs rrkzBbox.from_extents%s1 BJJtV,-  $DLLO rc&dj||S)Nz@Bbox(x0={0.x0:{1}}, y0={0.y0:{1}}, x1={0.x1:{1}}, y1={0.y1:{1}})format)rfmts r __format__zBbox.__format__:s N F4  rct|dS)Nr;rprCs rrDz Bbox.__str__?sdBrc$dj|S)Nz*Bbox([[{0.x0}, {0.y0}], [{0.x1}, {0.y1}]])rprCs r__repr__z Bbox.__repr__Bs;BB4HHrc||_y)a Set whether the existing bounds of the box should be ignored by subsequent calls to :meth:`update_from_data_xy`. value : bool - When ``True``, subsequent calls to `update_from_data_xy` will ignore the existing bounds of the `Bbox`. - When ``False``, subsequent calls to `update_from_data_xy` will include the existing bounds of the `Bbox`. N)r])rvalues rr#z Bbox.ignoreEs  rc| |j}|jjdk(ryt|d|j|j |\}}}|rn|j |r,|dddf|jdddf<|d|j d<|r-|dddf|jdddf<|d|j d<yyy)a Update the bounds of the `Bbox` to contain the vertices of the provided path. After updating, the bounds will have positive *width* and *height*; *x0* and *y0* will be the minimal values. Parameters ---------- path : `~matplotlib.path.Path` ignore : bool, optional - When ``True``, ignore the existing bounds of the `Bbox`. - When ``False``, include the existing bounds of the `Bbox`. - When ``None``, use the last value passed to :meth:`ignore`. updatex, updatey : bool, default: True When ``True``, update the x/y values. Nrr)r]r)rrrr\rc)rpathr#updatexupdateyrrdchangeds rupdate_from_pathzBbox.update_from_pathRs >\\F ==   " "5 $ dllF#<  OO %+AqD\ QT""() Q%+AqD\ QT""() Q rctj|}|jtj|tj|j g|dy)a Update the x-bounds of the `Bbox` based on the passed in data. After updating, the bounds will have positive *width*, and *x0* will be the minimal value. Parameters ---------- x : `~numpy.ndarray` Array of x-values. ignore : bool, optional - When ``True``, ignore the existing bounds of the `Bbox`. - When ``False``, include the existing bounds of the `Bbox`. - When ``None``, use the last value passed to :meth:`ignore`. F)r#r|Nr}ravelrE column_stackonesr)rrr#s rupdate_from_data_xzBbox.update_from_data_xtsE HHQK   !RWWQVV_1E!F(. ! ?rctj|}|jtjtj|j |g|dy)a Update the y-bounds of the `Bbox` based on the passed in data. After updating, the bounds will have positive *height*, and *y0* will be the minimal value. Parameters ---------- y : `~numpy.ndarray` Array of y-values. ignore : bool, optional - When ``True``, ignore the existing bounds of the `Bbox`. - When ``False``, include the existing bounds of the `Bbox`. - When ``None``, use the last value passed to :meth:`ignore`. F)r#r{Nr)rrr#s rupdate_from_data_yzBbox.update_from_data_ysE HHQK   "''!&&/11E!F(. ! ?rcbt|dk(ryt|}|j||||y)a Update the `Bbox` bounds based on the passed in *xy* coordinates. After updating, the bounds will have positive *width* and *height*; *x0* and *y0* will be the minimal values. Parameters ---------- xy : (N, 2) array-like The (x, y) coordinates. ignore : bool, optional - When ``True``, ignore the existing bounds of the `Bbox`. - When ``False``, include the existing bounds of the `Bbox`. - When ``None``, use the last value passed to :meth:`ignore`. updatex, updatey : bool, default: True When ``True``, update the x/y values. rN)r#r{r|)r%r r~)rxyr#r{r|rzs rrEzBbox.update_from_data_xys8$ r7a< Bx d6&-w  @rcB||jd<|jyNrrrcrrZs rrzBbox.x0  T rcB||jd<|jyNrrrs rrzBbox.y0rrcB||jd<|jyNrrrs rrzBbox.x1rrcB||jd<|jyNrrrs rrzBbox.y1rrcB||jd<|jyNrrrs rrzBbox.p0 Q rcB||jd<|jyNrrrs rrzBbox.p1rrcJ||jdddf<|jyrrrintervals rrzBbox.intervalx% QT rcJ||jdddf<|jyrrrs rrzBbox.intervalyrrc|\}}}}tj||g||z||zggt}tj|j|k7r||_|j yyr )r}rrYrrrc)rrrrrrrs rrz Bbox.boundss_ 1aAq6AE1q5>2E: 66$,,&( )!DL OO  *rc|jS)a The minimum positive value in both directions within the Bbox. This is useful when dealing with logarithmic scales and other scales where negative bounds result in floating point errors, and will be used as the minimum extent instead of *p0*. r\rCs rrdz Bbox.minposs||rc"||jddyr rrs rrdz Bbox.minposs Qrc |jdS)a# The minimum positive value in the *x*-direction within the Bbox. This is useful when dealing with logarithmic scales and other scales where negative bounds result in floating point errors, and will be used as the minimum *x*-extent instead of *x0*. rrrCs rminposxz Bbox.minposx||Arc"||jd<yrrrs rrz Bbox.minposx Qrc |jdS)a# The minimum positive value in the *y*-direction within the Bbox. This is useful when dealing with logarithmic scales and other scales where negative bounds result in floating point errors, and will be used as the minimum *y*-extent instead of *y0*. rrrCs rminposyz Bbox.minposyrrc"||jd<yrrrs rrz Bbox.minposy rrc(d|_|jS)zn Get the points of the bounding box as an array of the form ``[[x0, y0], [x1, y1]]``. r)r>rrCs rrzBbox.get_pointss  ||rcxtj|j|k7r||_|jyy)z Set the points of the bounding box directly from an array of the form ``[[x0, y0], [x1, y1]]``. No error checking is performed, as this method is mainly for internal use. N)r}rrrcrs r set_pointszBbox.set_pointss/ 66$,,&( )!DL OO  *rctj|j|jk7r&|j|_|j yy)zS Set this bounding box from the "frozen" bounds of another `Bbox`. N)r}rrrrcrrXs rsetzBbox.set"sA 66$,,%"2"2"44 5 ++-DL OO  6rcF|jxs|jS)z/Return whether the bbox has changed since init.)mutatedxmutatedyrCs rmutatedz Bbox.mutated*s}}1$--/1rc|jd|jdk7xs|jd|jdk7S)z4Return whether the x-limits have changed since init.rrrr^rCs rrz Bbox.mutatedx.D T"d&7&7&==> T"d&7&7&== ?rc|jd|jdk7xs|jd|jdk7S)z4Return whether the y-limits have changed since init.rrrrCs rrz Bbox.mutatedy3rr)NTTr ),r&rprqrrrArxrarcrorRrDrirlrkrsrDrvr#r~rrrErzrsetterrrrrrrrrrSrdrrrrrrrr __classcell__r_s@rrrs\N`0&   - ! &&<<BB#'(  I  ,D?&?&@2[[[[[[[[[[[[__ ]] ^^ ^^2? ?rrcTeZdZdZfdZeddZdZereZ dZdZ dZ xZ S) TransformedBboxz A `Bbox` that is automatically transformed by a given transform. When either the child bounding box or transform changes, the bounds of this bbox will update accordingly. c 0tjt|tjt||jdk7s|j dk7r t dt| di|||_ ||_ |j||d|_ y)ze Parameters ---------- bbox : `Bbox` transform : `Transform` rHrrWz8The input and output dimensions of 'transform' must be 2Nr6) rcheck_isinstancerz Transform input_dims output_dimsrrXrA_bbox _transformrWr)rrHrr*r_s rrAzTransformedBbox.__init__@s hT2 i9=   1 $ (=(=(BJL L "6" # $ * rrrch|jr|jj}|jj |d|dg|d|dg|d|dg|d|dgg}t j j|d}t|dddft|dddff}|d|dkDr|ddd}t|dddft|dddff}|d|dkDr|ddd}t j|d|dg|d|dgg|_ d|_|jS) Nrrrrrr) r>rrrrr}r~filledrrrr)rprxsyss rrzTransformedBbox.get_pointsUsT == %%'A__..D'1T7#D'1T7#D'1T7#D'1T7#%&F UU\\&#.FVAqD\"Cq!t $55Bw4 "XVAqD\"Cq!t $55Bw4 "X88A1A1%DL DM||rcH|j}|j||Sr  _get_pointsrrs rrzTransformedBbox.get_pointsv!%%'F KK Mrc|jj|jjj ||fSr )rrrinvertedrrs rrzTransformedBbox.contains{s5"tzz""DOO$<$<$>$H$H!Q$PQQrc|jj|jjj ||fSr )rrrrrrs rrzTransformedBbox.fully_containss7(tzz(($//*B*B*D*N*NPQSTv*VWWr) r&rprqrrrAr/rDrrxrrrrrs@rrr9s; &w 5G<    RXrrceZdZdZdfd ZeddZdZereZ dZe dZ e jdZ e d Z e jd Z e d Zejd Ze d ZejdZxZS) LockableBboxz A `Bbox` where some elements may be locked at certain values. When the child bounding box changes, the bounds of this bbox will update accordingly with the exception of the locked elements. c Dtjt|t |di|||_|j |d|_||||g}|Dcgc]}|du} }tjj|t| jd|_ ycc}w)a Parameters ---------- bbox : `Bbox` The child bounding box to wrap. x0 : float or None The locked value for x0, or None to leave unlocked. y0 : float or None The locked value for y0, or None to leave unlocked. x1 : float or None The locked value for x1, or None to leave unlocked. y1 : float or None The locked value for y1, or None to leave unlocked. rNmaskrVr6)rrrzrXrArrWrr}r~rrYrn_locked_points) rrHrrrrr*fprZrr_s rrAzLockableBbox.__init__s( hT2 "6"  $ "b" ')*t ** eekk"e$k?GGO+s Brrc|jr[|jj}tj|j j ||j |_d|_|jSr)r>rrr}whererrrrs rrzLockableBbox.get_pointssX ==ZZ**,F88D$7$7$<$<$*$($7$79DLDM||rcH|j}|j||Sr rrs rrzLockableBbox.get_pointsrrcT|jjdry|jdS)zB float or None: The value used for the locked x0. rNrrrCs r locked_x0zLockableBbox.locked_x0,    # #D )&&t, ,rc|du|jjd<||jjd<|jyrrrdatarc)rrs rrzLockableBbox.locked_x0<)+t  &)+  & rcT|jjdry|jdS)zB float or None: The value used for the locked y0. rNrrCs r locked_y0zLockableBbox.locked_y0rrc|du|jjd<||jjd<|jyrr)rrs rrzLockableBbox.locked_y0rrcT|jjdry|jdS)zB float or None: The value used for the locked x1. rNrrCs r locked_x1zLockableBbox.locked_x1rrc|du|jjd<||jjd<|jyrr)rrs rrzLockableBbox.locked_x1rrcT|jjdry|jdS)zB float or None: The value used for the locked y1. rNrrCs r locked_y1zLockableBbox.locked_y1rrc|du|jjd<||jjd<|jyrr)rrs rrzLockableBbox.locked_y1rr)NNNN)r&rprqrrrAr/rDrrxrrSrrrrrrrs@rrrs P:w(89G    -- -- -- --rrceZdZdZdZ dZ dZ dZ dZdZ dZ e dZ dZ d Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZddZdZy)ra The base class of all `TransformNode` instances that actually perform a transformation. All non-affine transformations should be subclasses of this class. New affine transformations should be subclasses of `Affine2D`. Subclasses of this class should override the following members (at minimum): - :attr:`input_dims` - :attr:`output_dims` - :meth:`transform` - :meth:`inverted` (if an inverse exists) The following attributes may be overridden if the default is unsuitable: - :attr:`is_separable` (defaults to True for 1D -> 1D transforms, False otherwise) - :attr:`has_inverse` (defaults to True if :meth:`inverted` is overridden, False otherwise) If the transform needs to do something non-standard with `matplotlib.path.Path` objects, such as adding curves where there were once line segments, it should override: - :meth:`transform_path` NFc6td|jDdk(r)|j|jcxk(rdk(r nnd|_td|jDdk(r2t |dr%|j tj urd|_yyyy)Nc36K|]}dt|vyw) is_separableNrUrrhs rr z.Transform.__init_subclass__..2sI6$v,.IrTc36K|]}dt|vyw) has_inverseNrrs rr z.Transform.__init_subclass__..8sH& f-Hrr) r(__mro__rrrhasattrrrrr7s r__init_subclass__zTransform.__init_subclass__-s IS[[I IQ NNNcoo::#C  HCKKH HA MC,LL (:(::"CO;- NrcFt|tr t||StS)z Compose two transforms together so that *self* is followed by *other*. ``A + B`` returns a transform ``C`` so that ``C.transform(x) == B.transform(A.transform(x))``. )rrcomposite_transform_factoryNotImplementedrs r__add__zTransform.__add__=s'eY/,D%8  rc#(Kt|fyw)a Return an iterator breaking down this transform stack from left to right recursively. If self == ((A, N), A) then the result will be an iterator which yields I : ((A, N), A), followed by A : (N, A), followed by (A, N) : (A), but not ((A, N), A) : I. This is equivalent to flattening the stack then yielding ``flat_stack[:i], flat_stack[i:]`` where i=0..(n-1). NIdentityTransformrCs r_iter_break_from_left_to_rightz(Transform._iter_break_from_left_to_rightLs !4''scy)a Return the number of transforms which have been chained together to form this Transform instance. .. note:: For the special case of a Composite transform, the maximum depth of the two is returned. rr6rCs rdepthzTransform.depthXsrcv|j|jkry|jD] \}}||k(s yy)aQ Return whether the given transform is a sub-tree of this transform. This routine uses transform equality to identify sub-trees, therefore in many situations it is object id which will be used. For the case where the given transform represents the whole of this transform, returns True. FT)rr)rrXrLsub_trees rcontains_branchzTransform.contains_branchfsE :: # >>@ KAx5  rc`|jdk7r td|j|fdzS)aU Return whether the given branch is a sub-tree of this transform on each separate dimension. A common use for this method is to identify if a transform is a blended transform containing an Axes' data transform. e.g.:: x_isdata, y_isdata = trans.contains_branch_seperately(ax.transData) rWLcontains_branch_seperately only supports transforms with 2 output dimensions)rrrrother_transforms rcontains_branch_seperatelyz$Transform.contains_branch_seperatelyysB   q CD D$$_581<??!))++  ,   %..** *23 3rc>|jjS)z9Array interface to get at this Transform's affine matrix. get_affine get_matrixrs rrzTransform.__array__ ++--rctj|}|j}|jd|jf}|j |j |}|dk(r&tjj|rJ|dS|dk(r|jdS|dk(r|Stdj|j)a Apply this transformation on the given array of *values*. Parameters ---------- values : array-like The input values as an array of length :attr:`input_dims` or shape (N, :attr:`input_dims`). Returns ------- array The output values as an array of length :attr:`output_dims` or shape (N, :attr:`output_dims`), depending on the input. rrrrrWz5Input values must have shape (N, {dims}) or ({dims},))dims) r} asanyarrayndimrnrtransform_affinetransform_non_affiner~ is_maskedrrq)rrgrress rrzTransform.transforms$v&{{T__ 56##D$=$=f$EF 19uus+ ++t9  19;;r? " QYJ C VV )+ +rc@|jj|S)a Apply only the affine part of this transformation on the given array of values. ``transform(values)`` is always equivalent to ``transform_affine(transform_non_affine(values))``. In non-affine transformations, this is generally a no-op. In affine transformations, this is equivalent to ``transform(values)``. Parameters ---------- values : array The input values as an array of length :attr:`input_dims` or shape (N, :attr:`input_dims`). Returns ------- array The output values as an array of length :attr:`output_dims` or shape (N, :attr:`output_dims`), depending on the input. rrrrgs rrzTransform.transform_affines0 **622rc|S)a Apply only the non-affine part of this transformation. ``transform(values)`` is always equivalent to ``transform_affine(transform_non_affine(values))``. In non-affine transformations, this is generally equivalent to ``transform(values)``. In affine transformations, this is always a no-op. Parameters ---------- values : array The input values as an array of length :attr:`input_dims` or shape (N, :attr:`input_dims`). Returns ------- array The output values as an array of length :attr:`output_dims` or shape (N, :attr:`output_dims`), depending on the input. r6rs rrzTransform.transform_non_affines . rcRt|j|jS)z Transform the given bounding box. For smarter transforms including caching (a common requirement in Matplotlib), see `TransformedBbox`. )rrr)rrHs rtransform_bboxzTransform.transform_bboxsDNN4??#4566rctS)z&Get the affine part of this transform.rrCs rrzTransform.get_affine"s  ""rc>|jjS)z5Get the matrix for the affine part of this transform.rrCs rrzTransform.get_matrix&rrcjt||jk7r td|j|S)a Return a transformed point. This function is only kept for backcompatibility; the more general `.transform` method is capable of transforming both a list of points and a single point. The point is given as a sequence of length :attr:`input_dims`. The transformed point is returned as a sequence of length :attr:`output_dims`. z/The length of 'point' must be 'self.input_dims')r%rrr)rpoints rtransform_pointzTransform.transform_point*s/ u: (NO O~~e$$rcB|j|j|S)z Apply the transform to `.Path` *path*, returning a new `.Path`. In some cases, this transform may insert curves into the path that began as line segments. )transform_path_affinetransform_path_non_affinerrzs rtransform_pathzTransform.transform_path:s ))$*H*H*NOOrc@|jj|S)z Apply the affine part of this transform to `.Path` *path*, returning a new `.Path`. ``transform_path(path)`` is equivalent to ``transform_path_affine(transform_path_non_affine(values))``. )rr)r+s rr)zTransform.transform_path_affineCs 66t<)r&rprqrrrrrrrrrrSrrr rrrrrr"rrr'r,r)r*r>rr6rrrrs:J K LJKG#   (  &=$03d.#+J3427#.% P= D/b $rrceZdZdZdZfdZdZedZdZ dZ e dZ e d Z e d Ze d Ze d ZxZS) TransformWrappera A helper class that holds a single child transform and acts equivalently to it. This is useful if a node of the transform tree must be replaced at run time with a transform of a different type. This class allows that replacement to correctly trigger invalidation. `TransformWrapper` instances must have the same input and output dimensions during their entire lifetime, so the child transform may only be replaced with another child transform of the same dimensions. Tcztjt|t||j |y)zn *child*: A `Transform` instance. This child may later be replaced with :meth:`set`. )rmN)rrrrXrAr)rrmr_s rrAzTransformWrapper.__init__s+ iu5  rc8|jj|Sr )_child__eq__rs rrEzTransformWrapper.__eq__s{{!!%((rrDc6|jjSr )rDrorCs rrozTransformWrapper.frozens{{!!##rct|dr|j|j|jf}|jj|jjf}||k7rt d|d||jj jt|d||_|j||j|_ |j|_ |j|_ |j|_ |j|_|j|_|j |_|j"|_|j$|_d|_|jd|_y)z Replace the current child of this transform with another one. The new child must have the same number of input and output dimensions as the current child. rDz+The input and output dims of the new child z% do not match those of current child Nr)rrcrrrDrr<rMrVrWrrrr,r)r*rrrr>)rrmnew_dimsold_dimss rrzTransformWrapper.sets@ 4 " OO ((%*;*;$>!#22%*%@%@").)H)H&** **    rc.|jjSr )rDrrCs rr+zTransformWrapper.st{{'='=rc.|jjSr )rDrrCs rr+zTransformWrapper. (?(?rc.|jjSr )rDrarCs rr+zTransformWrapper.sdkk&;&;rc.|jjSr )rDrrCs rr+zTransformWrapper.s)A)Arc.|jjSr )rDrrCs rr+zTransformWrapper.rLr)r&rprqrrrerArEr/rDrorrSrrrarrrrs@rrArAsi L)x(G$#J=>J?@K;rr?rBr)rrer@s rrzAffine2DBase.invertedNs_ >> !T]]//#C!N##!)D,@,@!@%c#h~NDNDM~~rN)r&rprqrrrrrorSrrjrrxrprr6rrrarasKJK2--2- , 2 rraceZdZdZdfd ZedZdZedZ dZ dZ dZ d Z d Zd Zd Zd ZdZddZdZdZxZS)rBz- A mutable 2D affine transformation. c t|di||tj}|j |_d|_y)z Initialize an Affine transform from a 3x3 numpy float array:: a c e b d f 0 0 1 If *matrix* is None, initialize with the identity transform. Nrr6)rXrAr_mtxrr>)rmatrixr*r_s rrAzAffine2D.__init___s9 "6" >&++FKKM  rrtcf|jtjtj|jk7jr|j S|jd|jdk7r#d|jdd|jddSd|jddS)NrrzAffine2D().scale(z, r$)rtr}diagr _base_strrCs rrDzAffine2D.__str__rsII);!<<AAC  =99T?diio5)4(9DIIdO;LAN =)4(9;  =rc xttj||||||dddg tj dS)z Create a new Affine2D instance from the given values:: a c e b d f 0 0 1 . rr)r2r2)rBr}rrYrn)r4rrr=efs r from_valueszAffine2D.from_valuesys? HHaAq!QS#6 > F Fv NP PrcN|jrd|_d|_|jS)z Get the underlying transformation matrix as a 3x3 array:: a c e b d f 0 0 1 . Nr)r>rSrtrCs rrzAffine2D.get_matrixs# ==!DNDMyyrc2||_|jy)z Set the underlying transformation matrix from a 3x3 array:: a c e b d f 0 0 1 . Nrtrcrds r set_matrixzAffine2D.set_matrixs  rctjt||j|_|j y)zh Set this transformation from the frozen copy of another `Affine2DBase` object. )rXN)rrrarrtrcrs rrz Affine2D.sets. l%8$$&  rcltjj|_|j|S)zH Reset the underlying matrix to the identity transform. )rrtrrcrCs rclearzAffine2D.clears) &**//1   rcrtj|}tj|}|j}|j \\}}}\}} } } ||z||zz |d<||z|| zz |d<||z|| zz |d<||z||zz|d<||z|| zz|d<||z|| zz|d<|j |S)z Add a rotation (in radians) to this transform in place. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. rrrrWrrrrW)mathr5r6rttolistrc) rthetar4rrexxrryxyyrrLs rrCzAffine2D.rotates HHUO HHUOii(+ % Rlr2rAFQVOD FQVOD FQVOD FQVOD FQVOD FQVOD   rcJ|jtj|S)z Add a rotation (in degrees) to this transform in place. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. )rCrrF)rdegreess r rotate_degzAffine2D.rotate_degs{{4<<011rch|j| | j|j||S)z Add a rotation (in radians) around the point (x, y) in place. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. ) translaterC)rrrrs r rotate_aroundzAffine2D.rotate_arounds1~~qb1"%,,U3==aCCrct|t|}}|j| | j|j||S)z Add a rotation (in degrees) around the point (x, y) in place. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. )rYrr)rrrrs rrotate_deg_aroundzAffine2D.rotate_deg_aroundsBQxq1~~qb1"%009CCAqIIrc|jdxx|z cc<|jdxx|z cc<|j|S)z Add a translation in place. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. rrrr;s rrzAffine2D.translates7 $2 $2  rcB||}|jdxx|zcc<|jdxx|zcc<|jdxx|zcc<|jdxx|zcc<|jdxx|zcc<|jdxx|zcc<|j|S)a2 Add a scale in place. If *sy* is None, the same scale is applied in both the *x*- and *y*-directions. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. rrrrrrr)rsxsys rscalezAffine2D.scales :B $2 $2 $2 $2 $2 $2  rctj|}tj|}|j}|j\\}}}\} } } } |dxx|| zz cc<|dxx|| zz cc<|dxx|| zz cc<|dxx||zz cc<|dxx||zz cc<|dxx||zz cc<|j |S)aC Add a skew in place. *xShear* and *yShear* are the shear angles along the *x*- and *y*-axes, respectively, in radians. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. rrrrrr)rtanrtrrc) rxShearyShearrxryrerrrrrrrLs rskewz Affine2D.skewsXXf  XXf ii(+ % Rlr2rA D R"W  D R"W  D R"W  D R"W  D R"W  D R"W   rcr|jtj|tj|S)aC Add a skew in place. *xShear* and *yShear* are the shear angles along the *x*- and *y*-axes, respectively, in degrees. Returns *self*, so this method can easily be chained with more calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. )rrrF)rrrs rskew_degzAffine2D.skew_deg*s'yyf-t||F/CDDrr )r&rprqrrrAr/rxrDrRr|rrrrrCrrrrrrrrrs@rrBrBZss"!(I= P P  .2D J .4 ErrBc~eZdZdZej dZdZeZ dZ dZ dZ dZ dZd Zd Zd Zd Zy )rzY A special class that does one thing, the identity transform, in a fast way. r2c|Sr r6rCs rrozIdentityTransform.frozen?r^rc|jSr )rtrCs rrzIdentityTransform.get_matrixEs yyrc,tj|Sr r}rrs rrzIdentityTransform.transformI}}V$$rc,tj|Sr rrs rrz"IdentityTransform.transform_affineMrrc,tj|Sr rrs rrz&IdentityTransform.transform_non_affineQrrc|Sr r6r+s rr,z IdentityTransform.transform_pathUr^rc|Sr r6r+s rr)z'IdentityTransform.transform_path_affineYr^rc|Sr r6r+s rr*z+IdentityTransform.transform_path_non_affine]r^rc|Sr r6rCs rrzIdentityTransform.get_affinear^rc|Sr r6rCs rrzIdentityTransform.inverteder^rN)r&rprqrrr}identityrtror/rDrrrrr,r)r*rrr6rrrr8sT 2;;q>D G%%%rrc.eZdZdZdZdZeddZy) _BlendedMixinzCCommon methods for `BlendedGenericTransform` and `BlendedAffine2D`.ct|ttfr4|j|jk(xr|j|jk(S|j|jk(r|j|k(St Sr )rBlendedAffine2DBlendedGenericTransform_x_yrrs rrEz_BlendedMixin.__eq__ms\ eo/FG HGGuxx'Bdgg.A B WW 77e# #! !rcn|jj||jj|fSr )rrr)rrs rr z(_BlendedMixin.contains_branch_seperatelyus0'' 2'' 24 4rrrN)r&rprqrrrEr r/rDr6rrrrjsM"4tT*GrrcxeZdZdZdZdZdZdZdZe dZ dZ e dZ e dZ d Zd Zd Zd Zy )rz A "blended" transform uses one transform for the *x*-direction, and another transform for the *y*-direction. This "generic" version can handle any given child transform in the *x*- and *y*-directions. rWTc ~tj|fi|||_||_|j ||d|_y)ak Create a new "blended" transform using *x_transform* to transform the *x*-axis and *y_transform* to transform the *y*-axis. You will generally not call this constructor directly but use the `blended_transform_factory` function instead, which can determine automatically which kind of blended transform to create. N)rrArrrW_affine)r x_transform y_transformr*s rrAz BlendedGenericTransform.__init__s< 4*6* +{3 rcjt|jj|jjSr )rrrrrCs rrzBlendedGenericTransform.depths477==$''--00rcyr5r6rs rrz'BlendedGenericTransform.contains_branchsrc^|jjxr|jjSr )rrarrCs rr+z BlendedGenericTransform.dgg&7&7&MDGGTWW((@TWW-@-@rczt|jj|jjSr )blended_transform_factoryrrorrCs rrozBlendedGenericTransform.frozens%()9477>>;KLLrcT|jjr|jjr|S|j}|j}||k(r |jdk(r|j |S|jdk(r|j |ddddf}n4|j |dddf}|j t |df}|jdk(r|j |ddddf}n4|j |dddf}|j t |df}t|tjjs$t|tjjr"tjj||fdStj||fdS)NrWrr) rrarrrrnr%rr}r~r concatenate)rrgrrx_pointsy_pointss rrz,BlendedGenericTransform.transform_non_affinesa 77  !2!2M GG GG 6alla'))&1 1 <<1 --f5a1f=H--fQTl;H''X(:;H <<1 --f5ae>8X"6: :rczt|jj|jjSr )rrrrrCs rrz BlendedGenericTransform.inverteds)&tww'7'7'9477;K;K;MNNrc|js |j|j|jk(r |jj |_n|jj j }|jj j }t j|d|dgdg}t||_d|_|jSNrrrrr) r>rrrrrr}rrB)rx_mtxy_mtxres rrz"BlendedGenericTransform.get_affines ==DLL0ww$''!#ww113 **,779**,779hha%(ODE'} DM||rN)r&rprqrrrrrrerArSrrrarrorrrr6rrrr|slJKLL 11 MNI@BKM;8O rrc eZdZdZdZdZdZy)rz A "blended" transform uses one transform for the *x*-direction, and another transform for the *y*-direction. This version is an optimization for the case where both child transforms are of type `Affine2DBase`. Tc 6|jxr |j}|jxr |j}|xr|}|s tdtj|fi|||_||_|j||tj |d|_ y)a Create a new "blended" transform using *x_transform* to transform the *x*-axis and *y_transform* to transform the *y*-axis. Both *x_transform* and *y_transform* must be 2D affine transforms. You will generally not call this constructor directly but use the `blended_transform_factory` function instead, which can determine automatically which kind of blended transform to create. zABoth *x_transform* and *y_transform* must be 2D affine transformsN) rarrrrArrrWrart)rrrr*rar is_corrects rrAzBlendedAffine2D.__init__s ))Ck.C.C "//LK4L4L /< 12 2 4*6* +{3d# rcr|jr|j|jk(r |jj|_nY|jj}|jj}t j |d|dgdg|_d|_d|_|jSr)r>rrrrtr}rrS)rrrs rrzBlendedAffine2D.get_matrixs ==ww$''! GG..0 **,**,HHeAha/%JK !DNDMyyrN)r&rprqrrrrArr6rrrrsL4 rrcrt|trt|tr t||St||S)z Create a new "blended" transform using *x_transform* to transform the *x*-axis and *y_transform* to transform the *y*-axis. A faster version of the blended transform is returned for the case where both child transforms are affine. )rrarr)rrs rrr s2 ; - {L 1{K88 "; <rrrorrr)rros rroz CompositeGenericTransform.frozen: sJ , GGNN dggnn.0&";<==? " rc||jur&|jjstj}t |||yr )rrrarr=rXr`)rr^r_r_s rr`z.CompositeGenericTransform._invalidate_internalC s8  '0A0A++E $U,=>rct|ttfr:||uxs4|j|jk(xr|j|jk(Syr5)rrCompositeAffine2Drrrs rrEz CompositeGenericTransform.__eq__J sM e79JK L5=>TWW%8&=)-EHH)< >rc#K|jjD]\}}|||jzf|jjD]\}}|j|z|fywr rrrrleftrights rrz8CompositeGenericTransform._iter_break_from_left_to_rightQ l77AAC (KD%' ' (77AAC (KD%''D.%' ' (A,A.cx|jdk7r td||k(ry|jj|S)NrWr )TT)rrrr r s rr z4CompositeGenericTransform.contains_branch_seperatelyW sE   q CD D ? "ww11/BBrc\|jj|jjzSr rrrrCs rr+z"CompositeGenericTransform.` s$''--$''--"?rc^|jjxr|jjSr )rrarrCs rr+z"CompositeGenericTransform.a rrc^|jjxr|jjSr )rrrrCs rr+z"CompositeGenericTransform.c sTWW))Bdgg.B.Brc^|jjxr|jjSr )rrrrCs rr+z"CompositeGenericTransform.e rrrrc@|jj|Sr rrs rrz*CompositeGenericTransform.transform_affinei s **622rcT|jjr|jjr|S|jjs1|jjr|jj|S|jj|jj |Sr )rrarrrrs rrz.CompositeGenericTransform.transform_non_affinem sr 77  !2!2M""tww'8'877//7 777//0A0A&0IJ JrcT|jjr|jjr|S|jjs1|jjr|jj|S|jj|jj |Sr )rrarr*r,r+s rr*z3CompositeGenericTransform.transform_path_non_affinev sy 77  !2!2K""tww'8'87744T: :7744$(GG$:$:4$@B Brc8|jjs|jjStt j |jjj |jjj Sr )rrarrBr}dotrrrCs rrz$CompositeGenericTransform.get_affine snww  77%%' 'BFF477#5#5#7#B#B#D#'77#5#5#7#B#B#DFG Grczt|jj|jjSr )rrrrrCs rrz"CompositeGenericTransform.inverted s.( GG    0 0 24 4r)r&rprqrrrerAror`rErr rSrrarrr/rDrrr*rrrrs@rrr sL (?( C ? @EMNIBDL@BKtT*G3KBG4rrcPeZdZdZfdZedZdZeddZ dZ xZ S)rz A composite transform formed by applying transform *a* then transform *b*. This version is an optimization that handles the case where both *a* and *b* are 2D affines. c D|jr |js td|j|jk7r td|j|_|j|_t |di|||_||_|j||d|_ y)aJ Create a new composite transform that is the result of applying `Affine2DBase` *a* then `Affine2DBase` *b*. You will generally not call this constructor directly but write ``a + b`` instead, which will automatically choose the best kind of composite transform instance to create. z%'a' and 'b' must be affine transformsrNr6) rarrrrXrArrrWrtrs rrAzCompositeAffine2D.__init__ s{{!++DE E ==ALL (;< <,,== "6" !Q rc\|jj|jjzSr rrCs rrzCompositeAffine2D.depth sww}}tww}},,rc#K|jjD]\}}|||jzf|jjD]\}}|j|z|fywr rrs rrz0CompositeAffine2D._iter_break_from_left_to_right rrrrc|jrYtj|jj |j j |_d|_d|_|j Sr)r>r}rrrrrtrSrCs rrzCompositeAffine2D.get_matrix sS ==""$""$&DI"DNDMyyr) r&rprqrrrArSrrr/rDrrrs@rrr s9 .--( tT*Grrct|tr|St|tr|St|trt|tr t||St ||S)av Create a new composite transform that is the result of applying transform a then transform b. Shortcut versions of the blended transform are provided for the case where both child transforms are affine, or one or the other is the identity transform. Composite transforms may also be created using the '+' operator, e.g.:: c = a + b )rrrBrr)r4rs rrr sQ$!&' A( ) Ax Z8%< A&& $Q **rc>eZdZdZdZfdZeddZdZxZ S) BboxTransformzP `BboxTransform` linearly transforms points from one `Bbox` to another. Tc tjt||t|di|||_||_|j||d|_d|_ y)zp Create a new `BboxTransform` that linearly transforms points from *boxin* to *boxout*. )boxinboxoutNr6) rrrzrXrA_boxin_boxoutrWrtrS)rrrr*r_s rrAzBboxTransform.__init__ sS heFC "6"   %( rrrct|jr|jj\}}}}|jj\}}}}||z } ||z } tr| dk(s| dk(r t dt j| d| | z|zgd| | | z|zggdgt|_ d|_ d|_|jS)Nrz/Transforming from or to a singular bounding boxrr) r>rrrrxrr}rrYrtrS) rinlinbinwinhoutloutboutwouthx_scaley_scales rrzBboxTransform.get_matrix s ==!%!3!3 Cc3%)\\%8%8 "D$dSjGSjG'Q,'Q, EGG7cT'\$5F"G'*GcT'\$5F"G"G"I"'(DI"DNDMyyr r&rprqrrrrAr/rDrrrs@rrr s'L x3Grrc<eZdZdZdZfdZedZdZxZ S)BboxTransformToz `BboxTransformTo` is a transformation that linearly transforms points from the unit bounding box to a given `Bbox`. Tc tjt|t|di|||_|j |d|_d|_y)z Create a new `BboxTransformTo` that linearly transforms points from the unit bounding box to *boxout*. )rNr6) rrrzrXrArrWrtrS)rrr*r_s rrAzBboxTransformTo.__init__ sH hv6 "6"  &! rrc|jrn|jj\}}}}tr|dk(s|dk(r t dt j |d|gd||ggdgt|_d|_ d|_|jSNrz(Transforming to a singular bounding box.rr) r>rrrxrr}rrYrtrS)rrrrrs rrzBboxTransformTo.get_matrix s ==%)\\%8%8 "D$d$!)tqy !KLL4#t"4$'t"4"4"6"'(DI"DNDMyyrr rs@rr r  s% L y)G rr r3ceZdZdZdZy)BboxTransformToMaxOnlyz `BboxTransformToMaxOnly` is a transformation that linearly transforms points from the unit bounding box to a given `Bbox` with a fixed upper left of (0, 0). c |jrl|jj\}}tr|dk(s|dk(r t dt j |ddgd|dggdgt|_d|_ d|_|jSr) r>rrrxrr}rrYrtrS)rrrs rrz!BboxTransformToMaxOnly.get_matrix4 s ==))JD$$!)tqy !KLL4#s"3$'s"3"3"5"'(DI"DNDMyyrN)r&rprqrrrr6rrrr. s  rrc<eZdZdZdZfdZedZdZxZ S)BboxTransformFromzj `BboxTransformFrom` linearly transforms points from a given `Bbox` to the unit bounding box. Tc tjt|t|di|||_|j |d|_d|_y)N)rr6) rrrzrXrArrWrtrS)rrr*r_s rrAzBboxTransformFrom.__init__J sF he4 "6"  %  rrc2|jr|jj\}}}}tr|dk(s|dk(r t dd|z }d|z }t j |d| |zgd|| |zggdgt|_d|_ d|_|jS)Nrz*Transforming from a singular bounding box.rrr) r>rrrxrr}rrYrtrS)rrrrrr r s rrzBboxTransformFrom.get_matrixU s ==!%!3!3 Cc3#(cQh !MNNCiGCiG7cT'\"B'*GcT'\"B"B"D"'(DI"DNDMyyrr rs@rrrC s%Lx(Grrc8eZdZdZfdZedZdZxZS)ScaledTranslationz| A transformation that translates by *xt* and *yt*, after *xt* and *yt* have been transformed by *scale_trans*. c t|di|||f|_||_|j |d|_d|_yNr6)rXrA_t _scale_transrWrtrS)rxtyt scale_transr*r_s rrAzScaledTranslation.__init__k sB "6"r(' +& rrc|jrgtjj|_|jj |j |jdddf<d|_d|_|jS)NrWr)r>rrtrrrrrSrCs rrzScaledTranslation.get_matrixu sb ==)..335DI#00::477CDIIbqb!e DM!DNyyr) r&rprqrrrAr/rDrrrs@rrrf st$Grrc(eZdZdZfdZdZxZS)_ScaledRotationz^ A transformation that applies rotation by *theta*, after transform by *trans_shift*. cLt|||_||_d|_yr )rXrA_theta _trans_shiftrt)rr trans_shiftr_s rrAz_ScaledRotation.__init__ s$  ' rc|jr^|jj|jdggd}|d}t j |}|j |_|jSr)r>r&rr%rBrCrrt)rtransformed_coordsadjusted_thetarotations rrz_ScaledRotation.get_matrix sh ==!%!2!2!N=O!PQR!S /2Nz((8H ++-DIyyr)r&rprqrrrArrrs@rr#r# s rr#c<eZdZdZdZfdZedZdZxZ S)AffineDeltaTransformav A transform wrapper for transforming displacements between pairs of points. This class is intended to be used to transform displacements ("position deltas") between pairs of points (e.g., as the ``offset_transform`` of `.Collection`\s): given a transform ``t`` such that ``t = AffineDeltaTransform(t) + offset``, ``AffineDeltaTransform`` satisfies ``AffineDeltaTransform(a - b) == AffineDeltaTransform(a) - AffineDeltaTransform(b)``. This is implemented by forcing the offset components of the transform matrix to zero. This class is experimental as of 3.3, and the API may change. Tc Tt|di|||_|j|yr)rXrA_base_transformrW)rrr*r_s rrAzAffineDeltaTransform.__init__ s) "6"( )$rr/c|jr@|jjj|_d|jdddf<|jS)NrrWr)r>r/rrrtrCs rrzAffineDeltaTransform.get_matrix sH ==,,779>>@DI !DIIbqb"f yyr) r&rprqrrrerAr/rDrrrs@rr-r- s& L% 01Grr-c@eZdZdZfdZdZdZdZdZdZ xZ S)TransformedPathaa A `TransformedPath` caches a non-affine transformed copy of the `~.path.Path`. This cached copy is automatically updated when the non-affine part of the transform changes. .. note:: Paths are considered immutable by this class. Any update to the path's vertices/codes will not trigger a transform recomputation. ctjt|t|||_||_|j|d|_d|_ y)zl Parameters ---------- path : `~.path.Path` transform : `Transform` rN) rrrrXrA_pathrrW_transformed_path_transformed_points)rrzrr_s rrAzTransformedPath.__init__ sL i9=  # )$!%#' rcV|j|jk(s |j}|jj |j |_t j|jj|j jd|j |_ d|_yr) r>r=r5rr*r4r r/rr)r6rCs r _revalidatezTransformedPath._revalidate s MMT// /))199$**E  "//OO889L9LM$**&  $ rcZ|j|j|jfS)a3 Return a copy of the child path, with the non-affine part of the transform already applied, along with the affine part of the path necessary to complete the transformation. Unlike :meth:`get_transformed_path_and_affine`, no interpolation will be performed. )r8r6rrCs r!get_transformed_points_and_affinez1TransformedPath.get_transformed_points_and_affine s( ''):::rcZ|j|j|jfS)z Return a copy of the child path, with the non-affine part of the transform already applied, along with the affine part of the path necessary to complete the transformation. )r8r5rrCs rget_transformed_path_and_affinez/TransformedPath.get_transformed_path_and_affine s( %%t'888rcl|j|jj|jS)zD Return a fully-transformed copy of the child path. )r8rr)r5rCs rget_fully_transformed_pathz*TransformedPath.get_fully_transformed_path s+ 44T5K5KLLrc6|jjSr )rrrCs rrzTransformedPath.get_affine s))++r) r&rprqrrrAr8r:r<r>rrrs@rr2r2 s'  (  ;9M,rr2c,eZdZdZfdZfdZxZS)TransformedPatchPathz A `TransformedPatchPath` caches a non-affine transformed copy of the `~.patches.Patch`. This cached copy is automatically updated when the non-affine part of the transform or the patch changes. clt||j|j||_y)zQ Parameters ---------- patch : `~.patches.Patch` N)rXrAget_path get_transform_patch)rpatchr_s rrAzTransformedPatchPath.__init__ s+ )5+>+>+@A rc|jj}||jk7r||_d|_t|yr )rErCr4r5rXr8)r patch_pathr_s rr8z TransformedPatchPath._revalidate s=[[))+   ##DJ%)D " r)r&rprqrrrAr8rrs@rrArA s rrActj|rtj|s| |fSd}||kr||}}d}tt||g\}}t t |t |}|d|z tj tjzkr| }|}n=||z ||zkr2|dk(r |dk(r| }|}n"||t |zz}||t |zz }|r|s||}}||fS)a Modify the endpoints of a range as needed to avoid singularities. Parameters ---------- vmin, vmax : float The initial endpoints. expander : float, default: 0.001 Fractional amount by which *vmin* and *vmax* are expanded if the original interval is too small, based on *tiny*. tiny : float, default: 1e-15 Threshold for the ratio of the interval to the maximum absolute value of its endpoints. If the interval is smaller than this, it will be expanded. This value should be around 1e-15 or larger; otherwise the interval will be approaching the double precision resolution limit. increasing : bool, default: True If True, swap *vmin*, *vmax* if *vmin* > *vmax*. Returns ------- vmin, vmax : float Endpoints, expanded and/or swapped if necessary. If either input is inf or NaN, or if both inputs are 0 or very close to zero, it returns -*expander*, *expander*. FTg.Ar)r}isfinitemaprYrabsfinfotiny)vminvmaxexpanderrN increasingswapped maxabsvalues r nonsingularrU s8 KK r{{4'8y(""G d{4dUT4L)JD$c$iT+KcDjBHHUO$8$888y  d* * 199DD HSY& &D HSY& &Dz4d :rc>|\}}||kDr||}}||cxkxr|kScS)a: Check, inclusively, whether an interval includes a given value. Parameters ---------- interval : (float, float) The endpoints of the interval. val : float Value to check is within interval. Returns ------- bool Whether *val* is within the *interval*. r6rrZr4rs rinterval_containsrXP s0 DAq1u!1 =q==rcZ|\}}||kDr||}}||z |z}||z |cxkxr||zkScS)a Check, inclusively, whether an interval includes a given value, with the interval expanded by a small tolerance to admit floating point errors. Parameters ---------- interval : (float, float) The endpoints of the interval. val : float Value to check is within interval. rtol : float, default: 1e-10 Relative tolerance slippage allowed outside of the interval. For an interval ``[a, b]``, values ``a - rtol * (b - a) <= val <= b + rtol * (b - a)`` are considered inside the interval. Returns ------- bool Whether *val* is within the *interval* (with tolerance). r6)rrZrtolr4rs r_interval_contains_closer[f sH, DAq1u!1 ET>D t8s &a$h && &&rcP|\}}||cxkxr|kncxs||cxkDxr|kDScS)aB Check, excluding endpoints, whether an interval includes a given value. Parameters ---------- interval : (float, float) The endpoints of the interval. val : float Value to check is within interval. Returns ------- bool Whether *val* is within the *interval*. r6rWs rinterval_contains_openr] s- DAq s;Q; %!c+A+%+%rctjgd||dk(r|tj||zS| t d|dk(r |dz}|dz}|t |||j zS)a Return a new transform with an added offset. Parameters ---------- trans : `Transform` subclass Any transform, to which offset will be applied. fig : `~matplotlib.figure.Figure`, default: None Current figure. It can be None if *units* are 'dots'. x, y : float, default: 0.0 The offset to apply. units : {'inches', 'points', 'dots'}, default: 'inches' Units of the offset. Returns ------- `Transform` subclass Transform with applied offset. )dotsrinches)unitsr_z3For units of inches or points a fig kwarg is neededrgR@)r check_in_listrBrrrdpi_scale_trans)transfigrrras r offset_copyrf s|( 35A xz++Aq111 {NOO  T  T  $Q3+>+>? ??r)gMbP?gV瞯rksJ JJ 8{{|FM}FMR"((BFFBFF+,Y?8Y?x HXhHXVv8vrV$ V$r KAyKA\//dA:AH[E|[E|/ /d++$ZmYZz2m\2j =o4 o4d2 2j+6'L'T#l#L_(  F 4l&<BD,mD,N?67t,':&(@r