o
    ·¶ßdÓJ  ã                   @  s´   d Z ddlmZ ddlmZmZ ddlZddlm	Z	 ddl
m  mZ ddlmZ ddlZddlmZ ddlmZ erAddlmZ ejG d	d
„ d
ƒƒZddd„Zdd„ Zdd„ ZdS )zF
Module consolidating common testing functions for checking plotting.
é    )Úannotations)ÚTYPE_CHECKINGÚSequenceN)Úcache_readonly)Úis_list_like)ÚSeries©ÚAxesc                   @  sô   e Zd ZdZdd„ Zdd„ Zedd„ ƒZedd	„ ƒZd;dd„Z	d;dd„Z
dd„ Zd<dd„Z	d<d=dd„Zdd„ Z	
d>dd„Zd d!„ Z	
d?d"d#„Zd@d%d&„Zd>d'd(„Zd)d*„ Zd+d,„ ZdAd.d/„Z	d;d0d1„Zi fd2d3„ZdBd5d6„Zd7d8„ Zd9d:„ Zd
S )CÚTestPlotBasezE
    This is a common base class used for various plotting tests
    c                 C  s   dd l }| ¡  d S ©Nr   )Ú
matplotlibZ
rcdefaults)ÚselfÚmpl© r   úP/app/.heroku/python/lib/python3.10/site-packages/pandas/tests/plotting/common.pyÚsetup_method!   s   zTestPlotBase.setup_methodc                 C  s   t  ¡  d S ©N)ÚtmÚclose©r   r   r   r   Úteardown_method&   s   zTestPlotBase.teardown_methodc                 C  s   dd l m} |S r   )Úmatplotlib.pyplotÚpyplot)r   Úpltr   r   r   r   )   s   zTestPlotBase.pltc                 C  s   ddl m} |jS )Nr   )Úcolors)r   r   ZcolorConverter)r   r   r   r   r   Úcolorconverter/   s   zTestPlotBase.colorconverterNTc                 C  sf   |r
|du r
t dƒ‚|  |¡}|D ]}|r(| ¡ dusJ ‚|  | ¡  ¡ |¡ q| ¡ du s0J ‚qdS )aQ  
        Check each axes has expected legend labels

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        labels : list-like
            expected legend labels
        visible : bool
            expected legend visibility. labels are checked only when visible is
            True
        Nz-labels must be specified when visible is True)Ú
ValueErrorÚ_flatten_visibleÚ
get_legendÚ_check_text_labelsZ	get_texts)r   ÚaxesÚlabelsÚvisibleÚaxr   r   r   Ú_check_legend_labels5   s   
ûz!TestPlotBase._check_legend_labelsc                 C  sV   |r
|du r
t dƒ‚|r!| ¡ \}}dd„ |D ƒ}||ksJ ‚dS | ¡ du s)J ‚dS )aB  
        Check ax has expected legend markers

        Parameters
        ----------
        ax : matplotlib Axes object
        expected_markers : list-like
            expected legend markers
        visible : bool
            expected legend visibility. labels are checked only when visible is
            True
        Nz.Markers must be specified when visible is Truec                 S  ó   g | ]}|  ¡ ‘qS r   )Z
get_marker)Ú.0Úhandler   r   r   Ú
<listcomp>]   ó    z5TestPlotBase._check_legend_marker.<locals>.<listcomp>)r   Zget_legend_handles_labelsr   )r   r#   Zexpected_markersr"   ZhandlesÚ_Úmarkersr   r   r   Ú_check_legend_markerL   s   z!TestPlotBase._check_legend_markerc           	      C  s`   |  ¡ }|  ¡ }t|ƒt|ƒksJ ‚t||ƒD ]\}}| ¡ }| ¡ }t ||¡ qt ¡  dS )z¤
        Check each axes has identical lines

        Parameters
        ----------
        xp : matplotlib Axes object
        rs : matplotlib Axes object
        N)Ú	get_linesÚlenÚzipZ
get_xydatar   Úassert_almost_equalr   )	r   ZxpÚrsZxp_linesZrs_linesZxplÚrslZxpdataZrsdatar   r   r   Ú_check_datab   s   	zTestPlotBase._check_datac                 C  sB   ddl m} t||ƒst|ƒs|g}|D ]
}| ¡ |ksJ ‚qdS )a   
        Check each artist is visible or not

        Parameters
        ----------
        collections : matplotlib Artist or its list-like
            target Artist or its list or collection
        visible : bool
            expected visibility
        r   )Ú
CollectionN)Úmatplotlib.collectionsr4   Ú
isinstancer   Úget_visible)r   Úcollectionsr"   r4   Úpatchr   r   r   Ú_check_visiblev   s   ÿzTestPlotBase._check_visibler    úAxes | Sequence[Axes]ÚfilledÚboolÚreturnÚNonec                 C  s2   |   |¡}|D ]}|jD ]	}|j|ksJ ‚qqdS )zÕ
        Check for each artist whether it is filled or not

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        filled : bool
            expected filling
        N)r   ZpatchesÚfill)r   r    r<   r#   r9   r   r   r   Ú_check_patches_all_filled‰   s   

ÿÿz&TestPlotBase._check_patches_all_filledc                   s*   |  ¡ }tt||ƒƒ‰ ‡ fdd„|jD ƒS )Nc                   s   g | ]}ˆ | ‘qS r   r   ©r&   Úv©Zmappedr   r   r(       r)   z3TestPlotBase._get_colors_mapped.<locals>.<listcomp>)ÚuniqueÚdictr/   Úvalues)r   Zseriesr   rE   r   rD   r   Ú_get_colors_mapped›   s   zTestPlotBase._get_colors_mappedc                 C  s|  ddl m}m}m} ddlm} | j}	|durk|dur)|  ||¡}|dt|ƒ… }t|ƒt|ƒks3J ‚t	||ƒD ]2\}
}t
|
|ƒrK|
 ¡ }|	 |¡}nt
|
||fƒr[t|
 ¡ d ƒ}n|
 ¡ }|	 |¡}||ksjJ ‚q8|durº|dur|  ||¡}|dt|ƒ… }t|ƒt|ƒks‹J ‚t	||ƒD ]+\}
}t
|
|ƒr |
 ¡ d }n|
 ¡ }t
|tjƒr®t|ƒ}|	 |¡}||ks¹J ‚qdS dS )a3  
        Check each artist has expected line colors and face colors

        Parameters
        ----------
        collections : list-like
            list or collection of target artist
        linecolors : list-like which has the same length as collections
            list of expected line colors
        facecolors : list-like which has the same length as collections
            list of expected face colors
        mapping : Series
            Series used for color grouping key
            used for andrew_curves, parallel_coordinates, radviz test
        r   )r4   ÚLineCollectionÚPolyCollection)ÚLine2DN)r5   r4   rI   rJ   Zmatplotlib.linesrK   r   rH   r.   r/   r6   Ú	get_colorZto_rgbaÚtupleZget_edgecolorZget_facecolorÚnpZndarray)r   r8   Z
linecolorsZ
facecolorsÚmappingr4   rI   rJ   rK   Úconvr9   ÚcolorÚresultÚexpectedr   r   r   Ú_check_colors¢   s@   



ïzTestPlotBase._check_colorsc                 C  sb   t |ƒs| ¡ |ksJ ‚dS dd„ |D ƒ}t|ƒt|ƒksJ ‚t||ƒD ]
\}}||ks.J ‚q$dS )a.  
        Check each text has expected labels

        Parameters
        ----------
        texts : matplotlib Text object, or its list-like
            target text, or its list
        expected : str or list-like which has the same length as texts
            expected text label, or its list
        c                 S  r%   r   )Úget_text)r&   Útr   r   r   r(   ð   r)   z3TestPlotBase._check_text_labels.<locals>.<listcomp>N)r   rU   r.   r/   )r   ZtextsrS   r!   ÚlabelÚer   r   r   r   â   s   ÿzTestPlotBase._check_text_labelsc           
      C  s  ddl m} |  |¡}|D ]z}|dus|durKt|j ¡ |ƒr$| ¡ }n
| ¡ |jdd }|D ]}	|dur>t |	 	¡ |¡ |durJt |	 
¡ |¡ q0|dusS|dur‡t|j ¡ |ƒr`| ¡ }n
| ¡ |jdd }|D ]}	|durzt |	 	¡ |¡ |dur†t |	 
¡ |¡ qlqdS )a—  
        Check each axes has expected tick properties

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        xlabelsize : number
            expected xticks font size
        xrot : number
            expected xticks rotation
        ylabelsize : number
            expected yticks font size
        yrot : number
            expected yticks rotation
        r   )ÚNullFormatterNT)Úminor)Zmatplotlib.tickerrY   r   r6   ÚxaxisZget_minor_formatterZget_xticklabelsr   r0   Zget_fontsizeZget_rotationÚyaxisZget_yticklabels)
r   r    Z
xlabelsizeZxrotZ
ylabelsizeZyrotrY   r#   r!   rW   r   r   r   Ú_check_ticks_propsõ   s0   

€
€çzTestPlotBase._check_ticks_propsÚlinearc                 C  s<   |   |¡}|D ]}|j ¡ |ksJ ‚|j ¡ |ksJ ‚qdS )a  
        Check each axes has expected scales

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        xaxis : {'linear', 'log'}
            expected xaxis scale
        yaxis : {'linear', 'log'}
            expected yaxis scale
        N)r   r[   Z	get_scaler\   )r   r    r[   r\   r#   r   r   r   Ú_check_ax_scales%  s
   
þzTestPlotBase._check_ax_scalesc           	      C  s    ddl m} |du rd}|  |¡}|dur,t|ƒ|ksJ ‚|D ]}t| ¡ ƒdks+J ‚q|dur=|  ||ƒ¡}||ks=J ‚t |d j 	¡ t
j|t
jd¡ dS )aÎ  
        Check expected number of axes is drawn in expected layout

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        axes_num : number
            expected number of axes. Unnecessary axes should be set to
            invisible.
        layout : tuple
            expected layout, (expected number of rows , columns)
        figsize : tuple
            expected figsize. default is matplotlib default
        r   ©Úflatten_axesN)gš™™™™™@g333333@)Zdtype)Ú!pandas.plotting._matplotlib.toolsra   r   r.   Zget_childrenÚ_get_axes_layoutr   Zassert_numpy_array_equalÚfigureZget_size_inchesrN   ÚarrayZfloat64)	r   r    Zaxes_numZlayoutZfigsizera   Zvisible_axesr#   rR   r   r   r   Ú_check_axes_shape6  s   
þzTestPlotBase._check_axes_shapec                 C  sV   t ƒ }t ƒ }|D ]}| ¡  ¡ }| |d d ¡ | |d d ¡ qt|ƒt|ƒfS )Nr   é   )ÚsetZget_positionZ
get_pointsÚaddr.   )r   r    Zx_setZy_setr#   Zpointsr   r   r   rc   Z  s   zTestPlotBase._get_axes_layoutc                 C  s&   ddl m} ||ƒ}dd„ |D ƒ}|S )z—
        Flatten axes, and filter only visible

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like

        r   r`   c                 S  s   g | ]}|  ¡ r|‘qS r   )r7   )r&   r#   r   r   r   r(   p  s    z1TestPlotBase._flatten_visible.<locals>.<listcomp>)rb   ra   )r   r    ra   r   r   r   r   d  s   	zTestPlotBase._flatten_visibler   c                 C  sx   |   |¡}|D ]2}|j}d}d}|D ]}t|ddƒ}	t|ddƒ}
|	r&|d7 }|
r,|d7 }q||ks3J ‚||ks9J ‚qdS )a  
        Check axes has expected number of errorbars

        Parameters
        ----------
        axes : matplotlib Axes object, or its list-like
        xerr : number
            expected number of x errorbar
        yerr : number
            expected number of y errorbar
        r   Úhas_xerrFÚhas_yerrrg   N)r   Ú
containersÚgetattr)r   r    ZxerrZyerrr#   rl   Z
xerr_countZ
yerr_countÚcrj   rk   r   r   r   Ú_check_has_errorbarss  s    
€ôz!TestPlotBase._check_has_errorbarsc                 C  sv  ddl m} t|tdœ}|du r7|du rd}t||| ƒsJ ‚|dkr3t|j|ƒs+J ‚t|jtƒs5J ‚dS dS |du rL|  |¡D ]	}t||ƒsIJ ‚q@dS t|tƒsSJ ‚t	| 
¡ ƒt	|ƒks_J ‚| ¡ D ]U\}}	t|	|| ƒspJ ‚|dkr|r~|	 ¡ |ks~J ‚qc|dkrŸ|rŽ|	j ¡ |ksŽJ ‚t|	j|ƒs–J ‚t|	jtƒsžJ ‚qc|dkr·|	d d }
|
j}|r¶| ¡ |ks¶J ‚qct‚dS )	at  
        Check box returned type is correct

        Parameters
        ----------
        returned : object to be tested, returned from boxplot
        return_type : str
            return_type passed to boxplot
        expected_keys : list-like, optional
            group labels in subplot case. If not passed,
            the function checks assuming boxplot uses single ax
        check_ax_title : bool
            Whether to check the ax.title is the same as expected_key
            Intended to be checked by calling from ``boxplot``.
            Normal ``plot`` doesn't attach ``ax.title``, it must be disabled.
        r   r   )rF   r    ÚbothNrF   rp   r    Zmedians)Úmatplotlib.axesr	   rF   rM   r6   r#   Úlinesr   r   ÚsortedÚkeysÚitemsZ	get_titler    ÚAssertionError)r   ÚreturnedÚreturn_typeZexpected_keysZcheck_ax_titler	   ÚtypesÚrÚkeyÚvalueÚliner    r   r   r   Ú_check_box_return_typeŽ  sH   þ€€ïz#TestPlotBase._check_box_return_typec                   sŠ  dd l }‡ fdd„}d}|D ]´}ˆ j ddt|ƒ |¡ |d7 }|jddd |jdd	|i|¤Ž |ƒ r6J ‚ˆ j ¡  ˆ j ddt|ƒ |¡ |d7 }|jdd
d |jd|ddœ|¤Ž |ƒ rbJ ‚ˆ j ¡  |dvrÂˆ j ddt|ƒ |¡ |d7 }|jdd
d |jdd	|i|¤Ž |ƒ s‘J ‚ˆ j ¡  ˆ j ddt|ƒ |¡ |d7 }|jddd |jd|d
dœ|¤Ž |ƒ s½J ‚ˆ j ¡  qd S )Nr   c                    sN   ˆ j  ¡ j ¡ } ˆ j  ¡ j ¡ }tdd„ | D ƒƒ}tdd„ |D ƒƒ}|o%| S )Nc                 s  ó    | ]	}|j  ¡  V  qd S r   ©Zgridliner7   ©r&   Úgr   r   r   Ú	<genexpr>Ò  ó   € zHTestPlotBase._check_grid_settings.<locals>.is_grid_on.<locals>.<genexpr>c                 s  r   r   r€   r   r   r   r   rƒ   Ó  r„   )r   Zgcar[   Zget_major_ticksr\   Úall)ZxticksZyticksZxoffZyoffr   r   r   Ú
is_grid_onÏ  s
   
z5TestPlotBase._check_grid_settings.<locals>.is_grid_onrg   é   r    F)ÚgridÚkindT)r‰   rˆ   )ÚpieZhexbinZscatterr   )r   r   Zsubplotr.   ÚrcZplotÚclf)r   ÚobjÚkindsÚkwsr   r†   Zspndxr‰   r   r   r   Ú_check_grid_settingsÊ  s>   







€äz!TestPlotBase._check_grid_settingsrQ   c                   s   ‡ fdd„|d D ƒS )zT
        Auxiliary function for correctly unpacking cycler after MPL >= 1.5
        c                   s   g | ]}|ˆ  ‘qS r   r   rB   ©Úfieldr   r   r(   ú  r)   z/TestPlotBase._unpack_cycler.<locals>.<listcomp>zaxes.prop_cycler   )r   ZrcParamsr’   r   r‘   r   Ú_unpack_cyclerö  s   zTestPlotBase._unpack_cyclerc                 C  ó
   |j d S )NÚx©Z_shared_axes©r   r#   r   r   r   Ú
get_x_axisü  ó   
zTestPlotBase.get_x_axisc                 C  r”   )NÚyr–   r—   r   r   r   Ú
get_y_axisÿ  r™   zTestPlotBase.get_y_axis)NT)T)r    r;   r<   r=   r>   r?   )NNN)NNNN)r^   r^   )r   r   )rQ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r$   r,   r3   r:   rA   rH   rT   r   r]   r_   rf   rc   r   ro   r~   r   r“   r˜   r›   r   r   r   r   r
      s>    




ÿ
ÿ@
ÿ
0
$


ÿ<
,r
   Fc              	   K  s¼   ddl m} |rt}nt}d}zH| d| ¡ ¡}| ¡  || |fi |¤ŽD ]}t |¡ q%tj	dd}| 
|¡ W d  ƒ n1 sCw   Y  W t |¡ |S W t |¡ |S t |¡ w )a×  
    Create plot and ensure that plot return object is valid.

    Parameters
    ----------
    f : func
        Plotting function.
    default_axes : bool, optional
        If False (default):
            - If `ax` not in `kwargs`, then create subplot(211) and plot there
            - Create new subplot(212) and plot there as well
            - Mind special corner case for bootstrap_plot (see `_gen_two_subplots`)
        If True:
            - Simply run plotting function with kwargs provided
            - All required axes instances will be created automatically
            - It is recommended to use it when the plotting function
            creates multiple axes itself. It helps avoid warnings like
            'UserWarning: To output multiple subplots,
            the figure containing the passed axes is being cleared'
    **kwargs
        Keyword arguments passed to the plotting function.

    Returns
    -------
    Plot object returned by the last plotting.
    r   Nrd   T)Zreturn_filelike)r   r   Ú_gen_default_plotÚ_gen_two_subplotsÚgetZgcfrŒ   r   Z"assert_is_valid_plot_return_objectZensure_cleanZsavefigr   )ÚfZdefault_axesÚkwargsr   Z	gen_plotsÚretÚfigÚpathr   r   r   Ú_check_plot_works  s&   ÿ
ú
þr¨   c                 k  s    | di |¤ŽV  dS )z'
    Create plot in a default way.
    Nr   r   ©r£   r¦   r¤   r   r   r   r    6  s   €r    c                 k  s`    d|vr
|  d¡ | di |¤ŽV  | tjju rd|vsJ ‚n|  d¡|d< | di |¤ŽV  dS )z9
    Create plot on two subplots forcefully created.
    r#   éÓ   éÔ   Nr   )Zadd_subplotÚpdZplottingZbootstrap_plotr©   r   r   r   r¡   =  s   €
r¡   )F)rŸ   Ú
__future__r   Útypingr   r   ÚnumpyrN   Zpandas.util._decoratorsr   Zpandas.util._test_decoratorsÚutilZ_test_decoratorsÚtdZpandas.core.dtypes.apir   Zpandasr¬   r   Zpandas._testingZ_testingr   rq   r	   Zskip_if_no_mplr
   r¨   r    r¡   r   r   r   r   Ú<module>   s(       
j3