U
    md7                  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	rtd| d| d|r| jdkrtd	t|t	r|g}|dk	r|dk	rt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	st|tjs|g}t| t	st| tjs| g} t|!tst|!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	rttt|| \}}t||\}}t|t	st|tjrt|dkst|dkr|+dk	rt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rtj'|7 ddddd }9n"|r|8rtj't(|6 dd}9t|tjrt||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   t01d! |+.|4 Y nX |8st2||| |!|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, |+@  |r8tAB|+| ||||	 |
rNtAC|+| || |4dkr\q(|dk	rxtDjE|d-d.g}Knd}K|8rtF|+|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{Gz?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{Gz?g{Gz?   )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?gp=
ף?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	rt|	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}	nt|	r>|	|}	t|	tst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rt | dfd
|i|}|jD ]4}|||j	
    |||j
    q|S t | dfddd|}	t|	tr.|	D ]4}|||j	
    |||j
    qn0|	||	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  qt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	rt| tr| g} d	d
 | D }tdd |D r|g}|D ](}t||kstdd |D st 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rdnt|dkrd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}|rt|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?gv/?)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       
 $    