U
    Åmœd7¨  ã                3   @   s|  d dl mZ d dlmZ d dlm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 d dlmZ d dlZd dl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$m%Z% d dl&m'Z' d dl"m(Z( d dl"m)Z) d dl*m+Z+m,Z, d dl-m.Z. ddl/m0Z0 ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z> ddl/m?Z@ ddlAmBZB ddl0mCZCmDZDmEZEmFZF ddlGmHZH eDe:e;e<e>d�ddddddddddddddd ddddd!ddddd"d#dd$dddddd%d&d'd(ddddddd)œ+eeIeeIeeI df eeI eeJ eJeJeKeeIeeK eeI f eeI eJeeeIef  eeI eeIeeI f eeeeLeLf eeeLeLf  f  eeI eHd* eeK ee+eIdf ee+eIdf eeIeeI edf e4eJeeKeeK df eeJ eeLeKe3df eeLe2f eIeeL eeI ee5ee5 df ee5ee5 df ee5ee5 df ee,ee, df eeJ eeKeKf eeIeIf eLeKeeK eeIeeI df eeJ eeJeIdf ee eeJ eeedf d+œ.d,d-„ƒZMd.d/„ ZNee5 ee5 ee5 ee, eLeeK eeeKdf eeKdf f d0œd1d2„ZOd3d4„ ZPePeDe:e;e<e>d�eeee df d5œd6d7„ƒƒZQePeDe:e;e<e>d�eeee df d5œd8d9„ƒƒZRePeDe:e<e>d:�eeee df d5œd;d<„ƒƒZSePeDe:e;e<e>d�dd=œeee1 eeee df d>œd?d@„ƒƒZTePeDe:e<e>d:�dddddAœeJeeJ eeJ eeJeIdf eeee df dBœdCdD„ƒƒZUePeDe:e=e<e>dE�dFdeFeFddGddGdddddddHœeIeejVdf eeIdeEf eeIeEf eeLeLeLeLf eKeeJ eKeeK eeK ee4 eeJ eeJ eeJeIdf eeee df dIœdJdF„ƒƒZWd dKœeeeIe
eI f  eee
eL e
e
eL  f  eHd* eLee
eL  dLœdMdN„ZXdteYeIeJdOœdPdQ„ZZeeIejVdRœdSdT„Z[dudUdV„Z\dveIdWœdXdY„Z]dweIeejVeJf dZœd[d\„Z^d]d^„ Z_ee eeK eKd_œd`da„Z`ee eeI eeK eKdbœdcdd„ZaeeeEdeIf eeeI ee f deœdfdg„Zbdxee eejV edeIeEf eJeeejV eeI f dhœdidj„Zceed eKeeKeKeKeKf dkœdldm„Zeddnœee4 eejV e4doœdpdq„Zfdrds„ ZgdS )yé    N)Úcopy)ÚIntegral)ÚcombinationsÚproduct)Ú
CollectionÚUnionÚOptionalÚSequenceÚAnyÚMappingÚListÚTuple)Úwarn)ÚAnnData)ÚCycler)ÚAxes)ÚFigure)Úis_categorical_dtype)ÚpyplotÚcolors)Úget_cmap)ÚrcParams)Úpatheffects)ÚColormapÚ	Normalize)Úpartialé   )Ú_utils)Ú_IGraphLayoutÚ_FontWeightÚ	_FontSizeÚ	ColorLikeÚVBoundÚcirclesÚcheck_projectionÚcheck_colornorm)Údoc_adata_color_etcÚdoc_edges_arrowsÚdoc_scatter_embeddingÚdoc_scatter_spatialÚdoc_show_save_axé   )Úlogging)Úsettings)Úsanitize_anndataÚ_doc_paramsÚEmptyÚ_empty)ÚLiteral)Úadata_color_etcZedges_arrowsÚscatter_bulkÚshow_save_axTFçš™™™™™¹?ZgreyÚ2dÚ	lightgrayÚboldúright marginÚright)g333333Ó?gš™™™™™©?)ÚblackÚwhiteé   g      Ð?)+ÚcolorÚgene_symbolsÚuse_rawÚ
sort_orderÚedgesÚedges_widthÚedges_colorÚneighbors_keyÚarrowsÚarrows_kwdsÚgroupsÚ
componentsÚ
dimensionsÚlayerÚ
projectionÚscale_factorÚ	color_mapÚcmapÚpaletteÚna_colorÚna_in_legendÚsizeÚframeonÚlegend_fontsizeÚlegend_fontweightÚ
legend_locÚlegend_fontoutlineÚcolorbar_locÚvmaxÚvminÚvcenterÚnormÚadd_outlineÚoutline_widthÚoutline_colorÚncolsÚhspaceÚwspaceÚtitleÚshowÚsaveÚaxÚ
return_fig©r7   Ú3d).ÚadataÚbasisr?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   Úreturnc       +   L         s  t |ƒ t| ƒ t| |ƒ}.t||||.jd d�}|dkrBtdd�ni }/|dkr`|dko^| jdk	}|r‚|dk	r‚td|› d|› d�ƒ‚|r˜| jdkr˜td	ƒ‚t|t	ƒr¨|g}|dk	rÆ|dk	rÂtd
ƒ‚n|}t
t|ƒƒ}| |¡ ||-d< tj|dd�}d|-k�rd|-d< t|t	ƒ�s|dk�r |gnt|ƒ}|(dk	�rLt|(t	ƒ�rD|(gnt|(ƒ}(t|t	ƒ�sft|tjƒ�sl|g}t|t	ƒ�s†t|tjƒ�sŒ|g}t| t	ƒ�s¦t| tjƒ�s¬| g} t|!tƒ�sÆt|!tjƒ�sÌ|!g}!d|-k�rê|dk�rê|- d¡}|dk	�r:|dk	�rHt|tjtjtjfƒ�rHt|ƒ| jd k�rHtj|td�}nd| jd  }|'dk�rfdtd d  d }'|dk	�r†ttt||ƒŽ ƒ\}}t||ƒ\}}t|t	ƒ�s¼t|tjƒ�r¼t|ƒdk�sÊt|ƒdk�rô|+dk	�rÜtdƒ‚t|&|'|%t|ƒƒ\}0}1n"d}1|+dk�rt  !¡ }0|0j"d5|/Ž}+g }2t#t||ƒƒD �]¤\}3\}4}5t$| |4||||d�}6t%| |4|6||d�\}7}8t&dƒ}9|dk�r¢|4dk	�r¢|8dk�r¢tj'|7 dd�ddd… }9n"|�rÄ|8�rÄtj't (|6¡ dd�}9t|tjƒ�ràt |¡|9 }|6|9 }6|7|9 }7|.dd…|5f |9dd…f }:|1�r.t j)|1|3 f|/Ž}+|2 *|+¡ |dk�rBt+j,�sRn|�sR|+ -d¡ |(dk�r~|4dk	�rr|+ .|4¡ n
|+ .d ¡ n>z|+ .|(|3 ¡ W n* t/k
�rº   t0 1d!¡ |+ .|4¡ Y nX |8�sìt2||| |!|3|7ƒ\};}<}=}>t3|;|<|=|>ƒ}?nd}?|dk�rD|+j4|:dd…df |:dd…df |:dd…d"f fd|7t+j5|?d#œ|-—Ž}@�nX|dk�r^t6|+j4|dd$�nt6t7||+|d%�}A|"�rf|#\}B}Ct 8|¡}D|D|D|C d"  d" }Et 8|E¡|D|B d"  d" }F|$\}G}Hd|-d< d&|-k�rØ|- d&¡nd}I|+j4|:dd…df |:dd…df f|Fd|Gt+j5|?d'œ|-—Ž |+j4|:dd…df |:dd…df f|Ed|Ht+j5|?d'œ|-—Ž |Idk�r^d(n|I|-d&< |A|:dd…df |:dd…df fd|7t+j5|?d#œ|-—Ž}@|+ 9g ¡ |+ :g ¡ |dk�rÄ|+ ;g ¡ t<|ƒ‰ ‡ fd)d*„|5D ƒ}J|+ =|Jd ¡ |+ >|Jd ¡ |dk�r|+j?|Jd" d+d,� |+ @¡  |�r8tA B|+| ||||	¡ |
�rNtA C|+| ||¡ |4dk�r\�q(|dk	�rxtDjE|d-d.�g}Knd}K|8�r¬tF|+|6tG| |4ƒ|:||||K||tH|1ƒd/� n |dk	�r(t jI|@|+d0d1d2|d3� �q(|,dk�rÞ|0S |1�rè|2n|+}2tAjJ||)|*d4� |)dk�r
|2S dS )6aO      Scatter plot for user specified embedding basis (e.g. umap, pca, etc)

    Parameters
    ----------
    basis
        Name of the `obsm` basis to use.
    {adata_color_etc}
    {edges_arrows}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.
    é   )rM   Ú
total_dimsrk   ©rM   NzGCannot use both a layer and the raw representation. Was passed:use_raw=z, layer=Ú.zL`use_raw` is set to True but AnnData object does not have raw. Please check.z+Cannot specify both `color_map` and `cmap`.rP   T©Z
keep_alphaZ	edgecolorÚnoneÚsr   )ZdtypeiÀÔ g      è?úfigure.figsizeg{®Gáz”?zVCannot specify `ax` when plotting multiple panels (each for a given value of 'color').éo   )rL   rA   r@   rI   )rQ   rR   FZstable)ÚkindéÿÿÿÿÚoffÚ z`The title list is shorter than the number of panels. Using 'color' value instead for some plots.r   )ÚmarkerÚcÚ
rasterizedr^   )ru   Zplotnonfinite)ru   rh   rN   Úalpha)ru   r|   r}   r~   r^   gffffffæ?c                    s   g | ]}ˆ t |d  ƒ ‘qS ©ro   )Ústr©Ú.0Úd©Úname© ú\/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/plotting/_tools/scatterplots.pyÚ
<listcomp>š  s     zembedding.<locals>.<listcomp>iùÿÿÿ)ZlabelpadÚw)Z	linewidthÚ
foreground)	rQ   Úscatter_arrayrX   rW   rV   rY   rR   rS   Úmulti_panelç{®Gáz„?g{®Gáz´?é   )rh   ÚpadÚfractionZaspectÚlocation©rf   rg   )rw   )Kr$   r.   Ú
_get_basisÚ_components_to_dimensionsÚshapeÚdictÚrawÚ
ValueErrorÚ
isinstancer�   r   r   Zset_badr   Úto_hexÚlistÚcabcr	   r   ÚpopÚpdZSeriesÚnpÚndarrayÚlenÚarrayÚfloatr   Úzipr   Ú_broadcast_argsÚ_panel_gridÚplÚfigureZadd_subplotÚ	enumerateÚ_get_color_source_vectorÚ_color_vectorÚsliceZargsortÚisnullZsubplotÚappendr-   Z_frameonZaxisÚ	set_titleÚ
IndexErrorÚloggÚwarningÚ_get_vboundnormr%   ÚscatterZ_vector_friendlyr   r#   ÚsqrtZ
set_yticksZ
set_xticksZ
set_zticksÚ_basis2nameÚ
set_xlabelÚ
set_ylabelZ
set_zlabelZautoscale_viewr   Z
plot_edgesZplot_arrowsr   Z
withStrokeÚ_add_categorical_legendÚ_get_paletteÚboolZcolorbarÚsavefig_or_show)Lrl   rm   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   ÚkwargsZbasis_valuesZargs_3dÚfigÚgridÚaxsÚcountÚvalue_to_plotÚdimsÚcolor_source_vectorÚcolor_vectorZcategoricalÚorderZcoordsZ
vmin_floatZ
vmax_floatZvcenter_floatZnorm_objÚ	normalizeZcaxrµ   Zbg_widthZ	gap_widthÚpointZgap_sizeZbg_sizeZbg_colorZ	gap_colorr   Zaxis_labelsZpath_effectr‡   r…   rˆ   Ú	embedding7   sö   K
   ÿÿÿ



$


ÿþý

ÿ
þ
ý
ü
ÿ
úû
	



ÿ     ÿü
ýùø
ÿ   ÿý

þùø
þùøþúù






ÿõ
     ÿ


rÊ   c              
   C   s´   ddl m} t||ƒ}t || ¡ t¡}tj|t	d d  d|  |t	d d  fd�}d| }d| }	|j
|||d|d |  d|  |	d|d |	  d	|  | |d
�}
||
fS )Nr   )Úgridspecrv   ro   )Zfigsizegš™™™™™É?g¤p=
×£À?rŽ   r6   )Znrowsrb   Úleftr;   ÚbottomÚtoprc   rd   )Ú
matplotlibrË   Úminr    ÚceilZastypeÚintr¨   r©   r   ZGridSpec)rc   rd   rb   Z
num_panelsrË   Z
n_panels_xZ
n_panels_yr¿   rÌ   rÍ   Úgsr‡   r‡   rˆ   r§   Ð  s*    
þÿø
r§   )r\   r[   r]   r^   ÚindexrÆ   rn   c           
      C   sÀ  g }d| fd|fd|ffD �]v\}}t |ƒdkr:|d }	nDz|| }	W n6 tk
r|   t d|› d|› d|› d	�¡ d
}	Y nX |	d
k	�rˆt|	tƒ�r|	 d¡�rzt|	dd
… ƒ W n6 tk
rê   t d|› d|	› d|d › d�¡ Y nX t	j
|t|	dd
… ƒd�}	n€t|	ƒ�r>|	|ƒ}	t|	tƒ�sˆt d|› d�¡ d
}	nJzt|	ƒ W n< tk
�r†   t d|› d|	› d|d › d�¡ d
}	Y nX | |	¡ q| t |ƒdk�r®|d n|| ¡ t|ƒS )a  
    Evaluates the value of vmin, vmax and vcenter, which could be a
    str in which case is interpreted as a percentile and should
    be specified in the form 'pN' where N is the percentile.
    Eg. for a percentile of 85 the format would be 'p85'.
    Floats are accepted as p99.9

    Alternatively, vmin/vmax could be a function that is applied to
    the list of color values (`color_vector`).  E.g.

    def my_vmax(color_vector): np.percentile(color_vector, p=80)


    Parameters
    ----------
    index
        This index of the plot
    color_vector
        List or values for the plot

    Returns
    -------

    (vmin, vmax, vcenter, norm) containing None or float values for
    vmin, vmax, vcenter and matplotlib.colors.Normalize  or None for norm.

    r\   r[   r]   ro   r   zThe parameter z# is not valid. If setting multiple z% values,check that the length of the z' list is equal to the number of plots. NÚpú=z for plot number z? is not valid. Please check the correct format for percentiles.)Úqz%The return of the function given for z? is not valid. Please check that the function returns a number.z
The given zƒ is not valid. Please check that the value given is a valid number, a string starting with 'p' for percentiles or a valid function.)r¢   r±   r²   Úerrorrš   r�   Ú
startswithr¤   r™   r    ZnanpercentileÚcallabler¯   Útuple)
r\   r[   r]   r^   rÔ   rÆ   ÚoutZv_nameÚvZv_valuer‡   r‡   rˆ   r´   ë  sJ    # 
ÿ

ÿ


ÿÿ
$r´   c                    s¦   dd l ‰ ˆ  t¡j ¡ }ˆ  | ¡}|j ¡ }| d¡ | d¡ | d¡ | |¡ ‡ fdd„| ¡ D ƒ}|jˆ j	j
k	r‚|j|d< ˆ j	t| ¡ ƒ|jd�| _|| _| S )	Nr   rm   r¾   rl   c                    s&   i | ]\}}|j ˆ jjkr||j “qS r‡   )Ú
annotationÚ	ParameterÚempty©rƒ   ÚkrÝ   ©Úinspectr‡   rˆ   Ú
<dictcomp>O  s   þ z'_wraps_plot_scatter.<locals>.<dictcomp>rn   )Úreturn_annotation)rä   Ú	signaturerÊ   Ú
parametersr   rž   ÚupdateÚitemsræ   Ú	Signaturerà   rœ   ÚvaluesÚ__signature__Ú__annotations__)ÚwrapperÚparamsZwrapper_sigZwrapper_paramsÚannotationsr‡   rã   rˆ   Ú_wraps_plot_scatterC  s&    






þ

 ÿrò   )rn   c                 K   s   t | df|ŽS )aŽ      Scatter plot in UMAP basis.

    Parameters
    ----------
    {adata_color_etc}
    {edges_arrows}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------

    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        sc.pl.umap(adata)

    Colour points by discrete variable (Louvain clusters).

    .. plot::
        :context: close-figs

        sc.pl.umap(adata, color="louvain")

    Colour points by gene expression.

    .. plot::
        :context: close-figs

        sc.pl.umap(adata, color="HES4")

    Plot muliple umaps for different gene expressions.

    .. plot::
        :context: close-figs

        sc.pl.umap(adata, color=["HES4", "TNFRSF4"])

    .. currentmodule:: scanpy

    See also
    --------
    tl.umap
    Úumap©rÊ   ©rl   r¾   r‡   r‡   rˆ   ró   b  s    ;ró   c                 K   s   t | df|ŽS )a      Scatter plot in tSNE basis.

    Parameters
    ----------
    {adata_color_etc}
    {edges_arrows}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------
    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        sc.tl.tsne(adata)
        sc.pl.tsne(adata, color='bulk_labels')

    .. currentmodule:: scanpy

    See also
    --------
    tl.tsne
    Útsnerô   rõ   r‡   r‡   rˆ   rö      s    &rö   )r3   r4   r5   c                 K   s   t | df|ŽS )a      Scatter plot in Diffusion Map basis.

    Parameters
    ----------
    {adata_color_etc}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------
    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        sc.tl.diffmap(adata)
        sc.pl.diffmap(adata, color='bulk_labels')

    .. currentmodule:: scanpy

    See also
    --------
    tl.diffmap
    Údiffmaprô   rõ   r‡   r‡   rˆ   r÷   É  s    $r÷   )Úlayout)rl   rø   rn   c                K   sX   |dkrt | jd d d ƒ}d| }d| |  ¡ krJtd d| |¡ƒ‚t| |f|ŽS )a³      Scatter plot in graph-drawing basis.

    Parameters
    ----------
    {adata_color_etc}
    layout
        One of the :func:`~scanpy.tl.draw_graph` layouts.
        By default, the last computed layout is used.
    {edges_arrows}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------
    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        sc.tl.draw_graph(adata)
        sc.pl.draw_graph(adata, color=['phase', 'bulk_labels'])

    .. currentmodule:: scanpy

    See also
    --------
    tl.draw_graph
    NÚ
draw_graphrð   rø   Údraw_graph_ÚX_z8Did not find {} in adata.obs. Did you compute layout {}?)r�   ÚunsZ	obsm_keysr™   ÚformatrÊ   )rl   rø   r¾   rm   r‡   r‡   rˆ   rù   ð  s    + ÿÿrù   )Úannotate_var_explainedrf   ri   rg   )rþ   rf   ri   rg   rn   c          
      K   s€  |st | df|||dœ|—ŽS d| j ¡ krTd| j ¡ krTtdt| j ¡ ƒ› d�ƒ‚dd„ t| jd d ƒD ƒ}|d	krÎt | dfd
|i|—Ž}|jD ]4}| ||j	 
¡  ¡  ¡ | ||j 
¡  ¡  ¡ q”|S t | dfdddœ|—Ž}	t|	tƒ�r.|	D ]4}| ||j	 
¡  ¡  ¡ | ||j 
¡  ¡  ¡ qön0|	 ||	j	 
¡  ¡  ¡ |	 ||	j 
¡  ¡  ¡ tjd||d� |dk�r||	S dS )a]      Scatter plot in PCA coordinates.

    Use the parameter `annotate_var_explained` to annotate the explained variance.

    Parameters
    ----------
    {adata_color_etc}
    annotate_var_explained
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------

    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc3k_processed()
        sc.pl.pca(adata)

    Colour points by discrete variable (Louvain clusters).

    .. plot::
        :context: close-figs

        sc.pl.pca(adata, color="louvain")

    Colour points by gene expression.

    .. plot::
        :context: close-figs

        sc.pl.pca(adata, color="CST3")

    .. currentmodule:: scanpy

    See also
    --------
    tl.pca
    pp.pca
    Úpca)rf   ri   rg   ZX_pcaz>Could not find entry in `obsm` for 'pca'.
Available keys are: rr   c              	   S   s6   i | ].\}}d   |d ¡d  |d t|d dƒ¡“qS )zPC{}ro   z
PC{} ({}%)éd   r   )rý   Úround)rƒ   ÚirÝ   r‡   r‡   rˆ   rå   r  s   ÿ zpca.<locals>.<dictcomp>Zvariance_ratioTri   Fr“   N)rÊ   ÚobsmÚkeysÚKeyErrorrœ   rª   rü   Zaxesr¸   ZxaxisZ	get_labelZget_textr¹   Zyaxisrš   r   r½   )
rl   rþ   rf   ri   rg   r¾   Z
label_dictr¿   rh   rÁ   r‡   r‡   rˆ   rÿ   (  sD    > ÿ  ÿÿÿþ

rÿ   )r3   Zscatter_spatialr4   r5   Úspatialç      ð?)rm   ÚimgÚimg_keyÚ
library_idÚ
crop_coordÚ	alpha_imgÚbwrT   rN   Ú	spot_sizerR   rf   ri   rg   )rm   r  r	  r
  r  r  r  rT   rN   r  rR   rf   ri   rg   rn   c             	   K   sr  t | j|ƒ\}}t||||d�\}}t||
ƒ}
t|||	d�}	t||	ƒ}t||d�}|r\d}nd}||	 |
 d }t| f||	||dddœ|—Ž}t|t	ƒsž|g}|D ]¢}t
 | ¡ | ¡ g¡}|dk	rÖ|j|||d	� n| d
¡ | ¡  |dk	�r| |d |d ¡ | |d |d ¡ q¢| |d |d ¡ | |d |d ¡ q¢tjd||d� |dk�sj|dk�rn|S dS )u©      Scatter plot in spatial coordinates.

    This function allows overlaying data on top of images.
    Use the parameter `img_key` to see the image in the background
    And the parameter `library_id` to select the image.
    By default, `'hires'` and `'lowres'` are attempted.

    Use `crop_coord`, `alpha_img`, and `bw` to control how it is displayed.
    Use `size` to scale the size of the Visium spots plotted on top.

    As this function is designed to for imaging data, there are two key assumptions
    about how coordinates are handled:

    1. The origin (e.g `(0, 0)`) is at the top left â€“ as is common convention
    with image data.

    2. Coordinates are in the pixel space of the source image, so an equal
    aspect ratio is assumed.

    If your anndata object has a `"spatial"` entry in `.uns`, the `img_key`
    and `library_id` parameters to find values for `img`, `scale_factor`,
    and `spot_size` arguments. Alternatively, these values be passed directly.

    Parameters
    ----------
    {adata_color_etc}
    {scatter_spatial}
    {scatter_bulk}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.

    Examples
    --------
    This function behaves very similarly to other embedding plots like
    :func:`~scanpy.pl.umap`

    >>> adata = sc.datasets.visium_sge("Targeted_Visium_Human_Glioblastoma_Pan_Cancer")
    >>> sc.pp.calculate_qc_metrics(adata, inplace=True)
    >>> sc.pl.spatial(adata, color="log1p_n_genes_by_counts")

    See Also
    --------
    :func:`scanpy.datasets.visium_sge`
        Example visium data.
    :tutorial:`spatial/basic-analysis`
        Tutorial on spatial analysis.
    )r  )r	  rN   ©r  ÚgrayNç      à?F)rm   rN   rT   rR   rf   rg   )rP   r   Úequalr   ro   r+   r   rf   r“   T)Ú_check_spatial_datarü   Ú
_check_imgÚ_check_spot_sizeÚ_check_scale_factorÚ_check_crop_coordÚ_check_na_colorrÊ   rš   rœ   r    ZconcatenateZget_xlimZget_ylimZimshowZ
set_aspectZinvert_yaxisZset_xlimZset_ylimr   r½   )rl   rm   r  r	  r
  r  r  r  rT   rN   r  rR   rf   ri   rg   r¾   Úspatial_dataZcmap_imgZcircle_radiusrÁ   rh   Z
cur_coordsr‡   r‡   rˆ   r  Ž  sT    N
  ÿ
ÿùø



rq   )rJ   rK   rM   rp   rn   c                C   sÜ   dddœ| }| dkr8|dkr8t dd„ t|ƒD ƒƒg}n| dk	rP|dk	rPtdƒ‚| dkrlttt|ƒ|ƒƒ}n&| dk	r’t| tƒr„| g} d	d
„ | D ƒ}tdd„ |D ƒƒrª|g}|D ](}t|ƒ|ksÐtdd„ |D ƒƒs®tƒ ‚q®|S )z:Normalize components/ dimensions args for embedding plots.r   r+   rj   Nc                 s   s   | ]
}|V  qd S ©Nr‡   )rƒ   r  r‡   r‡   rˆ   Ú	<genexpr>  s     z,_components_to_dimensions.<locals>.<genexpr>z-Cannot provide both dimensions and componentsÚallc                 S   s    g | ]}d d„ |  d¡D ƒ‘qS )c                 S   s   g | ]}t |ƒd  ‘qS r€   )rÒ   )rƒ   Údimr‡   r‡   rˆ   r‰   !  s     z8_components_to_dimensions.<locals>.<listcomp>.<listcomp>ú,)Úsplit©rƒ   r}   r‡   r‡   rˆ   r‰   !  s     z-_components_to_dimensions.<locals>.<listcomp>c                 s   s   | ]}t |tƒV  qd S r  ©rš   r   )rƒ   Úelr‡   r‡   rˆ   r  #  s     c                 s   s   | ]}t |tƒV  qd S r  r!  r‚   r‡   r‡   rˆ   r  '  s     )	rÛ   Úranger™   rœ   r   rš   r�   r  r¢   )rJ   rK   rM   rp   ZndimsrÄ   r‡   r‡   rˆ   r•   
  s"    	
r•   )rQ   rX   rS   c                 C   s6  |	rBt  |¡ ¡ rBd|kr"tdƒ‚| d¡ d¡}| ¡ }||d< |j}|dkrv|  ¡ }|  	|j
|j|jd |jg¡ |dkrÔ|D ]}| jg g || |d� q‚| jddd	t|ƒd
kr¸dnt|ƒdkrÈdnd|d� n^|dk�r2t j|
ddgd�j|dd� ¡  ¡ }| ¡ D ]&\}}}| j||||dd||d� �q
dS )z Add a legend to the passed Axes.ZNAzINo fallback for null labels has been defined if NA already in categories.Tg…ëQ¸í?r:   )r}   ÚlabelFzcenter left)ro   r  é   ro   r�   r   r+   )rU   ÚlocZbbox_to_anchorZncolÚfontsizezon dataÚxÚy)Úcolumns)ZobservedÚcenter)ÚweightZverticalalignmentZhorizontalalignmentr'  Zpath_effectsN)rŸ   r®   ÚanyÚNotImplementedErrorÚadd_categoriesÚfillnar   Ú
categoriesZget_positionZset_positionZx0Zy0ÚwidthÚheightrµ   Zlegendr¢   Z	DataFrameÚgroupbyZmedianZ
sort_indexZ
itertuplesÚtext)rh   rÅ   rQ   rX   rW   rV   rY   r�   rR   rS   rŒ   ZcatsÚboxr$  Zall_posZx_posZy_posr‡   r‡   rˆ   rº   -  sN    ÿ"û
 ÿÿ
ørº   )rl   rm   rn   c                 C   sN   || j kr| j | S d|› �| j kr4| j d|› � S td|› d|› d�ƒ‚dS )z9Get array for basis from anndata. Just tries to add 'X_'.rû   zCould not find 'z' or 'X_z
' in .obsmN)r  r  )rl   rm   r‡   r‡   rˆ   r”   o  s
    

r”   c                 C   sž   |dkrt  t j| j¡S |dk	rP|| jjkrP|| jkrP| jj| j| |k d }|rn|| jjkrn| j	 
|¡}n| j
||d�}|ršt|ƒrš| |j |¡¡}|S )z<
    Get array from adata that colors will be based on.
    Nr   )rL   )r    Úbroadcast_toÚnanÚn_obsÚobsr*  Z	var_namesÚvarrÔ   r˜   Z
obs_vectorr   Zremove_categoriesr1  Ú
difference)rl   rÃ   rA   r@   rL   rI   rì   r‡   r‡   rˆ   r«   y  s"    ÿ
þýÿr«   )Ú
values_keyc                 C   s€   |› d�}t  | j| ¡}|r.t | ||¡ n<|| jksPt| j| ƒt|jƒk r^t | |¡ nt 	| |¡ t
t|j| j| ƒƒS )NÚ_colors)rŸ   ÚCategoricalr:  r   Z_set_colors_for_categorical_obsrü   r¢   r1  Z'_set_default_colors_for_categorical_obsZ_validate_paletter—   r¥   )rl   r=  rQ   Z	color_keyrì   r‡   r‡   rˆ   r»   —  s    
ÿr»   )r=  rn   c                    s¢   t tjdd�‰ |dkr,t ˆ |ƒ| j¡dfS t|ƒs<|dfS ‡ fdd„t| ||d� ¡ D ƒ}t	 
| |¡¡}| ¡  ¡ r–| ˆ |ƒg¡}| ˆ |ƒ¡}|dfS dS )a  
    Map array of values to array of hex (plus alpha) codes.

    For categorical data, the return value is list of colors taken
    from the category palette or from the given `palette` value.

    For continuous values, the input array is returned (may change in future).
    Trs   NFc                    s   i | ]\}}|ˆ |ƒ“qS r‡   r‡   rá   ©r›   r‡   rˆ   rå   »  s   ÿ z!_color_vector.<locals>.<dictcomp>)rQ   )r   r   r›   r    r7  r9  r   r»   rê   rŸ   r?  ÚmapZisnar-  r/  r0  )rl   r=  rì   rQ   rR   rO   rÆ   r‡   r@  rˆ   r¬   ¦  s    
þr¬   c                 C   sP   | dkrdn>| dkrdn2| dkr$dn&| dkr0dnd	| krH|   d
d¡ ¡ n| }|S )z4
    converts the 'basis' into the proper name.
    r÷   ZDCrö   ZtSNEró   ZUMAPrÿ   ÚPCrù   rú   r{   )ÚreplaceÚupper)rm   Zcomponent_namer‡   r‡   rˆ   r·   Ê  s    ÿÿÿÿÿõr·   )r  r  rn   c                 C   s6   | dkr|dkrt dƒ‚n|dkr.| d d S |S dS )zV
    Resolve spot_size value.

    This is a required argument for spatial plots.
    NzUWhen .uns['spatial'][library_id] does not exist, spot_size must be provided directly.ÚscalefactorsZspot_diameter_fullres)r™   )r  r  r‡   r‡   rˆ   r  ß  s    ÿr  )r  r	  rN   rn   c                 C   s8   |dk	r|S | dk	r0|dk	r0| d d|› d� S dS dS )z$Resolve scale_factor, defaults to 1.NrE  Ztissue_Z_scalefr  r‡   )r  r	  rN   r‡   r‡   rˆ   r  ò  s
    r  )rü   r
  rn   c                 C   sx   |   di ¡}|tkrZt|ƒdkr8tdt| ¡ ƒ› �ƒ‚n"t|ƒdkrVt| ¡ ƒd }nd}|dk	rl|| }nd}||fS )zŽ
    Given a mapping, try and extract a library id/ mapping with spatial data.

    Assumes this is `.uns` from how we parse visium data.
    r  ro   zUFound multiple possible libraries in `.uns['spatial']. Please specify. Options are:
	r   N)Úgetr1   r¢   r™   rœ   r  )rü   r
  Zspatial_mappingr  r‡   r‡   rˆ   r     s    ÿ
r  )r  r  r	  r  rn   c                    s|   |dkr.ˆ dk	r.|t kr.t‡ fdd„dD ƒƒ}|dkrRˆ dk	rR|dk	rRˆ d | }|rtt |ddd…f dd	d
g¡}||fS )z*
    Resolve image for spatial plots.
    Nc                 3   s   | ]}|ˆ d  kr|V  qdS )ÚimagesNr‡   )rƒ   râ   ©r  r‡   rˆ   r  %  s      z_check_img.<locals>.<genexpr>)ZhiresZlowresrG  .r+   gÅ�1w-!Ó?gbX9´Èâ?gÉv¾Ÿ/½?)r1   Únextr    Údot)r  r  r	  r  r‡   rH  rˆ   r    s    	ÿr  )r  rN   rn   c                    s:   | dkrdS t | ƒdkr tdƒ‚t‡ fdd„| D ƒƒ} | S )z$Handle cropping with image or basis.Nr>   z3Invalid crop_coord of length {len(crop_coord)}(!=4)c                 3   s   | ]}|ˆ  V  qd S r  r‡   r   ©rN   r‡   rˆ   r  7  s     z$_check_crop_coord.<locals>.<genexpr>)r¢   r™   rÛ   )r  rN   r‡   rK  rˆ   r  .  s    r  r  )rR   r  rn   c                C   s   | d kr|d k	rd} nd} | S )N)ç        rL  rL  rL  r8   r‡   )rR   r  r‡   r‡   rˆ   r  ;  s
    r  c                     sf   ddl m} dd„ | D ƒ}t|ƒ‰ t|ƒdˆ hksPt|ƒˆ hksPtd|› d�ƒ‚t‡ fdd„| D ƒƒS )	z(Broadcasts arguments to a common length.r   )Úrepeatc                 S   s   g | ]}t |ƒ‘qS r‡   )r¢   )rƒ   Úargr‡   r‡   rˆ   r‰   J  s     z#_broadcast_args.<locals>.<listcomp>ro   z3Could not broadast together arguments with shapes: rr   c                    s2   g | ]*‰ t ˆ ƒd kr*‡ fdd„tˆƒD ƒnˆ ‘qS )ro   c                    s   g | ]}ˆ d  ‘qS )r   r‡   )rƒ   Ú_©rN  r‡   rˆ   r‰   O  s     z._broadcast_args.<locals>.<listcomp>.<listcomp>)r¢   r#  )rƒ   ©ÚlongestrP  rˆ   r‰   O  s     )Ú	itertoolsrM  ÚmaxÚsetr™   rœ   )ÚargsrM  Zlensr‡   rQ  rˆ   r¦   F  s    ÿr¦   )N)FNNN)N)r8   )F)hÚcollections.abcÚabcr�   r   Únumbersr   rS  r   r   Útypingr   r   r   r	   r
   r   r   r   Úwarningsr   Únumpyr    ZpandasrŸ   Zanndatar   Zcyclerr   Zmatplotlib.axesr   Zmatplotlib.figurer   Zpandas.api.typesr   rÏ   r   r¨   r   Zmatplotlib.cmr   r   r   Zmatplotlib.colorsr   r   Ú	functoolsr   r{   r   r   r   r    r!   r"   r#   r$   r%   Z_docsr&   r'   r(   r)   r*   r,   r²   Z	_settingsr-   r.   r/   r0   r1   Z_compatr2   r�   r¼   r¤   rÒ   rÊ   r§   r´   rò   ró   rö   r÷   rù   rÿ   r¡   r  r•   r—   rº   r”   r«   r»   r¬   r·   r  r  r  r  rÛ   r  r  r¦   r‡   r‡   r‡   rˆ   Ú<module>   s:  (
(
ü
Ò"


Ð   ùXü 7ü "ý !üÿ þ1ýúø`ü	ð
îyü
ú. õöB       ÿ
 ÿþ$ þü þ üûýÿ þ