o
    h|                    @   s  d dl mZmZ d dlmZ d dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlZd dlZd dlZd dlZd dlmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZ d dl m!Z" d dl#m$Z% d dl&m'Z' d dl(m)Z) d dl*m+Z, d dl-m.Z/ d dl0m1Z2 d d	l3m4Z4m5Z5 d dl6m7Z8 d dl9m:Z; d dl<m=Z> d dl?m@ZA d dlBmCZD eEeFZGG d
d dZHG dd dZIddddZJG dd dZKeLddgiG dd dejMZNdd ZOdS )    )IterableSequence)	ExitStackN)Real)
attrgetter)_apicbook
_docstring	offsetbox)_OrderedSet	_check_1dindex_of)SubplotSpec)cyclervalidate_axisbelowc                   @   s&   e Zd ZdZddddZdd ZdS )_axis_method_wrappera6  
    Helper to generate Axes methods wrapping Axis methods.

    After ::

        get_foo = _axis_method_wrapper("xaxis", "get_bar")

    (in the body of a class) ``get_foo`` is a method that forwards it arguments
    to the ``get_bar`` method of the ``xaxis`` attribute, and gets its
    signature and docstring from ``Axis.get_bar``.

    The docstring of ``get_foo`` is built by replacing "this Axis" by "the
    {attr_name}" (i.e., "the xaxis", "the yaxis") in the wrapped method's
    dedented docstring; additional replacements can be given in *doc_sub*.
    Ndoc_subc                C   s|   || _ || _tttj|}g | _|r9dd| j  i|pi }| D ]\}}||vr2| j	| |
||}q$|| _d S )Nz	this Axiszthe )	attr_namemethod_nameinspectgetdocgetattrmaxisAxis_missing_subsitemsappendreplace__doc__)selfr   r   r   dockv r$   i/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/matplotlib/axes/_base.py__init__4   s   
z_axis_method_wrapper.__init__c              
      s   t | j d| j   fdd}|j|_||_|j d| |_| j|_tt	t
j| j|_| jrEtd|j| jdtt| jt||| d S )N.c                    s    | |i |S Nr$   )r    argskwargs
get_methodr$   r%   wrapperI   s   z2_axis_method_wrapper.__set_name__.<locals>.wrapperzWThe definition of {} expected that the docstring of Axis.{} contains {!r} as substrings, )r   r   r   
__module____name____qualname__r   r   	signaturer   r   r   __signature__r   
ValueErrorformatjoinmapreprsetattr)r    ownernamer-   r$   r+   r%   __set_name__C   s$   z!_axis_method_wrapper.__set_name__)r0   r/   r1   r   r&   r<   r$   r$   r$   r%   r   #   s    r   c                   @   s    e Zd ZdZdd Zdd ZdS )_TransformedBoundsLocatorz
    Axes locator for `.Axes.inset_axes` and similarly positioned Axes.

    The locator is a callable object used in `.Axes.set_aspect` to compute the
    Axes location depending on the renderer.
    c                 C   s   || _ || _dS )z
        *bounds* (a ``[l, b, w, h]`` rectangle) and *transform* together
        specify the position of the inset Axes.
        N)_bounds
_transform)r    bounds	transformr$   r$   r%   r&   h   s   
z"_TransformedBoundsLocator.__init__c                 C   s&   t t jj| j | j|jddj S )NFroot)mtransformsTransformedBboxBboxfrom_boundsr>   r?   
get_figuretransSubfigure)r    axrendererr$   r$   r%   __call__p   s   z"_TransformedBoundsLocator.__call__N)r0   r/   r1   r   r&   rL   r$   r$   r$   r%   r=   `   s    r=   Fambiguous_fmt_datakeyc          	      C   s  d}d}d}| dvrzt | }|||fW S  ty   Y nw |r#dnd}d}|t| k r| | }| ||d  tjv rU|durHt|| d| ||d  }|d7 }n||tjv rm|durft|| d|}|d7 }nd|tjv r|dur~t|| d	|}|d7 }nL|t  v r|durt|| d
|}|d7 }n3|dkrt	
d| |d }|st|| dt |d }|t|d 7 }nt|| d||t| k s-|du r|du rtjd }|du rd}|du rd}|||fS )av  
    Convert a MATLAB style color/line style format string to a (*linestyle*,
    *marker*, *color*) tuple.

    Example format strings include:

    * 'ko': black circles
    * '.b': blue dots
    * 'r--': red dashed lines
    * 'C2--': the third color in the color cycle, dashed lines

    The format is absolute in the sense that if a linestyle or marker is not
    defined in *fmt*, there is no line or marker. This is expressed by
    returning 'None' for the respective quantity.

    See Also
    --------
    matplotlib.Line2D.lineStyles, matplotlib.colors.cnames
        All possible styles and color format strings.
    N)01z9{!r} is neither a data key nor a valid format string ({})z&{!r} is not a valid format string ({})r      ztwo linestyle symbols   ztwo marker symbolsztwo color symbolsCzC\d+z 'C' must be followed by a numberzunrecognized character zlines.linestyleNone)mcolorsto_rgbar4   lenmlines
lineStylesr5   lineMarkersget_named_colors_mappingrematchmplrcParams)	fmtrN   	linestylemarkercolorerrfmticcn_colorr$   r$   r%   _process_plot_formaty   sh   








rh   c                   @   sx   e Zd ZdZdddZdd Zddd	d
dZdd Ze fddZ	dd Z
dd Zdd Zdd ZdddddZdS )_process_plot_var_argsa  
    Process variable length arguments to `~.Axes.plot`, to support ::

      plot(t, s)
      plot(t1, s1, t2, s2)
      plot(t1, s1, 'ko', t2, s2)
      plot(t1, s1, 'ko', t2, s2, 'r--', t3, e3)

    an arbitrary number of *x*, *y*, *fmt* are allowed
    Line2Dc                 C   s&   t jg d|d || _| d  d S )Nrj   Polygoncoordinatesoutput)r   check_in_listro   set_prop_cycle)r    ro   r$   r$   r%   r&      s   z_process_plot_var_args.__init__c                 C   s&   |d u r	t jd }d| _g || _d S )Nzaxes.prop_cycler   )r^   r_   _idx_cycler_items)r    r   r$   r$   r%   rq      s   
z%_process_plot_var_args.set_prop_cycleNF)datareturn_kwargsc                /   s   |j |d dD ]}||v rtt d j|q	|sd S  d u r+dd |D }nh fdd|D }t|dkr=d}nAt|dkrqzt|d  W n tyV   d}Y n(w |d |d urnt	d	|d d
t
 d}nd}nt|dkrzd}ntd|dd u rt|| || |d< |} d uot|dk}	t|dkrt|dstd|r|d d |dd  }
}|rt|d tr|
|d f7 }
|dd  }| j||
||	|dE d H  |sd S d S )N)r*   xyrR   c                 S   s   g | ]}t |qS r$   )r   sanitize_sequence.0ar$   r$   r%   
<listcomp>       z3_process_plot_var_args.__call__.<locals>.<listcomp>c                    s   g | ]}t  |qS r$   )r^   	_replacer)ry   argrt   r$   r%   r{          r   rQ   zSecond argument a"   is ambiguous: could be a format string but is in 'data'; using as data.  If it was intended as data, set the format string to an empty string to suppress this warning.  If it was intended as a format string, explicitly pass the x-values as well.  Alternatively, rename the entry in 'data'.   zwUsing arbitrary long args with data is not supported due to ambiguity of arguments; use multiple plotting calls insteadlabel   z]plot() with multiple groups of data (i.e., pairs of x and y) does not support multiple labels)rN   ru   )_process_unit_infor   kwarg_errorr   stackfunctionrW   rh   r4   warn_externalRuntimeWarninggetr^   _label_from_argr   is_scalar_or_string
isinstancestr
_plot_args)r    axesrt   ru   r)   r*   pos_onlyreplacedlabel_namer_idxrN   thisr$   r   r%   rL      sf   		z_process_plot_var_args.__call__c                 C   s6   | j | j }d|v r| jd t| j  | _|d S dS )z#Return the next color in the cycle.rc   rR   r"   )rs   rr   rW   )r    entryr$   r$   r%   get_next_color.  s
   z%_process_plot_var_args.get_next_colorc                    sZ   | j | j }tfddh |  D r+| jd t| j  | _ fdd| D S i S )a8  
        If some keys in the property cycle (excluding those in the set
        *ignore*) are absent or set to None in the dict *kw*, return a copy
        of the next entry in the property cycle, excluding keys in *ignore*.
        Otherwise, don't advance the property cycle, and return an empty dict.
        c                 3   s     | ]}  |d d u V  qd S r(   r   ry   r"   )kwr$   r%   	<genexpr>?  s    z6_process_plot_var_args._getdefaults.<locals>.<genexpr>rR   c                    s   i | ]\}}| vr||qS r$   r$   ry   r"   r#   )ignorer$   r%   
<dictcomp>B  s    z7_process_plot_var_args._getdefaults.<locals>.<dictcomp>)rs   rr   anyrW   r   )r    r   r   defaultsr$   )r   r   r%   _getdefaults7  s
   z#_process_plot_var_args._getdefaultsc                 C   s*   |D ]}| |ddu r|| ||< qdS )zx
        Add to the dict *kw* the entries in the dict *default* that are absent
        or set to None in *kw*.
        Nr   )r    r   r   r"   r$   r$   r%   _setdefaultsF  s
   z#_process_plot_var_args._setdefaultsc                 C   s:   i ||}|  | || tj||fi |}||fS r(   )r   r   rX   rj   )r    r   xyr   r*   segr$   r$   r%   
_make_lineO  s   z!_process_plot_var_args._make_linec                 C   s*   i ||}|  | || ||f|fS r(   )r   r   )r    r   r   r   r   r*   r$   r$   r%   _make_coordinatesU  s   z(_process_plot_var_args._make_coordinatesc           
      C   s   | |}||}| }| }h ddd | D B }| ||}| || |dd }|dd  | || tj	t
||f||dd|d d}	|	jd	i | |	|fS )
N>   rb   
markersizemarkeredgecolormarkeredgewidthmarkerfacecolorc                 S   s   h | ]
\}}|d ur|qS r(   r$   r   r$   r$   r%   	<setcomp>m  s    z7_process_plot_var_args._make_polygon.<locals>.<setcomp>rc   fillTclosed)	facecolorr   r   r$   )convert_xunitsconvert_yunitscopyr   r   r   r   popmpatchesrl   npcolumn_stackset)
r    r   r   r   r   r*   ignoresdefault_dictr   r   r$   r$   r%   _make_polygonZ  s&   


	
z$_process_plot_var_args._make_polygon)ru   rN   c                   sb  t |dkrt|d tr|^ }}t||d\}}	}
nt |dkr&td|}d\}}	}
tdd |D r:td	i td
||	|
fD ].\}}|durr| dkrn|v rn|dkrnt	| d| d| d| d|d
 ||< qDt |dkrt
|d t
|d nt|d \ jdur j  jdur j jd jd krtdj dj jdksĈjdkrtdj dj jdkrވddtjf jdkrddtjf | jdkr| jn&| jdkrddd< | jn| jdkr| jn
tjg d| jd jd jd dkr@dkr@kr@td d  d!dksJdkrLg S d"}t}t|rb|g| }n/t ||krl|}n%|dkrd#t | d$}tjd%|d& |g}ntd't | d(| d) fd*dt|D }|rt|S d+d, |D S )-a  
        Process the arguments of ``plot([x], y, [fmt], **kwargs)`` calls.

        This processes a single set of ([x], y, [fmt]) parameters; i.e. for
        ``plot(x, y, x2, y2)`` it will be called twice. Once for (x, y) and
        once for (x2, y2).

        x and y may be 2D and thus can still represent multiple datasets.

        For multiple datasets, if the keyword argument *label* is a list, this
        will unpack the list and assign the individual labels to the datasets.

        Parameters
        ----------
        tup : tuple
            A tuple of the positional parameters. This can be one of

            - (y,)
            - (x, y)
            - (y, fmt)
            - (x, y, fmt)

        kwargs : dict
            The keyword arguments passed to ``plot()``.

        return_kwargs : bool
            Whether to also return the effective keyword arguments after label
            unpacking as well.

        ambiguous_fmt_datakey : bool
            Whether the format string in *tup* could also have been a
            misspelled data key.

        Returns
        -------
        result
            If *return_kwargs* is false, a list of Artists representing the
            dataset(s).
            If *return_kwargs* is true, a list of (Artist, effective_kwargs)
            representing the dataset(s). See *return_kwargs*.
            The Artist is either `.Line2D` (if called from ``plot()``) or
            `.Polygon` otherwise.
        rR   rM   r   z!third arg must be a format string)NNNc                 s   s    | ]}|d u V  qd S r(   r$   )ry   r#   r$   r$   r%   r         z4_process_plot_var_args._plot_args.<locals>.<genexpr>z(x, y, and format string must not be None)ra   rb   rc   NnonerT   z  is redundantly defined by the 'z'' keyword argument and the fmt string "z" (-> =z-). The keyword argument will take precedence.rQ   r   z8x and y must have same first dimension, but have shapes z and z3x and y can be no greater than 2D, but have shapes rj   rl   r   Trm   rk   rn   zx has z columns but y has z columnsr   zPassing label as a length z sequence when plotting a single dataset is deprecated in Matplotlib 3.9 and will error in 3.11.  To keep the current behavior, cast the sequence to string before passing.z3.9)messagezJlabel must be scalar or have the same length as the input data, but found z for z
 datasets.c              	   3   sP    | ]#\}} d d | f d d | f i d|iV  qd S )Nr   r$   )ry   jr   r   r   r*   make_artistncxncyr   r   r$   r%   r     s    *c                 S   s   g | ]}|d  qS r   r$   )ry   lr$   r$   r%   r{   "      z5_process_plot_var_args._plot_args.<locals>.<listcomp>)rW   r   r   rh   r4   r   ziplowerr   r   r   r   xaxisupdate_unitsyaxisshapendimr   newaxisro   r   r   r   r   rp   maxr   r   warn_deprecated	enumeratelist)r    r   tupr*   ru   rN   rv   r`   ra   rb   rc   	prop_namevalr   
n_datasetslabelsmsgresultr$   r   r%   r     s   -









z!_process_plot_var_args._plot_args)rj   )r0   r/   r1   r   r&   rq   rL   r   	frozensetr   r   r   r   r   r   r$   r$   r$   r%   ri      s    
K		3ri   r   fcc                
       s	  e Zd ZU dZdZdd eD Ze ZdZ	e
jed< 	 ejed< 	 ejed< 	 ed	d
 Zdd Zdddddddddd	 fdd
Z fddZ fddZdd Zdd Zdd Zdd Zd d! Zdud"d#Zd$d% Z fd&d'Zd(d) Zed*d+ Zdvd-d.Z d/d0 Z!dwd2d3Z"d4d5 Z#d6d7 Z$dwd8d9Z%d:d; Z&d<d= Z'd>d? Z(dxd@dAZ)dydCdDZ*dydEdFZ+dGdH Z,dIdJ Z-dKdL Z.dMdN Z/dOdP Z0dzdSdTZ1dUdV Z2dWdX Z3dYdZ Z4d[d\ Z5d]d^ Z6G d_d` d`e7Z8edadb Z9edcdd Z:ededf Z;edgdh Z<edidj Z=edkdl Z>edmdn Z?dodp Z@dqdr ZAdsdt ZBdudv ZCdwdx ZDd{dydzZEd{d| ZFdxd}d~ZGdd ZHduddZIdd ZJdxddZKdd ZLduddZMduddddZNdd ZOdd ZPdd ZQdd ZRdd ZSeTddZUeTddZVeTddZWeTddZXdd ZYdd ZZdd Z[dd Z\dd Z]d|ddZ^dd Z_dd Z`dd Zadd Zbdd Zcdd Zddd Zedd Zfdd ZgduddZhdxddZid}ddZjd~ddddZkdd ZleTddÃZmeTddÃZneTddăZoeTddăZpddƄ ZqddȄ Zreddʄ Zsesjtddʄ Zsdd̈́ Zuddτ Zvddф Zwddӄ ZxddddԜddքZydd؄ Zzddڄ Z{ddd܄Z|dddބZ}dd Z~ejdd Zdd Zdd Zdd Zdd Zdd Zdd ZejdddZdBddddddddZdddZdyddZdd Zdd Zdd Zd~ddd dZdd ZeTddZdd Zd~ddZd	d
 Zdd Zd~dddddddZeTddZeTddZeTddZeTddddidZeTddZeTddZeTddZeTddddidZdd Zd~ddddZd d! ZeTddZd"d# Zd~d$d%Zd&d' Zd~ddddd(d)d*ZeTddZeTddZeTddZeTdddd+idZeTddZeTddZeTddZeTdddd,idZeTdd-ZeTdd-Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC ZdDdE ZdFdG Z	H	ddIdJZ	H	ddKdLZdMdN ZdOdP ZÐdQdR ZĐdSdT ZŐdUdV ZƐdWdX ZǐdYdZ ZȐd[d\ Zɐdudddd]d^d_Zʐd`da Zːdbdc Z̐ddde Z͐dfdg Zΐdhdi ZϐdxdjdkZddldmdnZddldodpZҐdqdr ZӐdsdt Zԇ  ZS (  	_AxesBaserectilinearr   r   c                 C   s   i | ]}|t  qS r$   )r   Grouperry   r;   r$   r$   r%   r   1  r|   z_AxesBase.<dictcomp>FdataLimr   r   c                    s    fdd j D S )z7A mapping of axis names, e.g. 'x', to `Axis` instances.c                    s   i | ]}|t  | d qS axis)r   r   r    r$   r%   r   Z  s    z'_AxesBase._axis_map.<locals>.<dictcomp>)_axis_namesr   r$   r   r%   	_axis_mapW  s   
z_AxesBase._axis_mapc                 C   s   d t| j| jjS )Nz({0}({1[0]:g},{1[1]:g};{1[2]:g}x{1[3]:g}))r5   typer0   	_positionr@   r   r$   r$   r%   __str__]  s   z_AxesBase.__str__NT auto)	r   frameonsharexshareyr   xscaleyscale
box_aspectforward_navigation_eventsc       	            sR  t    d|v r!|rtd|d}tjtjtf|d |f}d}t	|dkr9t
|d tjr9|d  | _n&t	|dkrPt|d rPtjj|d  | _ntj  | _| _t||}| jjdk sk| jjdk rotd| j | _| | _d| _d	| _d
| _t| jd| _|
| _|| _ || _!| "| | #| |r| $| nd| _%| &|	 d| _'g | _(g | _)t*j+,| - | _.| /  |du rt0j1d }|| _2|| _3| 4t0j1d  d| _5| 6  d| _7d| _8| 9d | :d |r| ;| |r| <| | =| | j>? D ]\}}|j@Ad| B| qt0j1}| jC|d o%|d |d o-|d |d o5|d |d o=|d |d oE|d |d oM|d |d oU|d |d o]|d dd	 | jC|d ok|d |d os|d |d o{|d |d o|d |d o|d  |d o|d! |d o|d  |d o|d! d"d	 dS )#a*  
        Build an Axes in a figure.

        Parameters
        ----------
        fig : `~matplotlib.figure.Figure`
            The Axes is built in the `.Figure` *fig*.

        *args
            ``*args`` can be a single ``(left, bottom, width, height)``
            rectangle or a single `.Bbox`.  This specifies the rectangle (in
            figure coordinates) where the Axes is positioned.

            ``*args`` can also consist of three numbers or a single three-digit
            number; in the latter case, the digits are considered as
            independent numbers.  The numbers are interpreted as ``(nrows,
            ncols, index)``: ``(nrows, ncols)`` specifies the size of an array
            of subplots, and ``index`` is the 1-based index of the subplot
            being created.  Finally, ``*args`` can also directly be a
            `.SubplotSpec` instance.

        sharex, sharey : `~matplotlib.axes.Axes`, optional
            The x- or y-`~.matplotlib.axis` is shared with the x- or y-axis in
            the input `~.axes.Axes`.  Note that it is not possible to unshare
            axes.

        frameon : bool, default: True
            Whether the Axes frame is visible.

        box_aspect : float, optional
            Set a fixed aspect for the Axes box, i.e. the ratio of height to
            width. See `~.axes.Axes.set_box_aspect` for details.

        forward_navigation_events : bool or "auto", default: "auto"
            Control whether pan/zoom events are passed through to Axes below
            this one. "auto" is *True* for axes with an invisible patch and
            *False* otherwise.

        **kwargs
            Other optional keyword arguments:

            %(Axes:kwdoc)s

        Returns
        -------
        `~.axes.Axes`
            The new `~.axes.Axes` object.
        rectz8'rect' cannot be used together with positional arguments)r   NrR   r   z/Width and height specified must be non-negativer   boxrS   Fzaxes.facecolorzaxes.axisbelowTunitsz	xtick.topzxtick.minor.topzxtick.bottomzxtick.minor.bottomzxtick.labeltopzxtick.labelbottomz
ytick.leftzytick.minor.leftzytick.rightzytick.minor.rightzytick.labelleftzytick.labelrightminor)	topbottomlabeltoplabelbottomleftright	labelleft
labelrightwhichzxtick.major.topzxtick.major.bottomzytick.major.leftzytick.major.rightmajor)Dsuperr&   	TypeErrorr   r   check_isinstancerD   rF   r   rW   r   frozenr   r   iterablerG   unit_originalPositionr   _from_subplot_argswidthheightr4   r   _aspect_adjustable_anchordictfromkeysr   _stale_viewlims_forward_navigation_events_sharex_sharey	set_label
set_figureset_subplotspec_subplotspecset_box_aspect_axes_locator	_children
_colorbarsmspinesSpines	from_dict_gen_axes_spinesspines
_init_axisr^   r_   
_facecolor_frameonset_axisbelow_rasterization_zorderclear	fmt_xdata	fmt_ydataset_navigateset_navigate_mode
set_xscale
set_yscale_internal_updater   r   	callbacks_connect_picklable_unit_change_handlertick_params)r    figr   r   r   r   r   r   r   r   r   r)   r*   r   subplotspecr;   r   r_   	__class__r$   r%   r&   a  s   
>



















z_AxesBase.__init__c                    s^   t | | j}d| jv rtjddd| j d| jdd d| jv p"|| _t  jdi | d S )	Nclaz3.6TzOverriding `Axes.cla` in z is pending deprecation in %(since)s and will be fully deprecated in favor of `Axes.clear` in the future. Please report this to the z author.)pendingr   r$   )r  _subclass_uses_cla__dict__r   r   r1   r/   __init_subclass__)clsr*   parent_uses_clar4  r$   r%   r:  	  s   

z_AxesBase.__init_subclass__c                    sD   t   } fdd jD |d<   jv r j nd |d< |S )Nc                    s,   i | ]}  j | v r| j |  qS r$   _shared_axesget_siblingsr   r   r$   r%   r     s    z*_AxesBase.__getstate__.<locals>.<dictcomp>r>  _twinned_axes)r  __getstate__r   r@  r?  )r    stater4  r   r%   rA    s   



z_AxesBase.__getstate__c                 C   sV   | d}| D ]\}}| j| j|  q	| d}|r#| jj|  || _d| _d S )Nr>  r@  T)r   r   r>  r6   r@  r9  _stale)r    rB  shared_axesr;   shared_siblingstwinned_siblingsr$   r$   r%   __setstate__!  s   


z_AxesBase.__setstate__c                 C   s   g }|   r|d|   g7 }t| dr2i }dD ]}| j|d}|r'|||< q|r2|d| g7 }| j D ]\}}|jrP|j rP|| d|j g7 }q7d| jj dd	| d	 S )
Nzlabel=	get_titler   centerr   locztitle=<z: r.   >)
	get_labelhasattrrH  r   r   r   get_textr5  r0   r6   )r    fieldstitlesr"   titler;   r   r$   r$   r%   __repr__,  s"   
z_AxesBase.__repr__c                 C      | j S )z?Return the `.SubplotSpec` associated with the subplot, or None.)r  r   r$   r$   r%   get_subplotspec=     z_AxesBase.get_subplotspecc                 C   s"   || _ | || jdd dS )z4Set the `.SubplotSpec`. associated with the subplot.FrB   N)r  _set_positionget_positionrH   )r    r3  r$   r$   r%   r  A  s   z_AxesBase.set_subplotspecc                 C   s   | j r| j  S dS )z<Return the `.GridSpec` associated with the subplot, or None.N)r  get_gridspecr   r$   r$   r%   r[  F  s   z_AxesBase.get_gridspecc                 C   rV  )a  
        Return the Axes bounding box in display space.

        This bounding box does not include the spines, ticks, ticklabels,
        or other labels.  For a bounding box including these elements use
        `~matplotlib.axes.Axes.get_tightbbox`.

        See Also
        --------
        matplotlib.axes.Axes.get_tightbbox
        matplotlib.axis.Axis.get_tightbbox
        matplotlib.spines.Spine.get_window_extent
        )bbox)r    rK   r$   r$   r%   get_window_extentJ     z_AxesBase.get_window_extentc                 C   sd   t j| dd| _| jj| j | jj| j t j| dd| _| jj	| j | jj
| j d S )NF)r&  )r   XAxisr   r   r   register_axisr   YAxisr   r   r   r   r$   r$   r%   r!  Z  s   z_AxesBase._init_axisc                    sR   t  | t| j|j| _tj | _	tj
 | _tt | _|   d S r(   )r  r  rD   rE   r   rI   r\  rF   nullr   r  _viewLimTransformWrapperIdentityTransform
transScale_set_lim_and_transforms)r    r2  r4  r$   r%   r  c  s   z_AxesBase.set_figurec                    sp    fdd j D }t| r6|D ]} j|  D ]}d|j|< qq jdi dd | D  d S d S )Nc                    s0   i | ]  t  fd dj  D qS )c                 3   s    | ]}|j   V  qd S r(   )r  ry   rJ   r;   r$   r%   r   u      z8_AxesBase._unstale_viewLim.<locals>.<dictcomp>.<genexpr>)r   r>  r?  )ry   r   ri  r%   r   t  s    z._AxesBase._unstale_viewLim.<locals>.<dictcomp>Fc                 S   s   i | ]
\}}d | |qS )scaler$   )ry   r;   rk  r$   r$   r%   r   |  s    r$   )r   r   valuesr>  r?  r  autoscale_viewr   )r    
need_scaler;   rJ   r$   r   r%   _unstale_viewLimq  s   
z_AxesBase._unstale_viewLimc                 C   s   |    | jS )z/The view limits as `.Bbox` in data coordinates.)ro  rc  r   r$   r$   r%   viewLim  s   z_AxesBase.viewLimallc                 C   sR   t ji dd | jD d| ji|d}|D ]}d| j|< q|dur'|| _dS dS )a  
        Mark a single axis, or all of them, as stale wrt. autoscaling.

        No computation is performed until the next autoscaling; thus, separate
        calls to control individual axises incur negligible performance cost.

        Parameters
        ----------
        axis : str, default: "all"
            Either an element of ``self._axis_names``, or "all".
        tight : bool or None, default: None
        c                 S   s   i | ]}||gqS r$   r$   r   r$   r$   r%   r     r   z5_AxesBase._request_autoscale_view.<locals>.<dictcomp>rq  r   TN)r   check_getitemr   r  _tight)r    r   tight
axis_namesr;   r$   r$   r%   _request_autoscale_view  s   
z!_AxesBase._request_autoscale_viewc                 C   sr   t | j| _t t  | _t t | j	| j| _
| j| j
| j  | _t | j| j| _t | j| j| _dS )a  
        Set the *_xaxis_transform*, *_yaxis_transform*, *transScale*,
        *transData*, *transLimits* and *transAxes* transformations.

        .. note::

            This method is primarily used by rectilinear projections of the
            `~matplotlib.axes.Axes` class, and is meant to be overridden by
            new kinds of projection Axes that need different transformations
            and limits. (See `~matplotlib.projections.polar.PolarAxes` for an
            example.)
        N)rD   BboxTransformTor\  	transAxesrd  re  rf  BboxTransformFromrE   rc  transLimits	transDatablended_transform_factory_xaxis_transform_yaxis_transformr   r$   r$   r%   rg    s   
z!_AxesBase._set_lim_and_transformsgridc                 C   D   |dkr| j S |dkr| jj S |dkr| jj S td|)a  
        Get the transformation used for drawing x-axis labels, ticks
        and gridlines.  The x-direction is in data coordinates and the
        y-direction is in axis coordinates.

        .. note::

            This transformation is primarily used by the
            `~matplotlib.axis.Axis` class, and is meant to be
            overridden by new kinds of projections that may need to
            place axis elements in different locations.

        Parameters
        ----------
        which : {'grid', 'tick1', 'tick2'}
        r  tick1tick2unknown value for which: )r}  r   r   get_spine_transformr   r4   r    r   r$   r$   r%   get_xaxis_transform     z_AxesBase.get_xaxis_transformc                 C   s<   t jd }| jddtdd| d | jddj d	|fS )
a  
        Returns
        -------
        transform : Transform
            The transform used for drawing x-axis labels, which will add
            *pad_points* of padding (in points) between the axis and the label.
            The x-direction is in data coordinates and the y-direction is in
            axis coordinates
        valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
            The text vertical alignment.
        halign : {'center', 'left', 'right'}
            The text horizontal alignment.

        Notes
        -----
        This transformation is primarily used by the `~matplotlib.axis.Axis`
        class, and is meant to be overridden by new kinds of projections that
        may need to place axis elements in different locations.
        xtick.alignmentr  r   r   r   H   FrB   r   r^   r_   r  rD   ScaledTranslationrH   dpi_scale_transr    
pad_pointslabels_alignr$   r$   r%   get_xaxis_text1_transform     

z#_AxesBase.get_xaxis_text1_transformc                 C   s8   t jd }| jddtd|d | jddj d|fS )	a  
        Returns
        -------
        transform : Transform
            The transform used for drawing secondary x-axis labels, which will
            add *pad_points* of padding (in points) between the axis and the
            label.  The x-direction is in data coordinates and the y-direction
            is in axis coordinates
        valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
            The text vertical alignment.
        halign : {'center', 'left', 'right'}
            The text horizontal alignment.

        Notes
        -----
        This transformation is primarily used by the `~matplotlib.axis.Axis`
        class, and is meant to be overridden by new kinds of projections that
        may need to place axis elements in different locations.
        r  r  r  r   r  FrB   r   r  r  r$   r$   r%   get_xaxis_text2_transform     

z#_AxesBase.get_xaxis_text2_transformc                 C   r  )a  
        Get the transformation used for drawing y-axis labels, ticks
        and gridlines.  The x-direction is in axis coordinates and the
        y-direction is in data coordinates.

        .. note::

            This transformation is primarily used by the
            `~matplotlib.axis.Axis` class, and is meant to be
            overridden by new kinds of projections that may need to
            place axis elements in different locations.

        Parameters
        ----------
        which : {'grid', 'tick1', 'tick2'}
        r  r  r  r  )r~  r   r   r  r   r4   r  r$   r$   r%   get_yaxis_transform  r  z_AxesBase.get_yaxis_transformc                 C   s<   t jd }| jddtd| d d| jddj |d	fS )
a  
        Returns
        -------
        transform : Transform
            The transform used for drawing y-axis labels, which will add
            *pad_points* of padding (in points) between the axis and the label.
            The x-direction is in axis coordinates and the y-direction is in
            data coordinates
        valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
            The text vertical alignment.
        halign : {'center', 'left', 'right'}
            The text horizontal alignment.

        Notes
        -----
        This transformation is primarily used by the `~matplotlib.axis.Axis`
        class, and is meant to be overridden by new kinds of projections that
        may need to place axis elements in different locations.
        ytick.alignmentr  r  r   r  r   FrB   r   r^   r_   r  rD   r  rH   r  r  r$   r$   r%   get_yaxis_text1_transform,  r  z#_AxesBase.get_yaxis_text1_transformc                 C   s8   t jd }| jddt|d d| jddj |dfS )	a  
        Returns
        -------
        transform : Transform
            The transform used for drawing secondart y-axis labels, which will
            add *pad_points* of padding (in points) between the axis and the
            label.  The x-direction is in axis coordinates and the y-direction
            is in data coordinates
        valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
            The text vertical alignment.
        halign : {'center', 'left', 'right'}
            The text horizontal alignment.

        Notes
        -----
        This transformation is primarily used by the `~matplotlib.axis.Axis`
        class, and is meant to be overridden by new kinds of projections that
        may need to place axis elements in different locations.
        r  r  r  r  r   FrB   r   r  r  r$   r$   r%   get_yaxis_text2_transformG  r  z#_AxesBase.get_yaxis_text2_transformc                 C   s$   | j t| j | j  d S r(   )rf  r   rD   r|  r   get_transformr   r   r$   r$   r%   _update_transScaleb  s
   z_AxesBase._update_transScalec                 C   s,   |r| j  S |  }|s|   | j S )aq  
        Return the position of the Axes within the figure as a `.Bbox`.

        Parameters
        ----------
        original : bool
            If ``True``, return the original position. Otherwise, return the
            active position. For an explanation of the positions see
            `.set_position`.

        Returns
        -------
        `.Bbox`

        )r  r  get_axes_locatorapply_aspectr   )r    originallocatorr$   r$   r%   rZ  g  s   

z_AxesBase.get_positionbothc                 C   s   | j ||d | d dS )a!  
        Set the Axes position.

        Axes have two position attributes. The 'original' position is the
        position allocated for the Axes. The 'active' position is the
        position the Axes is actually drawn at. These positions are usually
        the same unless a fixed aspect is set to the Axes. See
        `.Axes.set_aspect` for details.

        Parameters
        ----------
        pos : [left, bottom, width, height] or `~matplotlib.transforms.Bbox`
            The new position of the Axes in `.Figure` coordinates.

        which : {'both', 'active', 'original'}, default: 'both'
            Determines which position variables to change.

        See Also
        --------
        matplotlib.transforms.Bbox.from_bounds
        matplotlib.transforms.Bbox.from_extents
        r  FN)rY  set_in_layout)r    posr   r$   r$   r%   set_position  s   z_AxesBase.set_positionc                 C   s\   t |tjstjj| }| j| D ]}|dv r|j| |dv r(|j	| qd| _
dS )z
        Private version of set_position.

        Call this internally to get the same functionality of `set_position`,
        but not to take the axis out of the constrained_layout hierarchy.
        )r  active)r  r  TN)r   rD   BboxBaserF   rG   r@  r?  r   r   r  stale)r    r  r   rJ   r$   r$   r%   rY    s   
z_AxesBase._set_positionc                 C   s0   | j | D ]}|jdd}|j|dd qdS )z
        Reset the active position to the original position.

        This undoes changes to the active position (as defined in
        `.set_position`) which may have been performed to satisfy fixed-aspect
        constraints.
        Tr  r  r  N)r@  r?  rZ  r  )r    rJ   r  r$   r$   r%   reset_position  s   z_AxesBase.reset_positionc                 C      || _ d| _dS )z
        Set the Axes locator.

        Parameters
        ----------
        locator : Callable[[Axes, Renderer], Bbox]
        TN)r  r  )r    r  r$   r$   r%   set_axes_locator     
z_AxesBase.set_axes_locatorc                 C   rV  )z*
        Return the axes_locator.
        )r  r   r$   r$   r%   r       z_AxesBase.get_axes_locatorc                 C   sH   | | jdd | s|| j | |_| r"| j| dS dS )z4Set the boilerplate props for artists added to Axes.FrB   N)	r  rH   is_transform_setset_transformr{  r   get_mouseover_mouseover_setaddr    rz   r$   r$   r%   _set_artist_props  s   z_AxesBase._set_artist_propsc                 C   s   t dddS )a  
        Returns
        -------
        Patch
            The patch used to draw the background of the Axes.  It is also used
            as the clipping path for any data elements on the Axes.

            In the standard Axes, this is a rectangle, but in other projections
            it may not be.

        Notes
        -----
        Intended to be overridden by new projection types.
        )        r        ?)r   	Rectangler   r$   r$   r%   _gen_axes_patch  s   z_AxesBase._gen_axes_patchr  inchesc                    s    fdddD S )a}  
        Returns
        -------
        dict
            Mapping of spine names to `.Line2D` or `.Patch` instances that are
            used to draw Axes spines.

            In the standard Axes, spines are single line segments, but in other
            projections they may not be.

        Notes
        -----
        Intended to be overridden by new projection types.
        c                    s   i | ]
}|t j |qS r$   )r  Spinelinear_spine)ry   sider   r$   r%   r     s    z._AxesBase._gen_axes_spines.<locals>.<dictcomp>)r   r   r   r   r$   )r    	locationsoffsetr   r$   r   r%   r    s   
z_AxesBase._gen_axes_spinesc                 C      t jt|d | jdur|| jurtd| jd | | || _|jj| j_|jj	| j_	|
 \}}| j||d| d |jj| j_dS )a  
        Share the x-axis with *other*.

        This is equivalent to passing ``sharex=other`` when constructing the
        Axes, and cannot be used if the x-axis is already being shared with
        another Axes.  Note that it is not possible to unshare axes.
        otherNzx-axis is already sharedr   Femitr   )r   r  r   r  r4   r>  r6   r   r   r   get_xlimset_xlimget_autoscalex_on_scale)r    r  x0x1r$   r$   r%   r        z_AxesBase.sharexc                 C   r  )a  
        Share the y-axis with *other*.

        This is equivalent to passing ``sharey=other`` when constructing the
        Axes, and cannot be used if the y-axis is already being shared with
        another Axes.  Note that it is not possible to unshare axes.
        r  Nzy-axis is already sharedr   Fr  )r   r  r   r  r4   r>  r6   r   r   r   get_ylimset_ylimget_autoscaley_onr  )r    r  y0y1r$   r$   r%   r     r  z_AxesBase.shareyc                 C   sn  t | dr| j }nd}| j }| j }| j D ]}|  q| j D ]}|	  q(d| _
tjg dd| _tjd rH| jt  tjd rU| jt  tjd | _tjd | _d	| _d| _t | _td
| _tjd | _| jg }| _|D ]}d	|_d	|_d	|_q|  t | _ g | _!d	| _"d	| _#d	| _$g | _%| &d | j&| jtjd tjd d t'j(tjd tjd d}tjd }	|	d	u rd}	d| _)nd| _)t*j+d|	d|ddd| _,t*j+d|	d|- ddd| _.t*j+d|	d|- ddd| _/tjd }
| 0|
 | j,| j.| j/fD ]}| 1| q| 2 | _| j3| j4dd | j5| j6 | j7d | j8d  | j9| j: | ;  | j<| j | j<| j | j=d	ure| j>| | j>| | j?d	urw| j>| | j>| | j@ D ]1\}}tA| d!| }|d	urtA| d"| | q|| jBd#kr|Cd$ |jDd d%dd& q|| E  d| _Fd	S )'Clear the Axes.patchT)xlim_changedylim_changedzlim_changed)signalszxtick.minor.visiblezytick.minor.visiblezaxes.xmarginzaxes.ymarginNrl   z	axes.gridFzaxes.grid.whichzaxes.grid.axis)r   r   zaxes.titlesizezaxes.titleweight)sizeweightzaxes.titleyr        ?r   baselinerJ  )r   r   textfontpropertiesverticalalignmenthorizontalalignmentr  r   r   zaxes.titlepadrB   r   r   _sharesharepolarlinearrR   r   )GrP  r  get_visibler   r   r   rl  r&  r   _clearignore_existing_data_limitsr   CallbackRegistryr.  r^   r_   set_minor_locatormtickerAutoMinorLocator_xmargin_ymarginrs  _use_sticky_edgesri   
_get_lines_get_patches_for_fill_gridOnr  _remove_method_parent_figurer   r   r  
child_axes_current_image_projection_initlegend_
containersr  font_managerFontProperties_autotitleposmtextTextrT  r   _left_title_right_title_set_title_offset_transr  r  r  rH   set_facecolorr"  set_edgecolorset_linewidthr  rx  set_axis_onset_clip_pathr  set_visibler  r   r   r;   
_set_scale_set_limr  r  )r    patch_visiblexaxis_visibleyaxis_visibler   spineold_childrenchldpropsr   title_offset_points_titler;   r  r$   r$   r%   __clear  s   















z_AxesBase.__clearc                 C      | j r	|   dS |   dS r  N)r8  r6  _AxesBase__clearr   r$   r$   r%   r&       z_AxesBase.clearc                 C   r  r  )r8  r  r&  r   r$   r$   r%   r6    r  z_AxesBase.clac                   @   sL   e Zd ZdZ	dddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )z_AxesBase.ArtistLista  
        A sublist of Axes children based on their type.

        The type-specific children sublists were made immutable in Matplotlib
        3.7.  In the future these artist lists may be replaced by tuples. Use
        as if this is a tuple already.
        Nc                    s    || _ || _ fdd| _dS )a!  
            Parameters
            ----------
            axes : `~matplotlib.axes.Axes`
                The Axes from which this sublist will pull the children
                Artists.
            prop_name : str
                The property name used to access this sublist from the Axes;
                used to generate deprecation warnings.
            valid_types : list of type, optional
                A list of types that determine which children will be returned
                by this sublist. If specified, then the Artists in the sublist
                must be instances of any of these types. If unspecified, then
                any type of Artist is valid (unless limited by
                *invalid_types*.)
            invalid_types : tuple, optional
                A list of types that determine which children will *not* be
                returned by this sublist. If specified, then Artists in the
                sublist will never be an instance of these types. Otherwise, no
                types will be excluded.
            c                    s"    st | o  pt |   S r(   )r   )artistinvalid_typesvalid_typesr$   r%   <lambda>  s   z/_AxesBase.ArtistList.__init__.<locals>.<lambda>N)_axes
_prop_name_type_check)r    r   r   r  r  r$   r  r%   r&     s   z_AxesBase.ArtistList.__init__c                 C   s   dt |  d| j dS )Nz<Axes.ArtistList of  rN  )rW   r  r   r$   r$   r%   rU    s   z_AxesBase.ArtistList.__repr__c                    s   t  fdd jjD S )Nc                 3   s    | ]}  |V  qd S r(   r  ry   r  r   r$   r%   r     rj  z/_AxesBase.ArtistList.__len__.<locals>.<genexpr>)sumr  r  r   r$   r   r%   __len__  s   z_AxesBase.ArtistList.__len__c                 c   s(    t | jjD ]
}| |r|V  qd S r(   )r   r  r  r  )r    r  r$   r$   r%   __iter__  s   
z_AxesBase.ArtistList.__iter__c                    s    fdd j jD | S )Nc                    s   g | ]	}  |r|qS r$   r  r  r   r$   r%   r{     s    
z4_AxesBase.ArtistList.__getitem__.<locals>.<listcomp>)r  r  )r    keyr$   r   r%   __getitem__  s
   
z _AxesBase.ArtistList.__getitem__c                 C   s>   t |ttjfrg | |S t |ttjfrg | |R S tS r(   )r   r   r   
ArtistListtupleNotImplementedr    r  r$   r$   r%   __add__  s
   z_AxesBase.ArtistList.__add__c                 C   s0   t |tr|t|  S t |tr|t|  S tS r(   )r   r   r%  r&  r'  r$   r$   r%   __radd__  s
   

z_AxesBase.ArtistList.__radd__NN)r0   r/   r1   r   r&   rU  r   r!  r#  r(  r)  r$   r$   r$   r%   r$    s    
r$  c              	   C   s(   | j | dtjtjtjtjt	j
tjfdS )Nartists)r  )r$  mcoll
Collectionmimage	AxesImagerX   rj   r   PatchmtableTabler  r  r   r$   r$   r%   r+    s   z_AxesBase.artistsc                 C      | j | dtjdS )Ncollectionsr  )r$  r,  r-  r   r$   r$   r%   r4    s   z_AxesBase.collectionsc                 C   r3  )Nimagesr5  )r$  r.  r/  r   r$   r$   r%   r6       z_AxesBase.imagesc                 C   r3  )Nlinesr5  )r$  rX   rj   r   r$   r$   r%   r8    r7  z_AxesBase.linesc                 C   r3  )Npatchesr5  )r$  r   r0  r   r$   r$   r%   r9  	  r7  z_AxesBase.patchesc                 C   r3  )Ntablesr5  )r$  r1  r2  r   r$   r$   r%   r:    r7  z_AxesBase.tablesc                 C   r3  )Ntextsr5  )r$  r  r  r   r$   r$   r%   r;    r7  z_AxesBase.textsc                 C   s
   | j  S )zGet the facecolor of the Axes.)r  get_facecolorr   r$   r$   r%   r<    s   
z_AxesBase.get_facecolorc                 C   s   || _ d| _| j|S )zx
        Set the facecolor of the Axes.

        Parameters
        ----------
        color : :mpltype:`color`
        T)r"  r  r  r  )r    rc   r$   r$   r%   r    s   z_AxesBase.set_facecolorc                 C   sT   t d|d | jddj| _| j| j| jfD ]}|| j	| j  |
d qdS )zw
        Set the offset for the title either from :rc:`axes.titlepad`
        or from set_title kwarg ``pad``.
        r  r  FrB   N)rD   r  rH   r  titleOffsetTransrT  r  r  r  rx  set_clip_box)r    r  r  r$   r$   r%   r  %  s   z!_AxesBase._set_title_offset_transc                 O   sX   |r|rt dt|dkr|d du rd}nt|i |}| j| | j| dS )a	  
        Set the property cycle of the Axes.

        The property cycle controls the style properties such as color,
        marker and linestyle of future plot commands. The style properties
        of data already added to the Axes are not modified.

        Call signatures::

          set_prop_cycle(cycler)
          set_prop_cycle(label=values, label2=values2, ...)
          set_prop_cycle(label, values)

        Form 1 sets given `~cycler.Cycler` object.

        Form 2 creates a `~cycler.Cycler` which cycles over one or more
        properties simultaneously and set it as the property cycle of the
        Axes. If multiple properties are given, their value lists must have
        the same length. This is just a shortcut for explicitly creating a
        cycler and passing it to the function, i.e. it's short for
        ``set_prop_cycle(cycler(label=values, label2=values2, ...))``.

        Form 3 creates a `~cycler.Cycler` for a single property and set it
        as the property cycle of the Axes. This form exists for compatibility
        with the original `cycler.cycler` interface. Its use is discouraged
        in favor of the kwarg form, i.e. ``set_prop_cycle(label=values)``.

        Parameters
        ----------
        cycler : `~cycler.Cycler`
            Set the given Cycler. *None* resets to the cycle defined by the
            current style.

            .. ACCEPTS: `~cycler.Cycler`

        label : str
            The property key. Must be a valid `.Artist` property.
            For example, 'color' or 'linestyle'. Aliases are allowed,
            such as 'c' for 'color' and 'lw' for 'linewidth'.

        values : iterable
            Finite-length iterable of the property values. These values
            are validated and will raise a ValueError if invalid.

        See Also
        --------
        matplotlib.rcsetup.cycler
            Convenience function for creating validated cyclers for properties.
        cycler.cycler
            The original function for creating unvalidated cyclers.

        Examples
        --------
        Setting the property cycle for a single property:

        >>> ax.set_prop_cycle(color=['red', 'green', 'blue'])

        Setting the property cycle for simultaneously cycling over multiple
        properties (e.g. red circle, green plus, blue cross):

        >>> ax.set_prop_cycle(color=['red', 'green', 'blue'],
        ...                   marker=['o', '+', 'x'])

        zCCannot supply both positional and keyword arguments to this method.rR   r   N)r  rW   r   r  rq   r  )r    r)   r*   
prop_cycler$   r$   r%   rq   1  s   Az_AxesBase.set_prop_cyclec                 C   rV  )z
        Return the aspect ratio of the Axes scaling.

        This is either "auto" or a float giving the ratio of y/x-scale.
        )r  r   r$   r$   r%   
get_aspect}  s   z_AxesBase.get_aspectc                    s   t |drd}t |dst|}|dkst|std|r, fdd jD }n g}|D ]}||_q1|du r> j} j	||d	 |durP j
||d	 d
 _dS )aK  
        Set the aspect ratio of the Axes scaling, i.e. y/x-scale.

        Parameters
        ----------
        aspect : {'auto', 'equal'} or float
            Possible values:

            - 'auto': fill the position rectangle with data.
            - 'equal': same as ``aspect=1``, i.e. same scaling for x and y.
            - *float*: The displayed size of 1 unit in y-data coordinates will
              be *aspect* times the displayed size of 1 unit in x-data
              coordinates; e.g. for ``aspect=2`` a square in data coordinates
              will be rendered with a height of twice its width.

        adjustable : None or {'box', 'datalim'}, optional
            If not ``None``, this defines which parameter will be adjusted to
            meet the required aspect. See `.set_adjustable` for further
            details.

        anchor : None or str or (float, float), optional
            If not ``None``, this defines where the Axes will be drawn if there
            is extra space due to aspect constraints. The most common way
            to specify the anchor are abbreviations of cardinal directions:

            =====   =====================
            value   description
            =====   =====================
            'C'     centered
            'SW'    lower left corner
            'S'     middle of bottom edge
            'SE'    lower right corner
            etc.
            =====   =====================

            See `~.Axes.set_anchor` for further details.

        share : bool, default: False
            If ``True``, apply the settings to all shared Axes.

        See Also
        --------
        matplotlib.axes.Axes.set_adjustable
            Set how the Axes adjusts to achieve the required aspect ratio.
        matplotlib.axes.Axes.set_anchor
            Set the position in case of extra space.
        equalrR   r   r   z#aspect must be finite and positive c                    &   h | ]} j |  D ]}|qqS r$   r=  ry   r;   siblingr   r$   r%   r     
    
z'_AxesBase.set_aspect.<locals>.<setcomp>N)r  T)r   
_str_equalfloatr   isfiniter4   r   r  r  set_adjustable
set_anchorr  )r    aspect
adjustableanchorr  r   rJ   r$   r   r%   
set_aspect  s"   0
z_AxesBase.set_aspectc                 C   rV  )a  
        Return whether the Axes will adjust its physical dimension ('box') or
        its data limits ('datalim') to achieve the desired aspect ratio.

        See Also
        --------
        matplotlib.axes.Axes.set_adjustable
            Set how the Axes adjusts to achieve the required aspect ratio.
        matplotlib.axes.Axes.set_aspect
            For a description of aspect handling.
        )r  r   r$   r$   r%   get_adjustable     z_AxesBase.get_adjustablec                    sn   t jddg|d |r fdd jD }n g}|dkr*tdd |D r*td|D ]}||_q,d	 _d
S )a  
        Set how the Axes adjusts to achieve the required aspect ratio.

        Parameters
        ----------
        adjustable : {'box', 'datalim'}
            If 'box', change the physical dimensions of the Axes.
            If 'datalim', change the ``x`` or ``y`` data limits. This
            may ignore explicitly defined axis limits.

        share : bool, default: False
            If ``True``, apply the settings to all shared Axes.

        See Also
        --------
        matplotlib.axes.Axes.set_aspect
            For a description of aspect handling.

        Notes
        -----
        Shared Axes (of which twinned Axes are a special case)
        impose restrictions on how aspect ratios can be imposed.
        For twinned Axes, use 'datalim'.  For Axes that share both
        x and y, use 'box'.  Otherwise, either 'datalim' or 'box'
        may be used.  These limitations are partly a requirement
        to avoid over-specification, and partly a result of the
        particular implementation we are currently using, in
        which the adjustments for aspect ratios are done sequentially
        and independently on each Axes as it is drawn.
        r   datalimrL  c                    rB  r$   r=  rC  r   r$   r%   r     rE  z+_AxesBase.set_adjustable.<locals>.<setcomp>c                 s   s$    | ]}t |jd dtjkV  qdS )__func__N)r   get_data_ratior   rh  r$   r$   r%   r     s    z+_AxesBase.set_adjustable.<locals>.<genexpr>zPCannot set Axes adjustable to 'datalim' for Axes which override 'get_data_ratio'TN)r   rp   r   r   r4   r  r  )r    rL  r  axsrJ   r$   r   r%   rI    s   
z_AxesBase.set_adjustablec                 C   rV  )a  
        Return the Axes box aspect, i.e. the ratio of height to width.

        The box aspect is ``None`` (i.e. chosen depending on the available
        figure space) unless explicitly specified.

        See Also
        --------
        matplotlib.axes.Axes.set_box_aspect
            for a description of box aspect.
        matplotlib.axes.Axes.set_aspect
            for a description of aspect handling.
        )_box_aspectr   r$   r$   r%   get_box_aspect  r^  z_AxesBase.get_box_aspectc                 C   sZ   h | j | | j | }|dur t|}|D ]}|d q|D ]}||_d|_q"dS )aD  
        Set the Axes box aspect, i.e. the ratio of height to width.

        This defines the aspect of the Axes in figure space and is not to be
        confused with the data aspect (see `~.Axes.set_aspect`).

        Parameters
        ----------
        aspect : float or None
            Changes the physical dimensions of the Axes, such that the ratio
            of the Axes height to the Axes width in physical units is equal to
            *aspect*. Defining a box aspect will change the *adjustable*
            property to 'datalim' (see `~.Axes.set_adjustable`).

            *None* will disable a fixed box aspect so that height and width
            of the Axes are chosen independently.

        See Also
        --------
        matplotlib.axes.Axes.set_aspect
            for a description of aspect handling.
        NrQ  T)r@  r?  rG  rI  rV  r  )r    rK  rU  rJ   r$   r$   r%   r    s   
z_AxesBase.set_box_aspectc                 C   rV  )z
        Get the anchor location.

        See Also
        --------
        matplotlib.axes.Axes.set_anchor
            for a description of the anchor.
        matplotlib.axes.Axes.set_aspect
            for a description of aspect handling.
        )r  r   r$   r$   r%   
get_anchorA  s   z_AxesBase.get_anchorc                    sh   |t jjv st|dkstddt jj |r$ fdd jD }n g}|D ]}||_q)d _dS )ux  
        Define the anchor location.

        The actual drawing area (active position) of the Axes may be smaller
        than the Bbox (original position) when a fixed aspect is required. The
        anchor defines where the drawing area will be located within the
        available space.

        Parameters
        ----------
        anchor : (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.).  str inputs are shorthands
            for (*x*, *y*) coordinates, as shown in the following diagram::

               ┌─────────────────┬─────────────────┬─────────────────┐
               │ 'NW' (0.0, 1.0) │ 'N' (0.5, 1.0)  │ 'NE' (1.0, 1.0) │
               ├─────────────────┼─────────────────┼─────────────────┤
               │ 'W'  (0.0, 0.5) │ 'C' (0.5, 0.5)  │ 'E'  (1.0, 0.5) │
               ├─────────────────┼─────────────────┼─────────────────┤
               │ 'SW' (0.0, 0.0) │ 'S' (0.5, 0.0)  │ 'SE' (1.0, 0.0) │
               └─────────────────┴─────────────────┴─────────────────┘

        share : bool, default: False
            If ``True``, apply the settings to all shared Axes.

        See Also
        --------
        matplotlib.axes.Axes.set_aspect
            for a description of aspect handling.
        rQ   zargument must be among %sr.   c                    rB  r$   r=  rC  r   r$   r%   r   s  rE  z'_AxesBase.set_anchor.<locals>.<setcomp>TN)	rD   rF   coefsrW   r4   r6   r   r  r  )r    rM  r  r   rJ   r$   r   r%   rJ  N  s   !
z_AxesBase.set_anchorc                 C   s\   | j  |  \}}| j |  \}}tt|| d}tt|| d}|| S )z
        Return the aspect ratio of the scaled data.

        Notes
        -----
        This method is intended to be overridden by new projection types.
        KH9)r   r  rA   
get_xboundr   
get_yboundr   abs)r    txmintxmaxtymintymaxxsizeysizer$   r$   r%   rT  |  s
   z_AxesBase.get_data_ratioc           (      C   sv  |du r
| j dd}|  }|dkr | jdu r | j|dd dS | jddj}tj 	|}|j
|j }| jd	krb| | jv rCtd
||   }| }||||}| ||  |d dS | jdur| }|| j||}| ||  |d |dkrdS | jdu r| j|dd n||  |}| j }	| j }
|	|  \}}|
|  \}}tt|| d}tt|| d}||j
|j  }|| }|| | d }t|dk rdS | j}|	|j\}}|
|j\}}d||  }d||  }|| }|| }|| }|| }|| }|| }d} d}!| | jd v }"| | jd v }#|"r7|#r7td|#r=d}$n'|| kr[||!kr[|dkrQ|dk pY|dk oY|dk}%n|dk}%|"pc|%}$|$rd||  }&|&|d  }|&|d  }|   st!"d | #|
$ ||g dS d||  }'|'|d  }|'|d  }| % st!"d | &|	$ ||g dS )a  
        Adjust the Axes for a specified data aspect ratio.

        Depending on `.get_adjustable` this will modify either the
        Axes box (position) or the view limits. In the former case,
        `~matplotlib.axes.Axes.get_anchor` will affect the position.

        Parameters
        ----------
        position : None or .Bbox

            .. note::
                This parameter exists for historic reasons and is considered
                internal. End users should not use it.

            If not ``None``, this defines the position of the
            Axes within the figure as a Bbox. See `~.Axes.get_position`
            for further details.

        Notes
        -----
        This is called automatically when each Axes is drawn.  You may need
        to call it yourself if you need to update the Axes position and/or
        view limits before the Figure is drawn.

        An alternative with a broader scope is `.Figure.draw_without_rendering`,
        which updates all stale components of a figure, not only the positioning /
        view limits of a single Axes.

        See Also
        --------
        matplotlib.axes.Axes.set_aspect
            For a description of aspect ratio handling.
        matplotlib.axes.Axes.set_adjustable
            Set how the Axes adjusts to achieve the required aspect ratio.
        matplotlib.axes.Axes.set_anchor
            Set the position in case of extra space.
        matplotlib.figure.Figure.draw_without_rendering
            Update all stale components of a figure.

        Examples
        --------
        A typical usage example would be the following. `~.Axes.imshow` sets the
        aspect to 1, but adapting the Axes position and extent to reflect this is
        deferred until rendering for performance reasons. If you want to know the
        Axes size before, you need to call `.apply_aspect` to get the correct
        values.

        >>> fig, ax = plt.subplots()
        >>> ax.imshow(np.zeros((3, 3)))
        >>> ax.bbox.width, ax.bbox.height
        (496.0, 369.59999999999997)
        >>> ax.apply_aspect()
        >>> ax.bbox.width, ax.bbox.height
        (369.59999999999997, 369.59999999999997)
        NTr  r   r  r  FrB   r   zHAdjustable 'box' is not allowed in a twinned Axes; use 'datalim' insteadrZ  rR   g{Gzt?g?r   r   r   zset_aspect(..., adjustable='datalim') or axis('equal') are not allowed when both axes are shared.  Try set_aspect(..., adjustable='box').r         @zQIgnoring fixed y limits to fulfill fixed data aspect with adjustable data limits.zQIgnoring fixed x limits to fulfill fixed data aspect with adjustable data limits.)'rZ  r@  rV  rY  rH   rI   rD   rF   r  transformedr
  r	  r  r@  RuntimeErrorrT  r  shrunk_to_aspectanchoredrX  r   r  r   rA   r[  r\  r   r]  r   	intervalx	intervalyr>  r  _logwarning
set_yboundinvertedr  
set_xbound)(r    positionrK  transbb
fig_aspectr   pbpb1x_trfy_trfxminxmaxyminymaxrb  rc  
data_ratio
y_expanderdLr  r  r  r  xryrxmargymargYsizeXsizeXmargYmargxmymshared_xshared_yadjust_yadjyycxcr$   r$   r%   r    s   9










z_AxesBase.apply_aspect)r  c                  s  t  ttfrՈ du rd  du rd     dkr!|   n- dkr+|   n# dv r| d | d | jdd  dkrL| jdd	d
 n dkr^| jdddd | d n dkrn| jdd | d n dkr| jdd | d | jdddd nȈ dkr| jdddd | d | 	 }| 
 }tt|t|d }| j|d |d | g|dd | j|d |d | g|dd ntd d durt dt| j krtdddd | jD  fddt| jD }n!i }| jD ]}|| dd}	|| dd}
|	|
f||< q| D ]&\}\}	}
|	du r9|
du r9dnd}t| d | d!}||	|
||d q'|rWtd"|d#}| jD ]}t| d$| d!}|| 7 }q\|S )%a  
        Convenience method to get or set some axis properties.

        Call signatures::

          xmin, xmax, ymin, ymax = axis()
          xmin, xmax, ymin, ymax = axis([xmin, xmax, ymin, ymax])
          xmin, xmax, ymin, ymax = axis(option)
          xmin, xmax, ymin, ymax = axis(**kwargs)

        Parameters
        ----------
        xmin, xmax, ymin, ymax : float, optional
            The axis limits to be set.  This can also be achieved using ::

                ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))

        option : bool or str
            If a bool, turns axis lines and labels on or off. If a string,
            possible values are:

            ================ ===========================================================
            Value            Description
            ================ ===========================================================
            'off' or `False` Hide all axis decorations, i.e. axis labels, spines,
                             tick marks, tick labels, and grid lines.
                             This is the same as `~.Axes.set_axis_off()`.
            'on' or `True`   Do not hide all axis decorations, i.e. axis labels, spines,
                             tick marks, tick labels, and grid lines.
                             This is the same as `~.Axes.set_axis_on()`.
            'equal'          Set equal scaling (i.e., make circles circular) by
                             changing the axis limits. This is the same as
                             ``ax.set_aspect('equal', adjustable='datalim')``.
                             Explicit data limits may not be respected in this case.
            'scaled'         Set equal scaling (i.e., make circles circular) by
                             changing dimensions of the plot box. This is the same as
                             ``ax.set_aspect('equal', adjustable='box', anchor='C')``.
                             Additionally, further autoscaling will be disabled.
            'tight'          Set limits just large enough to show all data, then
                             disable further autoscaling.
            'auto'           Automatic scaling (fill plot box with data).
            'image'          'scaled' with axis limits equal to data limits.
            'square'         Square plot; similar to 'scaled', but initially forcing
                             ``xmax-xmin == ymax-ymin``.
            ================ ===========================================================

        emit : bool, default: True
            Whether observers are notified of the axis limit change.
            This option is passed on to `~.Axes.set_xlim` and
            `~.Axes.set_ylim`.

        Returns
        -------
        xmin, xmax, ymin, ymax : float
            The axis limits.

        See Also
        --------
        matplotlib.axes.Axes.set_xlim
        matplotlib.axes.Axes.set_ylim

        Notes
        -----
        For 3D Axes, this method additionally takes *zmin*, *zmax* as
        parameters and likewise returns them.
        TonFoff)rA  rt  scaledr   imagesquarer   rt  rA  rQ  rR  r  r   rS   )rL  rM  rt  r  r  r   r  zUnrecognized string z to axis; try 'on' or 'off'NrQ   zAThe first argument to axis() must be an iterable of the form [{}]r.   c                 s   s     | ]}| d | dV  qdS )zmin, r   Nr$   r   r$   r$   r%   r     s    
z!_AxesBase.axis.<locals>.<genexpr>c                    s*   i | ]\}}| d | d |d   qS )rQ   rR   r$   )ry   re   r;   r~   r$   r%   r     s    z"_AxesBase.axis.<locals>.<dictcomp>minr   set_limr   r$   get_)r   r   boolr   r  set_axis_offset_autoscale_onrN  rm  r  r  r   r   diffr  r  r4   rW   r   r  r5   r6   r   r   r   r   r   r   )r    r~   r  r*   xlimylim	edge_sizelimitsr;   ax_minax_maxax_auto
set_ax_limlims
get_ax_limr$   r  r%   r   .  s   C







z_AxesBase.axisc                 C   rV  )z?Return the `.Legend` instance, or None if no legend is defined.)r  r   r$   r$   r%   
get_legend  rX  z_AxesBase.get_legendc                 C      t d| jS )z6Return a list of `.AxesImage`\s contained by the Axes.r/  )r   silent_listr6  r   r$   r$   r%   
get_images     z_AxesBase.get_imagesc                 C   r  )z-Return a list of lines contained by the Axes.rj   )r   r  r8  r   r$   r$   r%   	get_lines  r  z_AxesBase.get_linesc                 C   rV  )z
        [*Discouraged*] Return the XAxis instance.

        .. admonition:: Discouraged

            The use of this function is discouraged. You should instead
            directly access the attribute `~.Axes.xaxis`.
        )r   r   r$   r$   r%   	get_xaxis     	z_AxesBase.get_xaxisc                 C   rV  )z
        [*Discouraged*] Return the YAxis instance.

        .. admonition:: Discouraged

            The use of this function is discouraged. You should instead
            directly access the attribute `~.Axes.yaxis`.
        )r   r   r$   r$   r%   	get_yaxis  r  z_AxesBase.get_yaxisget_gridlinesget_ticklinesc                 C   s2   t jtjtjf|d || jvrtd|| _dS )z
        Set the current image.

        This image will be the target of colormap functions like
        ``pyplot.viridis``, and other functions such as `~.pyplot.clim`.  The
        current image is an attribute of the current Axes.
        )imz4Argument must be an image or collection in this AxesN)	r   r  r,  r-  r.  r/  r  r4   r  )r    r  r$   r$   r%   _sci  s   

z_AxesBase._scic                 C   rV  )z:Helper for `~matplotlib.pyplot.gci`; do not use elsewhere.)r  r   r$   r$   r%   _gci  rX  z_AxesBase._gcic                 C   s   t dd | jD S )z
        Return whether any artists have been added to the Axes.

        This should not be used to determine whether the *dataLim*
        need to be updated, and may not actually be useful for
        anything.
        c                 s   s*    | ]}t |tjtjtjtjfV  qd S r(   )	r   r,  r-  r.  r/  rX   rj   r   r0  rx   r$   r$   r%   r     s    z%_AxesBase.has_data.<locals>.<genexpr>)r   r  r   r$   r$   r%   has_data  s   z_AxesBase.has_datac                 C   sH   | |_ | j| | jj|_| | | du r|| j d| _	|S )a  
        Add an `.Artist` to the Axes; return the artist.

        Use `add_artist` only for artists for which there is no dedicated
        "add" method; and if necessary, use a method such as `update_datalim`
        to manually update the `~.Axes.dataLim` if the artist is to be included
        in autoscaling.

        If no ``transform`` has been specified when creating the artist (e.g.
        ``artist.get_transform() == None``) then the transform is set to
        ``ax.transData``.
        NT)
r   r  r   remover  r  get_clip_pathr  r  r  r  r$   r$   r%   
add_artist  s   

z_AxesBase.add_artistc                 C   sB   | |_ tj|_| j| tj| jddj	| jgd|_
d| _|S )z
        Add an `.Axes` to the Axes' children; return the child Axes.

        This is the lowlevel version.  See `.axes.Axes.inset_axes`.
        FrB   )ownersT)r  martist_stale_axes_callbackstale_callbackr  r   	functoolspartialrH   _remove_axesr  r  )r    rJ   r$   r$   r%   add_child_axes	  s   
z_AxesBase.add_child_axesc                 C   s   t jtj|d | s|dt| j  | j| | jj	|_
| | | du r3|| j |rY|   || j}| }t|j sTt||jgg}| | d| _|S )zI
        Add a `.Collection` to the Axes; return the collection.
        )
collection_childNT)r   r  r,  r-  rO  r  rW   r  r   r  r  r  r  r  r  ro  get_datalimr{  
get_pointsr   isinfminposrq  concatenateupdate_datalimr  )r    r  autolimrQ  pointsr$   r$   r%   add_collection'	  s"   


z_AxesBase.add_collectionc                 C   sX   t jtj|d | | | s|dt| j  | j	| | jj
|_d| _|S )zD
        Add an `.AxesImage` to the Axes; return the image.
        )r  r  T)r   r  r.  r/  r  rO  r  rW   r  r   r  r  r  )r    r  r$   r$   r%   	add_imageG	  s   

z_AxesBase.add_imagec                 C   s,   |  \}}}}| j||f||ff d S r(   )
get_extentr   r  )r    r  rx  ry  rz  r{  r$   r$   r%   _update_image_limitsT	  s   z_AxesBase._update_image_limitsc                 C   sz   t jtj|d | | | du r|| j | | |	 s-|
dt| j  | j| | jj|_d| _|S )z?
        Add a `.Line2D` to the Axes; return the line.
        )lineNr  T)r   r  rX   rj   r  r  r  r  _update_line_limitsrO  r  rW   r  r   r  r  r  )r    r  r$   r$   r%   add_lineX	  s   


z_AxesBase.add_linec                 C   s:   t jtj|d | | | j| | jj|_d| _	|S )z=
        Add a `.Text` to the Axes; return the text.
        )txtT)
r   r  r  r  r  r  r   r  r  r  )r    r  r$   r$   r%   	_add_texti	  s   

z_AxesBase._add_textc                 C   s   |  }|jjdkrdS | }|| jkr|}n)t|| jr?|| j }| jjr9| }|	 \}}|
|}n||}n|}|jjsGdS || j\}	}
| jdkrh|	r^||  kr^d}	|
rh||  krhd}
| jj|| j|	|
d d| _dS )zY
        Figures out the data limit of the given line, updating `.Axes.dataLim`.
        r   Nr   Fupdatexupdatey)get_pathverticesr  r  r{  r   contains_branch_seperately	is_affine_get_transformed_pathget_transformed_path_and_affinetransform_path_affinetransform_pathr;   r  r  r   update_from_pathr  )r    r  pathline_trf	data_pathtrf_to_dataline_trans_pathna_path_r  r  r$   r$   r%   r  t	  s6   



z_AxesBase._update_line_limitsc                 C   sV   t jtj|d | | | du r|| j | | | j	
| | j	j|_|S )z?
        Add a `.Patch` to the Axes; return the patch.
        )pN)r   r  r   r0  r  r  r  r  _update_patch_limitsr  r   r  r  )r    r  r$   r$   r%   	add_patch	  s   


z_AxesBase.add_patchc                 C   s   t |tjr| s| sdS | }g }|jddD ]\}}| \}}||dg|d qt	|r<t
|}| }|| j\}	}
|	sN|
sNdS | jdkrg|	r]||  kr]d}	|
rg||  krgd}
|| j }||}| j||	|
d dS )z+Update the data limits for the given patch.NF)simplifyr   rR   r   r  )r   r   r  	get_width
get_heightr  iter_bezieraxis_aligned_extremar   rW   r   vstackr  r  r{  r;   r  r  rA   r  )r    r  r  r  curvecoder  dzeros	patch_trfr  r  r  xysr$   r$   r%   r  	  s2   




z_AxesBase._update_patch_limitsc                 C   sL   t jtj|d | | | j| | du r|| j	 | jj
|_|S )z?
        Add a `.Table` to the Axes; return the table.
        )tabN)r   r  r1  r2  r  r  r   r  r  r  r  r  )r    r  r$   r$   r%   	add_table	  s   

z_AxesBase.add_tablec                 C   s:   |  }|s|dt| j  | j| | jj|_|S )zS
        Add a `.Container` to the Axes' containers; return the container.
        z_container%d)rO  r  rW   r  r   r  r  )r    	containerr   r$   r$   r%   add_container	  s   
z_AxesBase.add_containerc                 C   sV   |du rt j| j|t dS tj| j|d | jD ]}|  q| 	  | 
| dS )zW
        Process axis units changes: requests updates to data and view limits.
        N)event)	axis_name)r  r  r0  objectr   rp   r   r8  recache_alwaysrelimrv  )r    r  r  r  r$   r$   r%   r0  	  s   


z_AxesBase._unit_change_handlerc                 C   s   | j d | j tj   d| _| jD ]+}|r|	 rBt
|tjr+| | qt
|tjr7| | qt
|tjrB| | qdS )a
  
        Recompute the data limits based on current artists.

        At present, `.Collection` instances are not supported.

        Parameters
        ----------
        visible_only : bool, default: False
            Whether to exclude invisible artists.
        TN)r   r   
set_pointsrD   rF   rb  r  r  r  r  r   rX   rj   r  r   r0  r  r.  r/  r  )r    visible_onlyr  r$   r$   r%   r  	  s   

z_AxesBase.relimc                 C   s>   t |}t t |sdS | jj|| j||d d| _dS )ak  
        Extend the `~.Axes.dataLim` Bbox to include the given points.

        If no data is set currently, the Bbox will ignore its limits and set
        the bound to be the bounds of the xydata (*xys*). Otherwise, it will
        compute the bounds of the union of its current data and the data in
        *xys*.

        Parameters
        ----------
        xys : 2D array-like
            The points to include in the data limits Bbox. This can be either
            a list of (x, y) tuples or a (N, 2) array.

        updatex, updatey : bool, default: True
            Whether to update the x/y limits.
        Nr  F)r   asarrayr   rH  r   update_from_data_xyr  )r    r  r  r  r$   r$   r%   r  
  s   

z_AxesBase.update_datalim)convertc          
   	      s  |pg }|pi }| j  |D ]+\}}z | }W n ty&   td|dw |dur8|dur8| s8|| q  D ]G\}}|du rFq=|| d|j}| jdkrbddd}||| |}||jkr|dur|	| |D ]\}	}|	|kr|dur|| qrq= fdd	|D S )
a  
        Set axis units based on *datasets* and *kwargs*, and optionally apply
        unit conversions to *datasets*.

        Parameters
        ----------
        datasets : list
            List of (axis_name, dataset) pairs (where the axis name is defined
            as in `._axis_map`).  Individual datasets can also be None
            (which gets passed through).
        kwargs : dict
            Other parameters from which unit info (i.e., the *xunits*,
            *yunits*, *zunits* (for 3D Axes), *runits* and *thetaunits* (for
            polar) entries) is popped, if present.  Note that this dict is
            mutated in-place!
        convert : bool, default: True
            Whether to return the original datasets or the converted ones.

        Returns
        -------
        list
            Either the original datasets if *convert* is False, or the
            converted ones if *convert* is True (the default).
        zInvalid axis name: Nr   r  
thetaunitsrunitsr   c                    s.   g | ]\}}r|d ur |  |n|qS r(   )convert_units)ry   r  rt   axis_mapr  r$   r%   r{   i
  s    z0_AxesBase._process_unit_info.<locals>.<listcomp>)
r   KeyErrorr4   
have_unitsr   r   r   r   r;   	set_units)
r    datasetsr*   r  r  rt   r   r   polar_unitsdataset_axis_namer$   r  r%   r   0
  s8   




z_AxesBase._process_unit_infoc                 C   s   | j |d S )zT
        Return whether the given event (in display coords) is in the Axes.
        r   r  containsr    
mouseeventr$   r$   r%   in_axesm
  s   z_AxesBase.in_axes_get_autoscale_on_set_autoscale_onc                 C   s   t dd | j D S )z8Return True if each axis is autoscaled, False otherwise.c                 s       | ]}|  V  qd S r(   )r  )ry   r   r$   r$   r%   r   z
  s    z-_AxesBase.get_autoscale_on.<locals>.<genexpr>)rq  r   rl  r   r$   r$   r%   get_autoscale_onx
  s   z_AxesBase.get_autoscale_onc                 C   s   | j  D ]}|| qdS )z
        Set whether autoscaling is applied to each axis on the next draw or
        call to `.Axes.autoscale_view`.

        Parameters
        ----------
        b : bool
        N)r   rl  r  )r    br   r$   r$   r%   r  }
  s   	z_AxesBase.set_autoscale_onc                 C   rV  )a  
        When autoscaling, whether to obey all `.Artist.sticky_edges`.

        Default is ``True``.

        Setting this to ``False`` ensures that the specified margins
        will be applied, even if the plot includes an image, for
        example, which would otherwise force a view limit to coincide
        with its data limit.

        The changing this property does not change the plot until
        `autoscale` or `autoscale_view` is called.
        )r  r   r$   r$   r%   use_sticky_edges
  s   z_AxesBase.use_sticky_edgesc                 C   s   t || _d S r(   )r  r  r    r  r$   r$   r%   r  
  r  c                 C   rV  )z
        Retrieve autoscaling margin of the x-axis.

        .. versionadded:: 3.9

        Returns
        -------
        xmargin : float

        See Also
        --------
        matplotlib.axes.Axes.set_xmargin
        )r  r   r$   r$   r%   get_xmargin
  r^  z_AxesBase.get_xmarginc                 C   rV  )z
        Retrieve autoscaling margin of the y-axis.

        .. versionadded:: 3.9

        Returns
        -------
        ymargin : float

        See Also
        --------
        matplotlib.axes.Axes.set_ymargin
        )r  r   r$   r$   r%   get_ymargin
  r^  z_AxesBase.get_ymarginc                 C   *   |dkrt d|| _| d d| _dS )a  
        Set padding of X data limits prior to autoscaling.

        *m* times the data interval will be added to each end of that interval
        before it is used in autoscaling.  If *m* is negative, this will clip
        the data range instead of expanding it.

        For example, if your data is in the range [0, 2], a margin of 0.1 will
        result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range
        of [0.2, 1.8].

        Parameters
        ----------
        m : float greater than -0.5
               margin must be greater than -0.5r   TN)r4   r  rv  r  r    mr$   r$   r%   set_xmargin
  
   

z_AxesBase.set_xmarginc                 C   r  )a  
        Set padding of Y data limits prior to autoscaling.

        *m* times the data interval will be added to each end of that interval
        before it is used in autoscaling.  If *m* is negative, this will clip
        the data range instead of expanding it.

        For example, if your data is in the range [0, 2], a margin of 0.1 will
        result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range
        of [0.2, 1.8].

        Parameters
        ----------
        m : float greater than -0.5
        r  r  r   TN)r4   r  rv  r  r   r$   r$   r%   set_ymargin
  r#  z_AxesBase.set_ymargin)r   r   rt  c                G   s   |r|dus
|durt dt|dkr|d  }}nt|dkr&|\}}n|r,t d|du rG|du rG|durAtd|d	 | j| jfS |durN|| _|durW| | |durb| | dS dS )
an	  
        Set or retrieve margins around the data for autoscaling axis limits.

        This allows to configure the padding around the data without having to
        set explicit limits using `~.Axes.set_xlim` / `~.Axes.set_ylim`.

        Autoscaling determines the axis limits by adding *margin* times the
        data interval as padding around the data. See the following illustration:

        .. plot:: _embedded_plots/axes_margins.py

        All input parameters must be floats greater than -0.5. Passing both
        positional and keyword arguments is invalid and will raise a TypeError.
        If no arguments (positional or otherwise) are provided, the current
        margins will remain unchanged and simply be returned.

        The default margins are :rc:`axes.xmargin` and :rc:`axes.ymargin`.

        Parameters
        ----------
        *margins : float, optional
            If a single positional argument is provided, it specifies
            both margins of the x-axis and y-axis limits. If two
            positional arguments are provided, they will be interpreted
            as *xmargin*, *ymargin*. If setting the margin on a single
            axis is desired, use the keyword arguments described below.

        x, y : float, optional
            Specific margin values for the x-axis and y-axis,
            respectively. These cannot be used with positional
            arguments, but can be used individually to alter on e.g.,
            only the y-axis.

        tight : bool or None, default: True
            The *tight* parameter is passed to `~.axes.Axes.autoscale_view`,
            which is executed after a margin is changed; the default
            here is *True*, on the assumption that when margins are
            specified, no additional padding to match tick marks is
            usually desired.  Setting *tight* to *None* preserves
            the previous setting.

        Returns
        -------
        xmargin, ymargin : float

        Notes
        -----
        If a previously used Axes method such as :meth:`pcolor` has set
        `~.Axes.use_sticky_edges` to `True`, only the limits not set by
        the "sticky artists" will be modified. To force all
        margins to be set, set `~.Axes.use_sticky_edges` to `False`
        before calling :meth:`margins`.

        See Also
        --------
        .Axes.set_xmargin, .Axes.set_ymargin
        NzACannot pass both positional and keyword arguments for x and/or y.rR   r   rQ   zVMust pass a single positional argument for all margins, or one for each margin (x, y).Tzignoring tight=z in get mode)	r  rW   r   r   r  r  rs  r"  r$  )r    r   r   rt  marginsr$   r$   r%   r%  
  s&   ;

z_AxesBase.marginsc                 C   r  )a  
        Set the zorder threshold for rasterization for vector graphics output.

        All artists with a zorder below the given value will be rasterized if
        they support rasterization.

        This setting is ignored for pixel-based output.

        See also :doc:`/gallery/misc/rasterization_demo`.

        Parameters
        ----------
        z : float or None
            The zorder below which artists are rasterized.
            If ``None`` rasterization based on zorder is deactivated.
        TN)r%  r  )r    zr$   r$   r%   set_rasterization_zorder=  s   
z"_AxesBase.set_rasterization_zorderc                 C   rV  )z?Return the zorder value below which artists will be rasterized.)r%  r   r$   r$   r%   get_rasterization_zorderQ  rX  z"_AxesBase.get_rasterization_zorderc                 C   s   |du r	d}d}n$|dv r|  t| |  }nd}|dv r+| t| |  }nd}|r4|r4d| _|r;|r;d| _|rD| jd|d |rO| jd	|d dS dS )
a  
        Autoscale the axis view to the data (toggle).

        Convenience method for simple axis view autoscaling.
        It turns autoscaling on or off, and then,
        if autoscaling for either axis is on, it performs
        the autoscaling on the specified axis or Axes.

        Parameters
        ----------
        enable : bool or None, default: True
            True turns autoscaling on, False turns it off.
            None leaves the autoscaling state unchanged.
        axis : {'both', 'x', 'y'}, default: 'both'
            The axis on which to operate.  (For 3D Axes, *axis* can also be set
            to 'z', and 'both' refers to all three Axes.)
        tight : bool or None, default: None
            If True, first set the margins to zero.  Then, this argument is
            forwarded to `~.axes.Axes.autoscale_view` (regardless of
            its value); see the description of its behavior there.
        NTr   r  Fr   r  r   r   r  r   )set_autoscalex_onr  r  set_autoscaley_onr  r  r  rv  )r    enabler   rt  scalexscaleyr$   r$   r%   	autoscaleU  s(   

z_AxesBase.autoscalec                    s  |dur	t | _tg  }} jrK jr/|r/  r/ttdd  j	d 
 D } jrK|rK  rKttdd  j	d 
 D }  dkrW||dk }  dkrc||dk } fd	d
}|| j	d d j j| j || j	d d j j| j dS )a  
        Autoscale the view limits using the data limits.

        Parameters
        ----------
        tight : bool or None
            If *True*, only expand the axis limits using the margins.  Note
            that unlike for `autoscale`, ``tight=True`` does *not* set the
            margins to zero.

            If *False* and :rc:`axes.autolimit_mode` is 'round_numbers', then
            after expansion by the margins, further expand the axis limits
            using the axis major locator.

            If None (the default), reuse the value set in the previous call to
            `autoscale_view` (the initial value is False, but the default style
            sets :rc:`axes.autolimit_mode` to 'data', in which case this
            behaves like True).

        scalex : bool, default: True
            Whether to autoscale the x-axis.

        scaley : bool, default: True
            Whether to autoscale the y-axis.

        Notes
        -----
        The autoscaling preserves any preexisting axis direction reversal.

        The data limits are not updated automatically when artist data are
        changed after the artist has been added to an Axes instance.  In that
        case, use :meth:`matplotlib.axes.Axes.relim` prior to calling
        autoscale_view.

        If the views of the Axes are fixed, e.g. via `set_xlim`, they will
        not be changed by autoscale_view().
        See :meth:`matplotlib.axes.Axes.autoscale` for an alternative.
        Nc                 S   "   g | ]}|  D ]}|jjqqS r$   )get_childrensticky_edgesr   ry   rJ   r  r$   r$   r%   r{         z,_AxesBase.autoscale_view.<locals>.<listcomp>r   c                 S   r1  r$   )r2  r3  r   r4  r$   r$   r%   r{     r5  r   logr   c                    s  | r|  sd S |} fdd|D }|r"t|t|}	}
ntjd   r.d S tj tj}	}
| }|	|	|
\}	}
t fdd|D }dt
|
|	  }||	| d }|dkrf|| nd }||
| }|t|kry|| nd }| }| }|j|	|
|\}	}
||	|
g\}}|| | }t|sd	}||| || g\}	}
|d urt|	|}	|d urt|
|}
js||	|
\}	}
||	|
 d S )
Nc                    s2   g | ]}t |jd   D ]	}t|r|qqS )interval)r   r   r   rH  )ry   rJ   r   ri  r$   r%   r{     s    zH_AxesBase.autoscale_view.<locals>.handle_single_axis.<locals>.<listcomp>mutatedc                 3   s"    | ]}t |jd   V  qdS )r  N)r   r   rh  ri  r$   r%   r     s    
zG_AxesBase.autoscale_view.<locals>.handle_single_axis.<locals>.<genexpr>gh㈵>rR   r   r   )r  r?  r  r   r   rc  r   infget_major_locatornonsingularr]  searchsortedrW   r  rn  r  limit_range_for_scalerA   rH  rs  view_limits)rk  rD  r;   r   marginstickies	set_boundsharedrl  r  r  r  minimum_minpostoli0x0boundi1x1boundrA   inverse_transx0tx1tdeltar   ri  r%   handle_single_axis  sD   



z4_AxesBase.autoscale_view.<locals>.handle_single_axis)r  rs  r   arrayr  r  r  sortr  r>  r?  r  r  
get_xscale
get_yscaler   ro  r   rm  )r    rt  r.  r/  
x_stickies
y_stickiesrM  r$   r   r%   rm    s2   '


>z_AxesBase.autoscale_viewc                 C   s^  | j dur| j std dS | j| j| jf}tdd |D s"dS t }|| j	 || j
|  || jddjd |  | j	D ]}| }||rU|| |nd qFtj }|D ]+}d}|j dv sq|j d	krw|j|}|du r|jd
| }t||j}q_|D ]}| \}	}
||	df | r|D ]!}|j| |jj r|jj|}| |||r|j}q|dk rtd  dS ||j!|k r| j"# $d|f\}
}||	|f ||j!|k r| j"# $dd| ||j! f\}
}||	|f qtdd |D }|D ]}| \}	}
||	|f qdS )z
        Update the title position based on the bounding box enclosing
        all the ticklabels and x-axis spine and xlabel...
        Nz2title position was updated manually, not adjustingc                 s   r  r(   )rQ  ry   rT  r$   r$   r%   r     r   z3_AxesBase._update_title_position.<locals>.<genexpr>FrB   rT  )r   unknownr   outliner  r   z1top of Axes not in the figure, so title not movedr  rQ   c                 s   s    | ]	}|  d  V  qdS )rR   N)rZ  rT  r$   r$   r%   r   B  s    )%r  rk  debugrT  r  r  r   r   updater  r@  r?  rH   _align_label_groupsr  r  r   r9  r   get_ticks_positionget_label_positionget_tightbboxr   r   r]  r   r{  rZ  r  rQ  r   
offsetTextintersectionrz  rx  rn  rA   )r    rK   rS  rU  rJ   r  r   rr  rT  r   r  r   r{  r$   r$   r%   _update_title_position  sh   



z _AxesBase._update_title_positionc           	      C   s  |d u rt d|  sd S |   |jd|  d d| _|  }| |r+|| |nd  |  }|	| j
 | jr>| jsK| j D ]}|	| qC| | | js`| j D ]}|	| qX| jddj spdd |D }t|tdd	}| j}|d ur|r|d
 j|k rtjdd |D |dd}|d | }||d  }ng }| jr| jr|r| j
g| }n| j
g| }|rt| jdd|| t|| || jddj |d d| _d S )NzNo renderer definedr   )gidTrB   c                 S   s$   g | ]}|  rt|tjr|qS r$   )get_animatedr   r.  r/  rx   r$   r$   r%   r{   m  s    
z"_AxesBase.draw.<locals>.<listcomp>zorderr"  r   c                 S   s   g | ]}|j qS r$   )rb  )ry   artr$   r$   r%   r{   y  s    r   )r  F) rf  r  ro  
open_groupget_gidrC  r  r  r2  r  r  axisonr#  r   rl  r_  r   rH   canvas	is_savingsortedr   r%  rb  r   r<  _draw_rasterizedr.  _draw_list_compositing_imagessuppressCompositeclose_groupr  )	r    rK   r  r+  r	  _axisrasterization_zordersplit_indexartists_rasterizedr$   r$   r%   drawI  s\   


z_AxesBase.drawc                 C   s   | | jddj  dS )z5
        Efficiently redraw a single artist.
        TrB   N)rs  rH   rh  get_rendererr  r$   r$   r%   draw_artist  s   z_AxesBase.draw_artistc                 C   s|   t  1}g | j | j| j| jD ]}||jdd q| | j	ddj
  W d   dS 1 s7w   Y  dS )zP
        Efficiently redraw Axes data, but not axis ticks, labels, etc.
        F)visibleTrB   N)r   r   rl  rT  r  r  enter_context_cm_setrs  rH   rh  rt  )r    r   r  r$   r$   r%   redraw_in_frame  s   "z_AxesBase.redraw_in_framec                 C   rV  )z.Get whether the Axes rectangle patch is drawn.)r#  r   r$   r$   r%   get_frame_on  rX  z_AxesBase.get_frame_onc                 C   r  )zx
        Set whether the Axes rectangle patch is drawn.

        Parameters
        ----------
        b : bool
        TN)r#  r  r  r$   r$   r%   set_frame_on  r  z_AxesBase.set_frame_onc                 C   rV  )z
        Get whether axis ticks and gridlines are above or below most artists.

        Returns
        -------
        bool or 'line'

        See Also
        --------
        set_axisbelow
        )
_axisbelowr   r$   r$   r%   get_axisbelow  rP  z_AxesBase.get_axisbelowc                 C   sB   t | | _}dddd| }| j D ]}|| qd| _dS )a  
        Set whether axis ticks and gridlines are above or below most artists.

        This controls the zorder of the ticks and gridlines. For more
        information on the zorder see :doc:`/gallery/misc/zorder_demo`.

        Parameters
        ----------
        b : bool or 'line'
            Possible values:

            - *True* (zorder = 0.5): Ticks and gridlines are below patches and
              lines, though still above images.
            - 'line' (zorder = 1.5): Ticks and gridlines are above patches
              (e.g. rectangles, with default zorder = 1) but still below lines
              and markers (with their default zorder = 2).
            - *False* (zorder = 2.5): Ticks and gridlines are above patches
              and lines / markers.

        Notes
        -----
        For more control, call the `~.Artist.set_zorder` method of each axis.

        See Also
        --------
        get_axisbelow
        r  g      ?g      @)Tr  FTN)r   r|  r   rl  
set_zorderr  )r    r  	axisbelowrb  r   r$   r$   r%   r$    s   
z_AxesBase.set_axisbelowr   c                 K   sZ   t jg d|d |dv r| jj|fd|i| |dv r+| jj|fd|i| dS dS )a  
        Configure the grid lines.

        Parameters
        ----------
        visible : bool or None, optional
            Whether to show the grid lines.  If any *kwargs* are supplied, it
            is assumed you want the grid on and *visible* will be set to True.

            If *visible* is *None* and there are no *kwargs*, this toggles the
            visibility of the lines.

        which : {'major', 'minor', 'both'}, optional
            The grid lines to apply the changes on.

        axis : {'both', 'x', 'y'}, optional
            The axis to apply the changes on.

        **kwargs : `~matplotlib.lines.Line2D` properties
            Define the line properties of the grid, e.g.::

                grid(color='r', linestyle='-', linewidth=2)

            Valid keyword arguments are:

            %(Line2D:kwdoc)s

        Notes
        -----
        The axis is drawn as a unit, so the effective zorder for drawing the
        grid is determined by the zorder of each axis, not by the zorder of the
        `.Line2D` objects comprising the grid.  Therefore, to set grid zorder,
        use `.set_axisbelow` or, for more control, call the
        `~.Artist.set_zorder` method of each axis.
        r   r   r  r   r)  r   r*  N)r   rp   r   r  r   )r    rv  r   r   r*   r$   r$   r%   r    s   %z_AxesBase.grid)r   style	scilimits	useOffset	useLocaleuseMathTextc             
   C   sZ  t |tr	| }| }|dur1z|\}}|| d  W n ttfy0 }	 ztd|	d}	~	ww dddddd}
tj|
|d}i dd	 | j D d
t	| j
 i}tj||d}z?|D ]9}|durl|jj| |durw|jj| |dur|jj| |dur|jj| |dur|jj| q_W dS  ty }	 ztd|	d}	~	ww )a   
        Configure the `.ScalarFormatter` used by default for linear Axes.

        If a parameter is not set, the corresponding property of the formatter
        is left unchanged.

        Parameters
        ----------
        axis : {'x', 'y', 'both'}, default: 'both'
            The axis to configure.  Only major ticks are affected.

        style : {'sci', 'scientific', 'plain'}
            Whether to use scientific notation.
            The formatter default is to use scientific notation.
            'sci' is equivalent to 'scientific'.

        scilimits : pair of ints (m, n)
            Scientific notation is used only for numbers outside the range
            10\ :sup:`m` to 10\ :sup:`n` (and only if the formatter is
            configured to use scientific notation at all).  Use (0, 0) to
            include all numbers.  Use (m, m) where m != 0 to fix the order of
            magnitude to 10\ :sup:`m`.
            The formatter default is :rc:`axes.formatter.limits`.

        useOffset : bool or float
            If True, the offset is calculated as needed.
            If False, no offset is used.
            If a numeric value, it sets the offset.
            The formatter default is :rc:`axes.formatter.useoffset`.

        useLocale : bool
            Whether to format the number using the current locale or using the
            C (English) locale.  This affects e.g. the decimal separator.  The
            formatter default is :rc:`axes.formatter.use_locale`.

        useMathText : bool
            Render the offset and scientific notation in mathtext.
            The formatter default is :rc:`axes.formatter.use_mathtext`.

        Raises
        ------
        AttributeError
            If the current formatter is not a `.ScalarFormatter`.
        NrR   z*scilimits must be a sequence of 2 integersTF)sci
scientificplainr   N)r  c                 S   s   i | ]\}}||gqS r$   r$   r   r$   r$   r%   r   L  r   z._AxesBase.ticklabel_format.<locals>.<dictcomp>r  r   z/This method only works with the ScalarFormatter)r   r   r   r4   r  r   rr  r   r   r   rl  r   	formatterset_scientificset_powerlimitsset_useOffsetset_useLocaleset_useMathTextAttributeError)r    r   r  r  r  r  r  r!  nerrSTYLESis_sci_styler  axisesr$   r$   r%   ticklabel_format  sR   
.z_AxesBase.ticklabel_formatc                 K   sf   t jg | jd|d | jD ]}||dfv r-| j|  }|jdi | | j||d qd| _dS )a  
        Control behavior of major tick locators.

        Because the locator is involved in autoscaling, `~.Axes.autoscale_view`
        is called automatically after the parameters are changed.

        Parameters
        ----------
        axis : {'both', 'x', 'y'}, default: 'both'
            The axis on which to operate.  (For 3D Axes, *axis* can also be
            set to 'z', and 'both' refers to all three axes.)
        tight : bool or None, optional
            Parameter passed to `~.Axes.autoscale_view`.
            Default is None, for no change.

        Other Parameters
        ----------------
        **kwargs
            Remaining keyword arguments are passed to directly to the
            ``set_params()`` method of the locator. Supported keywords depend
            on the type of the locator. See for example
            `~.ticker.MaxNLocator.set_params` for the `.ticker.MaxNLocator`
            used by default for linear.

        Examples
        --------
        When plotting small subplots, one might want to reduce the maximum
        number of ticks and use tight bounds, for example::

            ax.locator_params(tight=True, nbins=4)

        r  r   r  TNr$   )r   rp   r   r   r:  
set_paramsrv  r  )r    r   rt  r*   r;   rL  r$   r$   r%   locator_params_  s   !

z_AxesBase.locator_paramsc                 K   s   t jg d|d |dv r2t|}|dd |dd |dd |dd | jjdi | |d	v r]t|}|d
d |dd |dd |dd | jjdi | dS dS )ac	  
        Change the appearance of ticks, tick labels, and gridlines.

        Tick properties that are not explicitly set using the keyword
        arguments remain unchanged unless *reset* is True. For the current
        style settings, see `.Axis.get_tick_params`.

        Parameters
        ----------
        axis : {'x', 'y', 'both'}, default: 'both'
            The axis to which the parameters are applied.
        which : {'major', 'minor', 'both'}, default: 'major'
            The group of ticks to which the parameters are applied.
        reset : bool, default: False
            Whether to reset the ticks to defaults before updating them.

        Other Parameters
        ----------------
        direction : {'in', 'out', 'inout'}
            Puts ticks inside the Axes, outside the Axes, or both.
        length : float
            Tick length in points.
        width : float
            Tick width in points.
        color : :mpltype:`color`
            Tick color.
        pad : float
            Distance in points between tick and label.
        labelsize : float or str
            Tick label font size in points or as a string (e.g., 'large').
        labelcolor : :mpltype:`color`
            Tick label color.
        labelfontfamily : str
            Tick label font.
        colors : :mpltype:`color`
            Tick color and label color.
        zorder : float
            Tick and label zorder.
        bottom, top, left, right : bool
            Whether to draw the respective ticks.
        labelbottom, labeltop, labelleft, labelright : bool
            Whether to draw the respective tick labels.
        labelrotation : float
            Tick label rotation
        grid_color : :mpltype:`color`
            Gridline color.
        grid_alpha : float
            Transparency of gridlines: 0 (transparent) to 1 (opaque).
        grid_linewidth : float
            Width of gridlines in points.
        grid_linestyle : str
            Any valid `.Line2D` line style spec.

        Examples
        --------
        ::

            ax.tick_params(direction='out', length=6, width=2, colors='r',
                           grid_color='r', grid_alpha=0.5)

        This will make all major ticks be red, pointing out of the box,
        and with dimensions 6 points by 2 points.  Tick labels will
        also be red.  Gridlines will be red and translucent.

        r  r   r)  r   Nr   r   r   r*  r   r   r   r   r$   )r   rp   r  r   r   set_tick_paramsr   )r    r   r*   xkwykwr$   r$   r%   r1    s    Bz_AxesBase.tick_paramsc                 C   s   d| _ d| _dS )ar  
        Hide all visual components of the x- and y-axis.

        This sets a flag to suppress drawing of all axis decorations, i.e.
        axis labels, axis spines, and the axis tick component (tick markers,
        tick labels, and grid lines). Individual visibility settings of these
        components are ignored as long as `set_axis_off()` is in effect.
        FTNrg  r  r   r$   r$   r%   r    s   	
z_AxesBase.set_axis_offc                 C   s   d| _ d| _dS )a&  
        Do not hide all visual components of the x- and y-axis.

        This reverts the effect of a prior `.set_axis_off()` call. Whether the
        individual axis decorations are drawn is controlled by their respective
        visibility settings.

        This is on by default.
        TNr  r   r$   r$   r%   r    s   

z_AxesBase.set_axis_onc                 C      | j j}| S )z-
        Get the xlabel text string.
        )r   r   rQ  r    r   r$   r$   r%   
get_xlabel     z_AxesBase.get_xlabelrK  c                K   s   |dur|| j _g d}h |h |@ r!|dur td| dn!|dur'|ntjd }tjd|d dd	d
d| }|j||d | j j||fi |S )a1  
        Set the label for the x-axis.

        Parameters
        ----------
        xlabel : str
            The label text.

        labelpad : float, default: :rc:`axes.labelpad`
            Spacing in points from the Axes bounding box including ticks
            and tick labels.  If None, the previous value is left as is.

        loc : {'left', 'center', 'right'}, default: :rc:`xaxis.labellocation`
            The label position. This is a high-level alternative for passing
            parameters *x* and *horizontalalignment*.

        Other Parameters
        ----------------
        **kwargs : `~matplotlib.text.Text` properties
            `.Text` properties control the appearance of the label.

        See Also
        --------
        text : Documents the properties supported by `.Text`.
        N)r   r  haZSpecifying 'loc' is disallowed when any of its corresponding low level keyword arguments () are also suppliedzxaxis.labellocationrI  rK  r   r  rR   )r   r  )	r   labelpadr  r^   r_   r   rp   rX  set_label_text)r    xlabelfontdictr  rL  r*   protected_kwr   r$   r$   r%   
set_xlabel  s*   
z_AxesBase.set_xlabelc                 C      | j | j    dS )z
        Invert the x-axis.

        See Also
        --------
        xaxis_inverted
        get_xlim, set_xlim
        get_xbound, set_xbound
        N)r   set_invertedget_invertedr   r$   r$   r%   invert_xaxis/     
z_AxesBase.invert_xaxisr  c                 C   $   |   \}}||k r||fS ||fS )z
        Return the lower and upper x-axis bounds, in increasing order.

        See Also
        --------
        set_xbound
        get_xlim, set_xlim
        invert_xaxis, xaxis_inverted
        )r  )r    r   r   r$   r$   r%   r[  =     
z_AxesBase.get_xboundc                 C   d   |du rt |r|\}}|  \}}|du r|}|du r|}| jt||ft|  ddd dS )aF  
        Set the lower and upper numerical bounds of the x-axis.

        This method will honor axis inversion regardless of parameter order.
        It will not change the autoscaling setting (`.get_autoscalex_on()`).

        Parameters
        ----------
        lower, upper : float or None
            The lower and upper bounds. If *None*, the respective axis bound
            is not modified.

            .. ACCEPTS: (lower: float, upper: float)

        See Also
        --------
        get_xbound
        get_xlim, set_xlim
        invert_xaxis, xaxis_inverted
        Nreverser  )r   r  r[  r  rj  r  xaxis_invertedr    r   upper	old_lower	old_upperr$   r$   r%   ro  M     

z_AxesBase.set_xboundc                 C      t | jjS )a  
        Return the x-axis view limits.

        Returns
        -------
        left, right : (float, float)
            The current x-axis limits in data coordinates.

        See Also
        --------
        .Axes.set_xlim
        .Axes.set_xbound, .Axes.get_xbound
        .Axes.invert_xaxis, .Axes.xaxis_inverted

        Notes
        -----
        The x-axis may be inverted, in which case the *left* value will
        be greater than the *right* value.
        )r%  rp  ri  r   r$   r$   r%   r  o     z_AxesBase.get_xlimc                 C   sH   |dur"||}t |tjr| }t |tr t|s td|S dS )z
        Raise ValueError if converted limits are non-finite.

        Note that this function also accepts None as a limit argument.

        Returns
        -------
        The limit value after call to convert(), or None if limit is None.
        Nz Axis limits cannot be NaN or Inf)r   r   ndarraysqueezer   rH  r4   )r    limitr  converted_limitr$   r$   r%   _validate_converted_limits  s   

z$_AxesBase._validate_converted_limits)r  r   rx  ry  c                C   f   |du rt |r|\}}|dur|durtd|}|dur)|dur'td|}| jj||||dS )a  
        Set the x-axis view limits.

        Parameters
        ----------
        left : float, optional
            The left xlim in data coordinates. Passing *None* leaves the
            limit unchanged.

            The left and right xlims may also be passed as the tuple
            (*left*, *right*) as the first positional argument (or as
            the *left* keyword argument).

            .. ACCEPTS: (left: float, right: float)

        right : float, optional
            The right xlim in data coordinates. Passing *None* leaves the
            limit unchanged.

        emit : bool, default: True
            Whether to notify observers of limit change.

        auto : bool or None, default: False
            Whether to turn on autoscaling of the x-axis. True turns on,
            False turns off, None leaves unchanged.

        xmin, xmax : float, optional
            They are equivalent to left and right respectively, and it is an
            error to pass both *xmin* and *left* or *xmax* and *right*.

        Returns
        -------
        left, right : (float, float)
            The new x-axis limits in data coordinates.

        See Also
        --------
        get_xlim
        set_xbound, get_xbound
        invert_xaxis, xaxis_inverted

        Notes
        -----
        The *left* value may be greater than the *right* value, in which
        case the x-axis values will decrease from left to right.

        Examples
        --------
        >>> set_xlim(left, right)
        >>> set_xlim((left, right))
        >>> left, right = set_xlim(left, right)

        One limit may be left unchanged.

        >>> set_xlim(right=right_lim)

        Limits may be passed in reverse order to flip the direction of
        the x-axis. For example, suppose *x* represents the number of
        years before present. The x-axis limits might be set like the
        following so 5000 years ago is on the left of the plot and the
        present is on the right.

        >>> set_xlim(5000, 0)
        Nz"Cannot pass both 'left' and 'xmin'z#Cannot pass both 'right' and 'xmax'r  )r   r  r  r   r  )r    r   r   r  r   rx  ry  r$   r$   r%   r       Bz_AxesBase.set_xlim	get_scale_set_axes_scaleget_ticklocs	set_ticks
set_xticksr   get_majorticklabelsget_minorticklabelsget_ticklabelsset_ticklabelszAxis.set_tickszAxes.set_xticksc                 C   r  )z-
        Get the ylabel text string.
        )r   r   rQ  r  r$   r$   r%   
get_ylabel  r  z_AxesBase.get_ylabelc          	      K   s   |dur|| j _g d}h |h |@ r!|dur td| dn#|dur'|ntjd }tjd|d dd	d
d| \}}|j||d | j j||fi |S )a1  
        Set the label for the y-axis.

        Parameters
        ----------
        ylabel : str
            The label text.

        labelpad : float, default: :rc:`axes.labelpad`
            Spacing in points from the Axes bounding box including ticks
            and tick labels.  If None, the previous value is left as is.

        loc : {'bottom', 'center', 'top'}, default: :rc:`yaxis.labellocation`
            The label position. This is a high-level alternative for passing
            parameters *y* and *horizontalalignment*.

        Other Parameters
        ----------------
        **kwargs : `~matplotlib.text.Text` properties
            `.Text` properties control the appearance of the label.

        See Also
        --------
        text : Documents the properties supported by `.Text`.
        N)r   r  r  r  r  zyaxis.labellocation)r   rJ  r   rK  )r   r   )r  rJ  )rR   r   )r   r  )	r   r  r  r^   r_   r   rp   rX  r  )	r    ylabelr  r  rL  r*   r  r   r  r$   r$   r%   
set_ylabel  s*   
z_AxesBase.set_ylabelc                 C   r  )z
        Invert the y-axis.

        See Also
        --------
        yaxis_inverted
        get_ylim, set_ylim
        get_ybound, set_ybound
        N)r   r  r  r   r$   r$   r%   invert_yaxis,  r  z_AxesBase.invert_yaxisc                 C   r  )z
        Return the lower and upper y-axis bounds, in increasing order.

        See Also
        --------
        set_ybound
        get_ylim, set_ylim
        invert_yaxis, yaxis_inverted
        )r  )r    r   r   r$   r$   r%   r\  :  r  z_AxesBase.get_yboundc                 C   r  )aC  
        Set the lower and upper numerical bounds of the y-axis.

        This method will honor axis inversion regardless of parameter order.
        It will not change the autoscaling setting (`.get_autoscaley_on()`).

        Parameters
        ----------
        lower, upper : float or None
            The lower and upper bounds. If *None*, the respective axis bound
            is not modified.

         .. ACCEPTS: (lower: float, upper: float)

        See Also
        --------
        get_ybound
        get_ylim, set_ylim
        invert_yaxis, yaxis_inverted
        Nr  r  )r   r  r\  r  rj  r  yaxis_invertedr  r$   r$   r%   rm  J  r  z_AxesBase.set_yboundc                 C   r  )a  
        Return the y-axis view limits.

        Returns
        -------
        bottom, top : (float, float)
            The current y-axis limits in data coordinates.

        See Also
        --------
        .Axes.set_ylim
        .Axes.set_ybound, .Axes.get_ybound
        .Axes.invert_yaxis, .Axes.yaxis_inverted

        Notes
        -----
        The y-axis may be inverted, in which case the *bottom* value
        will be greater than the *top* value.
        )r%  rp  rj  r   r$   r$   r%   r  l  r  z_AxesBase.get_ylim)r  r   rz  r{  c                C   r  )a  
        Set the y-axis view limits.

        Parameters
        ----------
        bottom : float, optional
            The bottom ylim in data coordinates. Passing *None* leaves the
            limit unchanged.

            The bottom and top ylims may also be passed as the tuple
            (*bottom*, *top*) as the first positional argument (or as
            the *bottom* keyword argument).

            .. ACCEPTS: (bottom: float, top: float)

        top : float, optional
            The top ylim in data coordinates. Passing *None* leaves the
            limit unchanged.

        emit : bool, default: True
            Whether to notify observers of limit change.

        auto : bool or None, default: False
            Whether to turn on autoscaling of the y-axis. *True* turns on,
            *False* turns off, *None* leaves unchanged.

        ymin, ymax : float, optional
            They are equivalent to bottom and top respectively, and it is an
            error to pass both *ymin* and *bottom* or *ymax* and *top*.

        Returns
        -------
        bottom, top : (float, float)
            The new y-axis limits in data coordinates.

        See Also
        --------
        get_ylim
        set_ybound, get_ybound
        invert_yaxis, yaxis_inverted

        Notes
        -----
        The *bottom* value may be greater than the *top* value, in which
        case the y-axis values will decrease from *bottom* to *top*.

        Examples
        --------
        >>> set_ylim(bottom, top)
        >>> set_ylim((bottom, top))
        >>> bottom, top = set_ylim(bottom, top)

        One limit may be left unchanged.

        >>> set_ylim(top=top_lim)

        Limits may be passed in reverse order to flip the direction of
        the y-axis. For example, suppose ``y`` represents depth of the
        ocean in m. The y-axis limits might be set like the following
        so 5000 m depth is at the bottom of the plot and the surface,
        0 m, is at the top.

        >>> set_ylim(5000, 0)
        Nz$Cannot pass both 'bottom' and 'ymin'z!Cannot pass both 'top' and 'ymax'r  )r   r  r  r   r  )r    r   r   r  r   rz  r{  r$   r$   r%   r    r  z_AxesBase.set_ylim
set_ytickszAxes.set_yticks	axis_datec                 C   $   | j dur
| j |S | j j|S )z
        Return *x* formatted as an x-value.

        This function will use the `.fmt_xdata` attribute if it is not None,
        else will fall back on the xaxis major formatter.
        N)r'  r   get_major_formatterformat_data_short)r    r   r$   r$   r%   format_xdata  
   z_AxesBase.format_xdatac                 C   r  )z
        Return *y* formatted as a y-value.

        This function will use the `.fmt_ydata` attribute if it is not None,
        else will fall back on the yaxis major formatter.
        N)r(  r   r  r  )r    r   r$   r$   r%   format_ydata  r  z_AxesBase.format_ydatac           	   	   C   s   | j | }t|dkr%d|du rdn| ||du rdS | |S | j||f}g }t|t	ddD ]}|j
 |\}}|d|||| q7dd	|S )
z;Return a format string formatting the *x*, *y* coordinates.rR   z(x, y) = ({}, {})Nz???rb  rc  z({}, {})z(x, y) = {}z | )r@  r?  rW   r5   r  r  r{  rA   rj  r   rn  r   r6   )	r    r   r   twins	screen_xyxy_strsrJ   data_xdata_yr$   r$   r%   format_coord  s    
z_AxesBase.format_coordc                 C      | j   | j  dS )z
        Display minor ticks on the Axes.

        Displaying minor ticks may reduce performance; you may turn them off
        using `minorticks_off()` if drawing speed is a problem.
        N)r   minorticks_onr   r   r$   r$   r%   r    s   
z_AxesBase.minorticks_onc                 C   r  )z!Remove minor ticks from the Axes.N)r   minorticks_offr   r   r$   r$   r%   r    s   
z_AxesBase.minorticks_offc                 C      dS )zV
        Return whether this Axes supports the zoom box button functionality.
        Tr$   r   r$   r$   r%   can_zoom     z_AxesBase.can_zoomc                 C   r  )zV
        Return whether this Axes supports any pan/zoom button functionality.
        Tr$   r   r$   r$   r%   can_pan  r  z_AxesBase.can_panc                 C   rV  )zG
        Get whether the Axes responds to navigation commands.
        	_navigater   r$   r$   r%   get_navigate!  r  z_AxesBase.get_navigatec                 C   
   || _ dS )z
        Set whether the Axes responds to navigation toolbar commands.

        Parameters
        ----------
        b : bool

        See Also
        --------
        matplotlib.axes.Axes.set_forward_navigation_events

        Nr  r  r$   r$   r%   r)  '  s   
z_AxesBase.set_navigatec                 C   rV  )zS
        Get the navigation toolbar button status: 'PAN', 'ZOOM', or None.
        _navigate_moder   r$   r$   r%   get_navigate_mode6  r  z_AxesBase.get_navigate_modec                 C   r  )z
        Set the navigation toolbar button status.

        .. warning::
            This is not a user-API function.

        Nr  r  r$   r$   r%   r*  <  s   
z_AxesBase.set_navigate_modec                 C   s   |   |  |  |  dS )a  
        Save information required to reproduce the current view.

        This method is called before a view is changed, such as during a pan or zoom
        initiated by the user.  It returns an opaque object that describes the current
        view, in a format compatible with :meth:`_set_view`.

        The default implementation saves the view limits and autoscaling state.
        Subclasses may override this as needed, as long as :meth:`_set_view` is also
        adjusted accordingly.
        )r  autoscalex_onr  autoscaley_on)r  r  r  r  r   r$   r$   r%   	_get_viewF  s   z_AxesBase._get_viewc                 C   s   | j di | dS )a7  
        Apply a previously saved view.

        This method is called when restoring a view (with the return value of
        :meth:`_get_view` as argument), such as with the navigation buttons.

        Subclasses that override :meth:`_get_view` also need to override this method
        accordingly.
        Nr$   )r   )r    viewr$   r$   r%   	_set_viewW  s   
z_AxesBase._set_viewinc           ,      C   s  t |dkrz|\}}}|dkrd}|dkrd}nd}d| }| jt|  |  g\\}	}
\}}||	 }||
 }||	 d }||
 d }||d  | | }||d  | | }||d |  ||d |  ||d |  ||d |  g}nt |d	krtd
 dS | 	 \}}| 
 \}}|\}}}}| j ||f||fg\\}}\}}tt||g||\}	}tt||g||\}
}|s|dkr||}	}|s|dkr||}
}|dkr|	|f}|
|f}||fS |dkrX| j }||||	|g\}}} }!|| |!|   }"||"| |   }#||"||!   }$| |#|$g}| j }%|%|||
|g\}&}'}(})|'|& |)|(  }"|&|"|(|&   }*|'|"|'|)   }+|% |*|+g}||fS )z
        Helper function to prepare the new bounds from a bbox.

        This helper function returns the new x and y bounds from the zoom
        bbox. This a convenience method to abstract the bbox logic
        out of the base setter.
        r   r   r  rR   r  outr  rd  r   zgWarning in _set_view_from_bbox: bounding box is not a tuple of length 3 or 4. Ignoring the view change.Nr   r   )rW   r{  rA   r   	transposer  r  r   r   r[  r\  rn  cliprj  r   r  r   ),r    r\  	directionmodetwinxtwinyxpypsclrx  rz  ry  r{  xwidthywidthxcenycenxzcyzcxmin0xmax0ymin0ymax0startxstartystopxstopy
new_xbound
new_yboundrv  sxmin0sxmax0sxminsxmaxfactorsxmin1sxmax1rw  symin0symax0syminsymaxsymin1symax1r$   r$   r%   _prepare_view_from_bboxc  sv   	








z!_AxesBase._prepare_view_from_bboxc                 C   sd   | j |||||d\}}|s|dkr| | | d |s.|dkr0| | | d dS dS dS )a  
        Update view from a selection bbox.

        .. note::

            Intended to be overridden by new projection types, but if not, the
            default implementation sets the view limits to the bbox directly.

        Parameters
        ----------
        bbox : 4-tuple or 3 tuple
            * If bbox is a 4 tuple, it is the selected bounding box limits,
              in *display* coordinates.
            * If bbox is a 3 tuple, it is an (xp, yp, scl) triple, where
              (xp, yp) is the center of zooming and scl the scale factor to
              zoom by.

        direction : str
            The direction to apply the bounding box.
                * `'in'` - The bounding box describes the view directly, i.e.,
                           it zooms in.
                * `'out'` - The bounding box describes the size to make the
                            existing view, i.e., it zooms out.

        mode : str or None
            The selection mode, whether to apply the bounding box in only the
            `'x'` direction, `'y'` direction or both (`None`).

        twinx : bool
            Whether this axis is twinned in the *x*-direction.

        twiny : bool
            Whether this axis is twinned in the *y*-direction.
        )r  r  r  r  r   Fr   N)r  ro  r+  rm  r,  )r    r\  r  r  r  r  r
  r  r$   r$   r%   _set_view_from_bbox  s   $




z_AxesBase._set_view_from_bboxc                 C   s8   t j| j | j | j  | j ||d| _dS )aQ  
        Called when a pan operation has started.

        Parameters
        ----------
        x, y : float
            The mouse coordinates in display coords.
        button : `.MouseButton`
            The pressed mouse button.

        Notes
        -----
        This is intended to be overridden by new projection types.
        )r  rq  trans_inverser\  r   r   N)typesSimpleNamespacerp  r  r{  rn  r\  
_pan_start)r    r   r   buttonr$   r$   r%   	start_pan  s   z_AxesBase.start_panc                 C   s   | ` dS )z
        Called when a pan operation completes (when the mouse button is up.)

        Notes
        -----
        This is intended to be overridden by new projection types.
        N)r  r   r$   r$   r%   end_pan  s   z_AxesBase.end_panc                 C   sf  dd }| j }||j }||j }||  krdkrdS  |dkr7||||\}}|j| | |j}	ne|dkrzO| | jj }| | jj }||||\}}| 	 dkr`d||   }}t
d	||f}
t
|j|jg}|j|j}||
||   }t||j}	W n ty   td
 Y dS w dS t
|	|j}|	 t}d|| < |S )z
        Helper function to return the new points after a pan.

        This helper function returns the points on the axis after a pan has
        occurred. This is a convenience method to abstract the pan logic
        out of the base setter.
        c                 S   s   | dkrt |t |kr|}||fS |}||fS | dkr"d}||fS | dkr,d}||fS | dkrpdt | t |k r@d}||fS dt | t |k rPd}||fS t |t |krf|t | t | }||fS |t | t | }||fS )Ncontrolr   r   r   shiftrQ   )r]  )r"  dxdyr$   r$   r%   format_deltas	  s0   
z0_AxesBase._get_pan_points.<locals>.format_deltasr   NrR   r   r   r  g      $@zOverflow while panning)r  r   r   r\  
translatedre  r  r	  r
  r@  r   powerrN  r  rq  rD   rF   OverflowErrorr   r   rH  r  astyper  )r    r  r"  r   r   r&  r  r$  r%  r   alphastart	oldpoints	newpointsvalidr  r$   r$   r%   _get_pan_points  sB   



z_AxesBase._get_pan_pointsc                 C   sL   |  ||||}|dur$| |dddf  | |dddf  dS dS )a  
        Called when the mouse moves during a pan operation.

        Parameters
        ----------
        button : `.MouseButton`
            The pressed mouse button.
        key : str or None
            The pressed key, if any.
        x, y : float
            The mouse coordinates in display coords.

        Notes
        -----
        This is intended to be overridden by new projection types.
        Nr   rR   )r0  r  r  )r    r  r"  r   r   r  r$   r$   r%   drag_pan?  s
   z_AxesBase.drag_panc                 C   sR   g | j | j | j | j| j| j| j| jd ur#| jgng | j	S r(   )
r  r   rl  r   rT  r  r  r  r  r  r   r$   r$   r%   r2  U  s&   z_AxesBase.get_childrenc                 C   s   | j |S r(   r  r  r$   r$   r%   r  a  s   z_AxesBase.containsc                 C   s   | j j|ddS )zf
        Return whether *point* (pair of pixel coordinates) is inside the Axes
        patch.
        r  )radius)r  contains_point)r    pointr$   r$   r%   r3  e  s   z_AxesBase.contains_pointc                    s   |   }| j D ]}|| q	| jr| js$| j D ]}|| q|| j || j || j	 t
tjtjtjf  fdd|D S )z
        Return a default list of artists that are used for the bounding box
        calculation.

        Artists are excluded either by not being visible or
        ``artist.set_in_layout(False)``.
        c                    s2   g | ]}|  r| rt| s| s|qS r$   )r  get_in_layoutr   _fully_clipped_to_axesrx   noclipr$   r%   r{     s
    
z<_AxesBase.get_default_bbox_extra_artists.<locals>.<listcomp>)r2  r   rl  r  rg  r#  r   rT  r  r  r   r   r   r
   AnnotationBbox	OffsetBox)r    r+  r   r	  r$   r7  r%   get_default_bbox_extra_artistsl  s   	z(_AxesBase.get_default_bbox_extra_artists)call_axes_locatorbbox_extra_artistsfor_layout_onlyc                C   s  g }|du r| j dd }|  sdS |  }| |r#|r#|| |nd | j D ]}| jrA| rAt	||}|rA|
| q+| | | |}	|
|	 | j| j| jfD ](}
|
 r|
|}|r||jdkr||j|j d d |_|jd |_|
| qY|}|du r|  }|D ],}||}|durd|j  k rtjk rn qd|j  k rtjk rn q|
| qtjdd	 |D S )
a  
        Return the tight bounding box of the Axes, including axis and their
        decorators (xlabel, title, etc).

        Artists that have ``artist.set_in_layout(False)`` are not included
        in the bbox.

        Parameters
        ----------
        renderer : `.RendererBase` subclass
            renderer that will be used to draw the figures (i.e.
            ``fig.canvas.get_renderer()``)

        bbox_extra_artists : list of `.Artist` or ``None``
            List of artists to include in the tight bounding box.  If
            ``None`` (default), then all artist children of the Axes are
            included in the tight bounding box.

        call_axes_locator : bool, default: True
            If *call_axes_locator* is ``False``, it does not call the
            ``_axes_locator`` attribute, which is necessary to get the correct
            bounding box. ``call_axes_locator=False`` can be used if the
            caller is only interested in the relative size of the tightbbox
            compared to the Axes bbox.

        for_layout_only : default: False
            The bounding box will *not* include the x-extent of the title and
            the xlabel, or the y-extent of the ylabel.

        Returns
        -------
        `.BboxBase`
            Bounding box in figure pixel coordinates.

        See Also
        --------
        matplotlib.axes.Axes.get_window_extent
        matplotlib.axis.Axis.get_tightbbox
        matplotlib.spines.Spine.get_window_extent
        NTrB   r   rQ   r  r  c                 S   s$   g | ]}|j d ks|jd kr|qS r   )r	  r
  )ry   r  r$   r$   r%   r{     s   $ z+_AxesBase.get_tightbbox.<locals>.<listcomp>)rH   _get_rendererr  r  r  r   rl  rg  r  _get_tightbbox_for_layout_onlyr   r_  r]  rT  r  r  r	  r  r  r;  r\  r   r9  r
  rD   rF   union)r    rK   r<  r=  r>  rr  r  r   baaxbboxrT  btbbox_artistsrz   r\  r$   r$   r%   r\    sN   +







z_AxesBase.get_tightbboxc                 O   s   d|v rd|v r|d | ur|d | urt d|  }|r/| jddj|g|R i |}n| jddj| dg|R i |dtg d| ji}| d	 |d	 |	| j
 | j| | |S )
z<Make a twinx Axes of self. This is used for twinx and twiny.r   r   z$Twinned Axes may share only one axisFrB   Taxes_locator)r   r   rR   rR   rQ  )r4   rW  rH   add_subplotadd_axesrZ  r=   rx  rI  r~  rb  r@  r6   )r    r)   r*   sstwinr$   r$   r%   _make_twin_axes  s,   "


z_AxesBase._make_twin_axesc                 C   sn   | j | d}|j  |jd |jd ||   | j  |j	d |j
	d | jj|j_|S )a  
        Create a twin Axes sharing the xaxis.

        Create a new Axes with an invisible x-axis and an independent
        y-axis positioned opposite to the original one (i.e. at right). The
        x-axis autoscale setting will be inherited from the original
        Axes.  To ensure that the tick marks of both y-axes align, see
        `~matplotlib.ticker.LinearLocator`.

        Returns
        -------
        Axes
            The newly created Axes instance

        Notes
        -----
        For those who are 'picking' artists while using twinx, pick
        events are only called for the artists in the top-most Axes.
        )r   r   F)rK  r   
tick_rightset_label_positionset_offset_positionr+  r  	tick_leftr   r  r  r   r    ax2r$   r$   r%   r    s   

z_AxesBase.twinxc                 C   sb   | j | d}|j  |jd ||   | j  |jd |j	d | jj
|j_
|S )a  
        Create a twin Axes sharing the yaxis.

        Create a new Axes with an invisible y-axis and an independent
        x-axis positioned opposite to the original one (i.e. at top). The
        y-axis autoscale setting will be inherited from the original Axes.
        To ensure that the tick marks of both x-axes align, see
        `~matplotlib.ticker.LinearLocator`.

        Returns
        -------
        Axes
            The newly created Axes instance

        Notes
        -----
        For those who are 'picking' artists while using twiny, pick
        events are only called for the artists in the top-most Axes.
        )r   r   F)rK  r   tick_toprM  r,  r  tick_bottomr   r  r  r   rP  r$   r$   r%   r    s   

z_AxesBase.twinyc                 C      t | jd S )z6Return an immutable view on the shared x-axes Grouper.r   r   GrouperViewr>  r   r$   r$   r%   get_shared_x_axes6     z_AxesBase.get_shared_x_axesc                 C   rT  )z6Return an immutable view on the shared y-axes Grouper.r   rU  r   r$   r$   r%   get_shared_y_axes:  rX  z_AxesBase.get_shared_y_axesc                 C   s    | j d|d | jd|d dS )a  
        Only show "outer" labels and tick labels.

        x-labels are only kept for subplots on the last row (or first row, if
        labels are on the top side); y-labels only for subplots on the first
        column (or last column, if labels are on the right side).

        Parameters
        ----------
        remove_inner_ticks : bool, default: False
            If True, remove the inner ticks as well (not only tick labels).

            .. versionadded:: 3.8
        F)skip_non_rectangular_axesremove_inner_ticksN)_label_outer_xaxis_label_outer_yaxis)r    r[  r$   r$   r%   label_outer>  s   
z_AxesBase.label_outer)r[  c                C     |rt | jtjjsd S |  }|sd S | j }| sK|dkr&| 	d |r,ddini }| jj
d
ddd| | jj d dkrK| jjd | s|dkrX| 	d |r^ddini }| jj
d
ddd| | jj d d	kr| jjd d S d S d S )Nr   r   Fr  )r   r   rR   r   )r   r   r   r$   )r   r  r^   r9  r  rW  r   r[  is_first_rowr  r  r]  rZ  r  is_last_row)r    rZ  r[  rI  label_positiontop_kw	bottom_kwr$   r$   r%   r\  R  @   



z_AxesBase._label_outer_xaxisc                C   r_  )Nr   r   Fr  )r   r   r   r   )r   r   rR   r$   )r   r  r^   r9  r  rW  r   r[  is_first_colr  r  r]  rZ  r  is_last_col)r    rZ  r[  rI  rb  left_kwright_kwr$   r$   r%   r]  m  re  z_AxesBase._label_outer_yaxisc                 C   r  )a  
        Set how pan/zoom events are forwarded to Axes below this one.

        Parameters
        ----------
        forward : bool or "auto"
            Possible values:

            - True: Forward events to other axes with lower or equal zorder.
            - False: Events are only executed on this axes.
            - "auto": Default behaviour (*True* for axes with an invisible
              patch and *False* otherwise)

        See Also
        --------
        matplotlib.axes.Axes.set_navigate

        Nr  )r    forwardr$   r$   r%   set_forward_navigation_events  s   
z'_AxesBase.set_forward_navigation_eventsc                 C   rV  )z=Get how pan/zoom events are forwarded to Axes below this one.rj  r   r$   r$   r%   get_forward_navigation_events  rX  z'_AxesBase.get_forward_navigation_eventsr(   )rq  N)r  F)r  )Nr  r  )NNF)T)TTr*  )Tr  N)NTT)Nr   r  )r  N)r  NFF)r0   r/   r1   r;   r   r>  r   r   r@  r8  rD   rF   __annotations__r   r_  ra  propertyr   r   r&   r:  rA  rG  rU  rW  r  r[  r]  r!  r  ro  rp  rv  rg  r  r  r  r  r  r  r  rZ  r  rY  r  r  r  r  r  r  r   r   r  r&  r6  r   r$  r+  r4  r6  r8  r9  r:  r;  r<  r  r  rq   r@  rN  rO  rI  rW  r  rX  rJ  rT  r  r   r  r  r  r  r  r   get_xgridlinesget_xticklinesget_ygridlinesget_yticklinesr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r0  r  r  r   r  r  r  r+  r,  r  r  r  setterr  r  r"  r$  r%  r'  r(  r0  rm  r_  r  allow_rasterizationrs  ru  ry  rz  r{  r}  r$  r	   interpdr  r  r  r1  r  r  r  r  r  r  r[  ro  r  r  r  rP  r+  
get_xticksr  get_xmajorticklabelsget_xminorticklabelsget_xticklabelsset_xticklabelsr  r  r  r  r\  rm  r  r  rQ  r,  
get_yticksr  get_ymajorticklabelsget_yminorticklabelsget_yticklabelsset_yticklabels
xaxis_date
yaxis_dater  r  r  r  r  r  r  r  r)  r  r*  r  r  r  r  r   r!  r0  r1  r2  r  r3  r;  r\  rK  r  r  rW  rY  r^  r\  r]  rl  rm  __classcell__r$   r$   r4  r%   r   %  s  
 	



 )
	
$
 		E






LH1%. % 



 0(=





R- G
F'*N)R3"N

3"N





P-
> Wr   c                 C   s   G dd d}|| | |S )a  
    A helper function for rasterizing the list of artists.

    The bookkeeping to track if we are or are not in rasterizing mode
    with the mixed-mode backends is relatively complicated and is now
    handled in the matplotlib.artist.allow_rasterization decorator.

    This helper defines the absolute minimum methods and attributes on a
    shim class to be compatible with that decorator and then uses it to
    rasterize the list of artists.

    This is maybe too-clever, but allows us to reuse the same code that is
    used on normal artists to participate in the "are we rasterizing"
    accounting.

    Please do not use this outside of the "rasterize below a given zorder"
    functionality of Axes.

    Parameters
    ----------
    figure : matplotlib.figure.Figure
        The figure all of the artists belong to (not checked).  We need this
        because we can at the figure level suppress composition and insert each
        rasterized artist as its own image.

    artists : List[matplotlib.artist.Artist]
        The list of Artists to be rasterized.  These are assumed to all
        be in the same Figure.

    renderer : matplotlib.backendbases.RendererBase
        The currently active renderer

    Returns
    -------
    None

    c                   @   s<   e Zd Zdd Zdd Zdd Zddd	Zejd
d Z	dS )z(_draw_rasterized.<locals>._MinimalArtistc                 S   r  )NTr$   r   r$   r$   r%   get_rasterized     z7_draw_rasterized.<locals>._MinimalArtist.get_rasterizedc                 S   s   d S r(   r$   r   r$   r$   r%   get_agg_filter  r  z7_draw_rasterized.<locals>._MinimalArtist.get_agg_filterc                 S   s   || _ || _d S r(   )figurer+  )r    r  r+  r$   r$   r%   r&     s   
z1_draw_rasterized.<locals>._MinimalArtist.__init__Fc                 S   s   |r	| j jddS | j S )NTrB   )r  rH   )r    rC   r$   r$   r%   rH     s   z3_draw_rasterized.<locals>._MinimalArtist.get_figurec                 S   s   | j D ]}|| qd S r(   )r+  rs  )r    rK   rz   r$   r$   r%   rs    s   
z-_draw_rasterized.<locals>._MinimalArtist.drawNrn  )
r0   r/   r1   r  r  r&   rH   r  rv  rs  r$   r$   r$   r%   _MinimalArtist  s    
r  )rs  )r  r+  rK   r  r$   r$   r%   rk    s   &rk  )Pcollections.abcr   r   
contextlibr   r  r   loggingnumbersr   operatorr   r\   r  numpyr   
matplotlibr^   r   r   r	   r
   matplotlib.artistr  r  matplotlib.axisr   r   matplotlib.cbookr   r   r   matplotlib.collectionsr4  r,  matplotlib.colorscolorsrU   matplotlib.font_managerr  matplotlib.gridspecr   matplotlib.imager  r.  matplotlib.linesr8  rX   matplotlib.patchesr9  r   matplotlib.rcsetupr   r   matplotlib.spinesr   r  matplotlib.tabletabler1  matplotlib.textr  r  matplotlib.tickertickerr  matplotlib.transforms
transformsrD   	getLoggerr0   rk  r   r=   rh   ri   define_aliasesArtistr   rk  r$   r$   r$   r%   <module>   s    
=S  [                                 