o
    :a0T                     @   s  d Z ddlZddlZddlZddlmZ ddlZddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZ ddlmZmZ G dd dZG d	d
 d
eZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd  d eZ$G d!d" d"eZ%eee"e%eed#Z&d$d% Z'd&d' Z(e(j re(j d(d))e*e+e' i e(_ d*d+ Z,d,d- Z-e	j.j/d.d))d/d0 e' D  e- 0 d1 dS )2a  
Scales define the distribution of data values on an axis, e.g. a log scaling.
They are defined as subclasses of `ScaleBase`.

See also `.axes.Axes.set_xscale` and the scales examples in the documentation.

See :doc:`/gallery/scales/custom_scale` for a full example of defining a custom
scale.

Matplotlib also supports non-separable transformations that operate on both
`~.axis.Axis` at the same time.  They are known as projections, and defined in
`matplotlib.projections`.
    N)ma)_api	docstring)
NullFormatterScalarFormatterLogFormatterSciNotationLogitFormatterNullLocator
LogLocatorAutoLocatorAutoMinorLocatorSymmetricalLogLocatorLogitLocator)	TransformIdentityTransformc                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )	ScaleBasea  
    The base class for all scales.

    Scales are separable transformations, working on a single dimension.

    Subclasses should override

    :attr:`name`
        The scale's name.
    :meth:`get_transform`
        A method returning a `.Transform`, which converts data coordinates to
        scaled coordinates.  This transform should be invertible, so that e.g.
        mouse positions can be converted back to data coordinates.
    :meth:`set_default_locators_and_formatters`
        A method that sets default locators and formatters for an `~.axis.Axis`
        that uses this scale.
    :meth:`limit_range_for_scale`
        An optional method that "fixes" the axis range to acceptable values,
        e.g. restricting log-scaled axes to positive values.
    c                 C      dS )a  
        Construct a new scale.

        Notes
        -----
        The following note is for scale implementors.

        For back-compatibility reasons, scales take an `~matplotlib.axis.Axis`
        object as first argument.  However, this argument should not
        be used: a single scale object should be usable by multiple
        `~matplotlib.axis.Axis`\es at the same time.
        N selfaxisr   r   2/usr/lib/python3/dist-packages/matplotlib/scale.py__init__4       zScaleBase.__init__c                 C      t  )zL
        Return the `.Transform` object associated with this scale.
        NotImplementedErrorr   r   r   r   get_transformB   s   zScaleBase.get_transformc                 C   r   )zi
        Set the locators and formatters of *axis* to instances suitable for
        this scale.
        r   r   r   r   r   #set_default_locators_and_formattersH      z-ScaleBase.set_default_locators_and_formattersc                 C   s   ||fS )z
        Return the range *vmin*, *vmax*, restricted to the
        domain supported by this scale (if any).

        *minpos* should be the minimum positive value in the data.
        This is used by log scales to determine a minimum value.
        r   r   ZvminZvmaxZminposr   r   r   limit_range_for_scaleO   s   zScaleBase.limit_range_for_scaleN)__name__
__module____qualname____doc__r   r   r   r"   r   r   r   r   r      s    r   c                   @   ,   e Zd ZdZdZdd Zdd Zdd Zd	S )
LinearScalez#
    The default linear scale.
    linearc                 C   r   )z	
        Nr   r   r   r   r   r   a   r   zLinearScale.__init__c                 C   l   | t  |t  |t  |jdkrtjd s&|jdkr.tjd r.|	t
  d S |	t  d S Nxzxtick.minor.visibleyzytick.minor.visibleset_major_locatorr   set_major_formatterr   set_minor_formatterr   Z	axis_namemplZrcParamsset_minor_locatorr   r	   r   r   r   r   r   h      z/LinearScale.set_default_locators_and_formattersc                 C   s   t  S )z
        Return the transform for linear scaling, which is just the
        `~matplotlib.transforms.IdentityTransform`.
        )r   r   r   r   r   r   t   r    zLinearScale.get_transformN)r#   r$   r%   r&   namer   r   r   r   r   r   r   r(   Z   s    r(   c                       s8   e Zd ZdZd ZZ fddZdd Zdd Z  Z	S )	FuncTransformzi
    A simple transform that takes and arbitrary function for the
    forward and inverse transform.
       c                    s2   t    t|rt|r|| _|| _dS td)a  
        Parameters
        ----------
        forward : callable
            The forward function for the transform.  This function must have
            an inverse and, for best behavior, be monotonic.
            It must have the signature::

               def forward(values: array-like) -> array-like

        inverse : callable
            The inverse of the forward function.  Signature as ``forward``.
        z,arguments to FuncTransform must be functionsN)superr   callable_forward_inverse
ValueError)r   forwardinverse	__class__r   r   r      s
   

zFuncTransform.__init__c                 C   s
   |  |S N)r:   )r   valuesr   r   r   transform_non_affine      
z"FuncTransform.transform_non_affinec                 C   s   t | j| jS rA   )r6   r;   r:   r   r   r   r   inverted      zFuncTransform.inverted)
r#   r$   r%   r&   
input_dimsoutput_dimsr   rC   rE   __classcell__r   r   r?   r   r6   |   s    r6   c                   @   r'   )
	FuncScalezN
    Provide an arbitrary scale with user-supplied function for the axis.
    functionc                 C   s   |\}}t ||}|| _dS )a  
        Parameters
        ----------
        axis : `~matplotlib.axis.Axis`
            The axis for the scale.
        functions : (callable, callable)
            two-tuple of the forward and inverse functions for the scale.
            The forward function must be monotonic.

            Both functions must have the signature::

               def forward(values: array-like) -> array-like
        N)r6   
_transform)r   r   	functionsr=   r>   	transformr   r   r   r      s   

zFuncScale.__init__c                 C      | j S )z7Return the `.FuncTransform` associated with this scale.rL   r   r   r   r   r         zFuncScale.get_transformc                 C   r*   r+   r.   r   r   r   r   r      r4   z-FuncScale.set_default_locators_and_formattersN)r#   r$   r%   r&   r5   r   r   r   r   r   r   r   rJ      s    rJ   c                       >   e Zd Zd ZZd fdd	Zdd Zdd Zd	d
 Z  Z	S )LogTransformr7   clipc                    sB   t    |dks|dkrtd|| _tjddd|d| _d S )Nr   r7   z#The log base cannot be <= 0 or == 1TFrT   masknonpositive)r8   r   r<   baser   check_getitem_clip)r   rY   rX   r?   r   r   r      s   

zLogTransform.__init__c                 C   s"   d t| j| j| jrdS dS )Nz{}(base={}, nonpositive={!r})rT   rV   )formattyper#   rY   r[   r   r   r   r   __str__   s
   zLogTransform.__str__c                 C   s   t jddd> t jt jdt jdt ji| j}|r||}nt |}|t | j }| jr=d||dk< W d    |S W d    |S 1 sHw   Y  |S )NignoreZdivideZinvalid   
   r   )	nperrstateelogZlog2log10getrY   r[   )r   arg   outr   r   r   rC      s    




z!LogTransform.transform_non_affinec                 C   
   t | jS rA   )InvertedLogTransformrY   r   r   r   r   rE      rD   zLogTransform.inverted)rT   
r#   r$   r%   rG   rH   r   r^   rC   rE   rI   r   r   r?   r   rS      s    rS   c                       s<   e Zd Zd ZZ fddZdd Zdd Zdd	 Z  Z	S )
rm   r7   c                       t    || _d S rA   )r8   r   rY   )r   rY   r?   r   r   r         

zInvertedLogTransform.__init__c                 C      d t| j| jS )Nz{}(base={}))r\   r]   r#   rY   r   r   r   r   r^         zInvertedLogTransform.__str__c                 C   s   t | j|S rA   )r   powerrY   r   rj   r   r   r   rC      rF   z)InvertedLogTransform.transform_non_affinec                 C   rl   rA   )rS   rY   r   r   r   r   rE      rD   zInvertedLogTransform.invertedrn   r   r   r?   r   rm      s    rm   c                   @   sJ   e Zd ZdZdZddddddZed	d
 Zdd Zdd Z	dd Z
dS )LogScalezT
    A standard logarithmic scale.  Care is taken to only plot positive values.
    rg   rb   NrT   )rY   subsrX   c                C   s   t ||| _|| _dS )a  
        Parameters
        ----------
        axis : `~matplotlib.axis.Axis`
            The axis for the scale.
        base : float, default: 10
            The base of the logarithm.
        nonpositive : {'clip', 'mask'}, default: 'clip'
            Determines the behavior for non-positive values. They can either
            be masked as invalid, or clipped to a very small positive number.
        subs : sequence of int, default: None
            Where to place the subticks between each major tick.  For example,
            in a log10 scale, ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place 8
            logarithmically spaced minor ticks between each major tick.
        N)rS   rL   rv   )r   r   rY   rv   rX   r   r   r   r   
  s   
zLogScale.__init__c                 C      | j jS rA   rL   rY   r   r   r   r   <lambda>      zLogScale.<lambda>c                 C   sR   | t| j |t| j |t| j| j |t| j| jd ud d S )N)ZlabelOnlyBase)r/   r
   rY   r0   r   r3   rv   r1   r   r   r   r   r     s   z,LogScale.set_default_locators_and_formattersc                 C   rO   )z6Return the `.LogTransform` associated with this scale.rP   r   r   r   r   r   (  rQ   zLogScale.get_transformc                 C   s0   t |sd}|dkr|n||dkr|fS |fS )z$Limit the domain to positive values.gYnr   rd   Zisfiniter!   r   r   r   r"   ,  s   

zLogScale.limit_range_for_scale)r#   r$   r%   r&   r5   r   propertyrY   r   r   r"   r   r   r   r   ru     s    	ru   c                   @   s2   e Zd ZdZdZdddZedd Zdd	 Zd
S )FuncScaleLogzu
    Provide an arbitrary scale with user-supplied function for the axis and
    then put on a logarithmic axes.
    functionlogrb   c                 C   s&   |\}}d| _ t||t| | _dS )a  
        Parameters
        ----------
        axis : `matplotlib.axis.Axis`
            The axis for the scale.
        functions : (callable, callable)
            two-tuple of the forward and inverse functions for the scale.
            The forward function must be monotonic.

            Both functions must have the signature::

                def forward(values: array-like) -> array-like

        base : float, default: 10
            Logarithmic base of the scale.
        N)rv   r6   rS   rL   )r   r   rM   rY   r=   r>   r   r   r   r   =  s   zFuncScaleLog.__init__c                 C   s
   | j jjS rA   )rL   Z_brY   r   r   r   r   rY   R  s   
zFuncScaleLog.basec                 C   rO   )z3Return the `.Transform` associated with this scale.rP   r   r   r   r   r   V  rQ   zFuncScaleLog.get_transformN)rb   )	r#   r$   r%   r&   r5   r   r|   rY   r   r   r   r   r   r}   5  s    

r}   c                       4   e Zd Zd ZZ fddZdd Zdd Z  ZS )SymmetricalLogTransformr7   c                    sp   t    |dkrtd|dkrtd|dkrtd|| _|| _|| _|d| jd   | _t|| _	d S )N      ?z'base' must be larger than 1g        z'linthresh' must be positivez'linscale' must be positive)
r8   r   r<   rY   	linthreshlinscale_linscale_adjrd   rg   	_log_base)r   rY   r   r   r?   r   r   r   ^  s   
z SymmetricalLogTransform.__init__c                 C   s   t |}t jddd# t || j | jt || j | j   }|| jk}W d    n1 s2w   Y  || | j ||< |S Nr_   r`   )rd   absre   signr   r   rg   r   r   rj   Zabs_ark   Zinsider   r   r   rC   l  s   
z,SymmetricalLogTransform.transform_non_affinec                 C      t | j| j| jS rA   )InvertedSymmetricalLogTransformrY   r   r   r   r   r   r   rE   v  s   
z SymmetricalLogTransform.inverted	r#   r$   r%   rG   rH   r   rC   rE   rI   r   r   r?   r   r   [  s
    
r   c                       r   )r   r7   c                    sL   t    t|||}|| _|| _||| _|| _|d| jd   | _d S )Nr   r   )	r8   r   r   rY   r   rN   invlinthreshr   r   )r   rY   r   r   symlogr?   r   r   r   ~  s   
z(InvertedSymmetricalLogTransform.__init__c                 C   s   t |}t jddd" t || j t | j|| j | j  }|| jk}W d    n1 s1w   Y  || | j ||< |S r   )	rd   r   re   r   r   rs   rY   r   r   r   r   r   r   rC     s   
z4InvertedSymmetricalLogTransform.transform_non_affinec                 C   r   rA   )r   rY   r   r   r   r   r   r   rE     s   z(InvertedSymmetricalLogTransform.invertedr   r   r   r?   r   r   {  s
    	
r   c                   @   s\   e Zd ZdZdZddddddd	Zed
d Zedd Zedd Z	dd Z
dd ZdS )SymmetricalLogScalea  
    The symmetrical logarithmic scale is logarithmic in both the
    positive and negative directions from the origin.

    Since the values close to zero tend toward infinity, there is a
    need to have a range around zero that is linear.  The parameter
    *linthresh* allows the user to specify the size of this range
    (-*linthresh*, *linthresh*).

    Parameters
    ----------
    base : float, default: 10
        The base of the logarithm.

    linthresh : float, default: 2
        Defines the range ``(-x, x)``, within which the plot is linear.
        This avoids having the plot go to infinity around zero.

    subs : sequence of int
        Where to place the subticks between each major tick.
        For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place
        8 logarithmically spaced minor ticks between each major tick.

    linscale : float, optional
        This allows the linear range ``(-linthresh, linthresh)`` to be
        stretched relative to the logarithmic range. Its value is the number of
        decades to use for each half of the linear range. For example, when
        *linscale* == 1.0 (the default), the space used for the positive and
        negative halves of the linear range will be equal to one decade in
        the logarithmic range.
    r   rb   ra   Nr7   )rY   r   rv   r   c                C   s   t |||| _|| _d S rA   )r   rL   rv   )r   r   rY   r   rv   r   r   r   r   r     s   
zSymmetricalLogScale.__init__c                 C   rw   rA   rx   r   r   r   r   ry     rz   zSymmetricalLogScale.<lambda>c                 C   rw   rA   )rL   r   r   r   r   r   ry     rz   c                 C   rw   rA   )rL   r   r   r   r   r   ry     rz   c                 C   sH   | t|   |t| j |t|  | j |t	  d S rA   )
r/   r   r   r0   r   rY   r3   rv   r1   r   r   r   r   r   r     s   z7SymmetricalLogScale.set_default_locators_and_formattersc                 C   rO   )zAReturn the `.SymmetricalLogTransform` associated with this scale.rP   r   r   r   r   r     rQ   z!SymmetricalLogScale.get_transform)r#   r$   r%   r&   r5   r   r|   rY   r   r   r   r   r   r   r   r   r     s    r   c                       rR   )LogitTransformr7   rV   c                    s6   t    tjddg|d || _ddd| | _d S )NrV   rT   rW   TFrU   )r8   r   r   Zcheck_in_list_nonpositiver[   r   rX   r?   r   r   r     s   
zLogitTransform.__init__c                 C   sb   t jddd t |d|  }W d   n1 sw   Y  | jr/d||dk< d|d|k< |S )z,logit transform (base 10), masked or clippedr_   r`   r7   Nrc   r   i  )rd   re   rh   r[   )r   rj   rk   r   r   r   rC     s   z#LogitTransform.transform_non_affinec                 C   rl   rA   )LogisticTransformr   r   r   r   r   rE     rD   zLogitTransform.invertedc                 C   rq   Nz{}({!r})r\   r]   r#   r   r   r   r   r   r^     rr   zLogitTransform.__str__rV   
r#   r$   r%   rG   rH   r   rC   rE   r^   rI   r   r   r?   r   r     s    	r   c                       rR   )r   r7   rV   c                    ro   rA   )r8   r   r   r   r?   r   r   r     rp   zLogisticTransform.__init__c                 C   s   ddd|    S )zlogistic transform (base 10)r   r7   rb   r   rt   r   r   r   rC     s   z&LogisticTransform.transform_non_affinec                 C   rl   rA   )r   r   r   r   r   r   rE     rD   zLogisticTransform.invertedc                 C   rq   r   r   r   r   r   r   r^     rr   zLogisticTransform.__str__r   r   r   r   r?   r   r     s    r   c                   @   s>   e Zd ZdZdZddddddZd	d
 Zdd Zdd ZdS )
LogitScalez
    Logit scale for data between zero and one, both excluded.

    This scale is similar to a log scale close to zero and to one, and almost
    linear around 0.5. It maps the interval ]0, 1[ onto ]-infty, +infty[.
    logitrV   z\frac{1}{2}Fone_halfuse_overlinec                C   s   t || _|| _|| _dS )a  
        Parameters
        ----------
        axis : `matplotlib.axis.Axis`
            Currently unused.
        nonpositive : {'mask', 'clip'}
            Determines the behavior for values beyond the open interval ]0, 1[.
            They can either be masked as invalid, or clipped to a number very
            close to 0 or 1.
        use_overline : bool, default: False
            Indicate the usage of survival notation (\overline{x}) in place of
            standard notation (1-x) for probability close to one.
        one_half : str, default: r"\frac{1}{2}"
            The string used for ticks formatter to represent 1/2.
        N)r   rL   _use_overline	_one_half)r   r   rX   r   r   r   r   r   r     s   

zLogitScale.__init__c                 C   rO   )z8Return the `.LogitTransform` associated with this scale.rP   r   r   r   r   r     rQ   zLogitScale.get_transformc                 C   sN   | t  |t| j| jd |tdd |td| j| jd d S )Nr   T)minor)r   r   r   )r/   r   r0   r   r   r   r3   r1   r   r   r   r   r     s   z.LogitScale.set_default_locators_and_formattersc                 C   s4   t |sd}|dkr|n||dkrd| fS |fS )zH
        Limit the domain to values between 0 and 1 (excluded).
        gHz>r   r7   r{   r!   r   r   r   r"   -  s   
z LogitScale.limit_range_for_scaleNr   )	r#   r$   r%   r&   r5   r   r   r   r"   r   r   r   r   r     s    r   )r)   rg   r   r   rK   r~   c                   C   s   t tS )z)Return the names of the available scales.)sorted_scale_mappingr   r   r   r   get_scale_namesA  s   r   c                 K   s@   | |   krtjddd |   } tjt| d}||fi |S )z
    Return a scale class by name.

    Parameters
    ----------
    scale : {%(names)s}
    axis : `matplotlib.axis.Axis`
    z3.5zjSupport for case-insensitive scales is deprecated since %(since)s and support will be removed %(removal)s.)message)scale)lowerr   Zwarn_deprecatedrZ   r   )r   r   kwargsZ	scale_clsr   r   r   scale_factoryF  s   	r   namesz, c                 C   s   | t | j< dS )z
    Register a new kind of scale.

    Parameters
    ----------
    scale_class : subclass of `ScaleBase`
        The scale to register.
    N)r   r5   )scale_classr   r   r   register_scale]  s   	r   c               	   C   sP   g } t  D ]\}}t|jpd}| d|dt|ddg qd| S )zF
    Helper function for generating docstrings related to scales.
     z    z        
)	r   itemsinspectZgetdocr   extendtextwrapindentjoin)Zdocsr5   r   r   r   r   r   _get_scale_docsi  s   

r   z{%s}c                 C   s   g | ]}t |qS r   )repr).0r,   r   r   r   
<listcomp>z  s    r   )Z
scale_typeZ
scale_docs)1r&   r   r   Znumpyrd   r   Z
matplotlibr2   r   r   Zmatplotlib.tickerr   r   r   r   r	   r
   r   r   r   r   Zmatplotlib.transformsr   r   r   r(   r6   rJ   rS   rm   ru   r}   r   r   r   r   r   r   r   r   r   r   mapr   r   r   Zinterpdupdaterstripr   r   r   r   <module>   sT    0<"$*)1& 7@

