U
    md@                  +   @   sr  d dl Z d dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZmZmZ d dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZ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+m,Z,m-Z- ddl(m)Z.m/Z0 ddl1m2Z2 ddl3m4Z4 d8ddee4d e
e5e6e-df e
e5e,f dddZ7dd ddd ei fee8ef ddd Z9dddei dd ddd!dddddei d"d#d"ddd$dd%d dddddei dd&dd&ddd&dddf(ee	e6 e	e
e8ee
e8e5f eee6f f f  e	e+ ee8ef e	ej: e
e5e8ee5 df e
e8ee8 ee8e8f df e;e8e	e8 e	e8 e	e5 e8e	e5 ee8ef e6e6e6e	e6 e	e6 e5e	e8 e6e	e5 e
ej:e8edf e;e
e8e#f e	e  ee8ef e	e; e;e;e;e;e	e; e
e;e8df e	e  e
e ee  df d''d(d)Z<ddddddd dddddei d"d#d"d*dddd&ddddd&ei dd$fee8ef ee8ef d+d,d-Z=d&d.dee>d/d.dd0dd1ddddd&d&d&dddd&ddddfeee
e8e5f  ee8 e;ee8 e
e8e#df ee8e
e8e#f f e	ee8  e5e	e8 ee	e5 e	e5 f e	e8 e	e5 e	e5 e;e;e;e
e5e6e-df e
e5e,df e;e;e;e	e; e
e;e8df e	e  e	e  d2d3d4Z?d9d6d7Z@dS ):    N)Path)MappingProxyType)OptionalUnionListSequenceMappingAnyTuple)AnnData)is_categorical_dtype)pyplotrcParamsticker)patheffects)Axes)is_color_likeColormap)issparse)check_random_state   )_utils)matrix_IGraphLayout_FontWeight	_FontSize   )r   logging)settings)LiteralF2don databold皙?pos)r    Z3d)adata
projectionlegend_fontsizelegend_fontweightc          %      K   sZ  t jddg|d\}}}}|dkr0| jd d }d}|dkrT|dkrH|n|}d\}}|dkrd| jkrld	}n4d
| jkr|d}n$d| jkrd}nd| jkrd}nd}ddlm}m}m} || |d ||||||||	|
||||||ddd |dkrx|| jd d krj|| |}||d|jd dd } |dd| f }!t	j
|!ddg| jdj| j| dd   }n| jd d }|d  |d   }"}#|d |" |d |# d|kr|d}$n|}$|	dk	r|	|d< |
dk	r|
|d< |dk	r||d< t| f|d dd||$|||d| |dk	r8t| t jd||d  |dkrV|S dS )!aa      Scatter and PAGA graph side-by-side.

    Consists in a scatter plot and the abstracted graph. See
    :func:`~scanpy.pl.paga` for all related parameters.

    See :func:`~scanpy.pl.paga_path` for visualizing gene changes along paths
    through the abstracted graph.

    Additional parameters are as follows.

    Parameters
    ----------
    adata
        Annotated data matrix.
    kwds_scatter
        Keywords for :func:`~scanpy.pl.scatter`.
    kwds_paga
        Keywords for :func:`~scanpy.pl.paga`.

    Returns
    -------
    A list of :class:`~matplotlib.axes.Axes` if `show` is `False`.
    r      )panelsright_marginNpagagroups) r/   ZX_draw_graph_faZdraw_graph_faZX_umapZumapZX_tsneZtsneZX_draw_graph_frZdraw_graph_fr)	embedding
_get_basis_components_to_dimensionsF)axbasiscoloredgesalphar.   
components
legend_locr(   r)   legend_fontoutline	color_mappaletteframeonsizetitleshowsave)r8   
dimensionsZ
total_dimsxy)columnsindexT)Zobservedr%   labelsfontsize
fontweightfontoutline)r3   r@   rA   r?   rG   colorsr=   r%   paga_comparer@   rA   )r   
setup_axesunsZobsmZscatterplotsr0   r1   r2   shapepd	DataFrameZ	obs_namesgroupbyobsmedianZ
sort_indexZto_numpyZget_xlimget_ylimZset_xlimZset_ylimpopr-   plsuptitlesavefig_or_show)%r&   r4   r6   r5   r7   r.   r8   r'   r9   r(   r)   r:   r;   r<   r=   r>   r?   r,   left_marginr@   rA   Ztitle_graphZgroups_graphr%   Zpaga_graph_paramsaxs_rY   r0   r1   r2   Z_basisZdimscoordsxlimZylimrG    r`   T/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/plotting/_tools/paga.pyrL      s    4





   







rL   )layout_kwdsc                    s  dd l }dd l}t|}|| }	|d kr.d}|dkrjzddlm}
 W n" tk
rh   td d}Y nX |dkr|d kr|	| j
d df}n| }|
dddddd	d
dddddd}d|kr|d }nd|kr|d }nd}|j| ||d}dd t|D  nV|dkrH||}t|| t | j
d k r^tdn||d t| }d|krt|}|j|t|tr|n|gdj}n|dkr||j}n|d kr|	| j
d df }n(| }|d d df  d9  < | }z|j|f|dd|j}W n. tk
rJ   |j|fd|i|j}Y nX dd t|D  t dkrtd d< t fd d!t|	D }|S )"Nr   frfa)ForceAtlas2zPackage 'fa2' is not installed, falling back to layout 'fr'.To use the faster and better ForceAtlas2 layout, install package 'fa2' (`pip install fa2`).r   F      ?Tg333333?g       @)ZoutboundAttractionDistributionZ
linLogModeZadjustSizesZedgeWeightInfluenceZjitterToleranceZbarnesHutOptimizeZbarnesHutThetaZmultiThreadedZscalingRatioZstrongGravityModeZgravityverbosemaxiter
iterationsi  )r%   ri   c                 S   s$   i | ]\}}||d  |d  gqS r   r*   r`   .0npr`   r`   ra   
<dictcomp>   s      z _compute_pos.<locals>.<dictcomp>eq_treezKThis is a forest and not a single tree. Try another `layout`, e.g., {'fr'}.   rt)rootcircler*   weight)seedweightsrw   c                 S   s$   i | ]\}}||d  |d  gqS rj   r`   rk   r`   r`   ra   ro     s      )      ?ry   c                    s   g | ]\}} | qS r`   r`   )rl   countrm   r$   r`   ra   
<listcomp>  s     z _compute_pos.<locals>.<listcomp>)randomnetworkxr   GraphZfa2re   ImportErrorloggwarningZrandom_samplerP   copyforceatlas2	enumerater   Zhierarchy_poslen
ValueErrorrw   bytes	_sc_utilsZget_igraph_from_adjacencylayout
isinstancelistr^   tolistAttributeErrornparray)adjacency_solidr   random_stateinit_posadj_treers   rb   r|   nx
nx_g_solidre   Zinit_coordsr   ri   Zpos_listZ	nx_g_treegZg_tree	pos_arrayr`   r$   ra   _compute_pos   s    	




  




 



 r   connectivitiesrf   ry      {Gz?T)'r&   	thresholdr5   r   rb   r   rs   rG   single_componentsolid_edgesdashed_edgestransitionsrH   rI   rJ   	text_kwdsnode_size_scalenode_size_poweredge_width_scalemin_edge_widthmax_edge_width	arrowsizer?   r[   r   r%   normalize_to_colorcmapcaxcb_kwdsr=   add_posexport_to_gexfuse_rawplotr@   rA   r3   returnc)           =   "      s~  |$dk	r|$t d |#dkr"|}# jd d  fdd})t|#tjrt|#tt|# tjrdd t j	 j
jD fd	d|# D }#|)|#r|#g}#|dkrtj}|)r҇fd
dtt|#D dkrt|#dkrdd |#D n8ttrfdd|#D ndkr.dd |#D |dkrh jdkrJ jn jj fdd|#D }*ndd |#D }*t|tr|krtd d|dt|}t|tjr|d krއfdd|D } jd |	  }+d},|dkrd}|dkr$d|+j|+j|k < |+  |
dk	rb jd |
  },|dkrbd|,j|,j|k < |,  |dkrd}-|dkr jd d }-t|+|||||-|d}|%rtj|(|#|*d\}.}/}0}1t|#dkrt|.ts|.g}.t|#D ].\}2}3|2 dk	r|.|2 |2  t |.|2 t|#tjr*|#n|3|	|
|||+|,||2 |||||||||||||*|2 ||"|2 |!|||d}4|*|2 r|dkr|/d d }5|/d d |5 }6d|0 t|# }7|/d d|2 d  d|7  }8|8|5|7|6g}9t ! }:|:"|9};n||2 };t j#|4t$%tj&|;d }<q| r4| jd d!< t 'd" |%rztj(d|&|'d# t|#dkrlt|.trl|.d }.|&d$krz|.S dS )%u      Plot the PAGA graph through thresholding low-connectivity edges.

    Compute a coarse-grained layout of the data. Reuse this by passing
    `init_pos='paga'` to :func:`~scanpy.tl.umap` or
    :func:`~scanpy.tl.draw_graph` and obtain embeddings with more meaningful
    global topology [Wolf19]_.

    This uses ForceAtlas2 or igraph's layout algorithms for most layouts [Csardi06]_.

    Parameters
    ----------
    adata
        Annotated data matrix.
    threshold
        Do not draw edges for weights below this threshold. Set to 0 if you want
        all edges. Discarding low-connectivity edges helps in getting a much
        clearer picture of the graph.
    color
        Gene name or `obs` annotation defining the node colors.
        Also plots the degree of the abstracted graph when
        passing {`'degree_dashed'`, `'degree_solid'`}.

        Can be also used to visualize pie chart at each node in the following form:
        `{<group name or index>: {<color>: <fraction>, ...}, ...}`. If the fractions
        do not sum to 1, a new category called `'rest'` colored grey will be created.
    labels
        The node labels. If `None`, this defaults to the group labels stored in
        the categorical for which :func:`~scanpy.tl.paga` has been computed.
    pos
        Two-column array-like storing the x and y coordinates for drawing.
        Otherwise, path to a `.gdf` file that has been exported from Gephi or
        a similar graph visualization software.
    layout
        Plotting layout that computes positions.
        `'fa'` stands for “ForceAtlas2”,
        `'fr'` stands for “Fruchterman-Reingold”,
        `'rt'` stands for “Reingold-Tilford”,
        `'eq_tree'` stands for “eqally spaced tree”.
        All but `'fa'` and `'eq_tree'` are igraph layouts.
        All other igraph layouts are also permitted.
        See also parameter `pos` and :func:`~scanpy.tl.draw_graph`.
    layout_kwds
        Keywords for the layout.
    init_pos
        Two-column array storing the x and y coordinates for initializing the
        layout.
    random_state
        For layouts with random initialization like `'fr'`, change this to use
        different intial states for the optimization. If `None`, the initial
        state is not reproducible.
    root
        If choosing a tree layout, this is the index of the root node or a list
        of root node indices. If this is a non-empty vector then the supplied
        node IDs are used as the roots of the trees (or a single tree if the
        graph is connected). If this is `None` or an empty list, the root
        vertices are automatically calculated based on topological sorting.
    transitions
        Key for `.uns['paga']` that specifies the matrix that stores the
        arrows, for instance `'transitions_confidence'`.
    solid_edges
        Key for `.uns['paga']` that specifies the matrix that stores the edges
        to be drawn solid black.
    dashed_edges
        Key for `.uns['paga']` that specifies the matrix that stores the edges
        to be drawn dashed grey. If `None`, no dashed edges are drawn.
    single_component
        Restrict to largest connected component.
    fontsize
        Font size for node labels.
    fontoutline
        Width of the white outline around fonts.
    text_kwds
        Keywords for :meth:`~matplotlib.axes.Axes.text`.
    node_size_scale
        Increase or decrease the size of the nodes.
    node_size_power
        The power with which groups sizes influence the radius of the nodes.
    edge_width_scale
        Edge with scale in units of `rcParams['lines.linewidth']`.
    min_edge_width
        Min width of solid edges.
    max_edge_width
        Max width of solid and dashed edges.
    arrowsize
       For directed graphs, choose the size of the arrow head head's length and
       width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute
       `mutation_scale` for more info.
    export_to_gexf
        Export to gexf format to be read by graph visualization programs such as
        Gephi.
    normalize_to_color
        Whether to normalize categorical plots to `color` or the underlying
        grouping.
    cmap
        The color map.
    cax
        A matplotlib axes object for a potential colorbar.
    cb_kwds
        Keyword arguments for :class:`~matplotlib.colorbar.Colorbar`,
        for instance, `ticks`.
    add_pos
        Add the positions to `adata.uns['paga']`.
    title
        Provide a title.
    frameon
        Draw a frame around the PAGA graph.
    plot
        If `False`, do not create the figure, simply compute the layout.
    save
        If `True` or a `str`, save the figure.
        A string is appended to the default filename.
        Infer the filetype if ending on \{`'.pdf'`, `'.png'`, `'.svg'`\}.
    ax
        A matplotlib axes object.

    Returns
    -------
    If `show==False`, one or more :class:`~matplotlib.axes.Axes` objects.
    Adds `'pos'` to `adata.uns['paga']` if `add_pos` is `True`.

    Examples
    --------

    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc3k_processed()
        sc.tl.paga(adata, groups='louvain')
        sc.pl.paga(adata)

    You can increase node and edge sizes by specifying additional arguments.

    .. plot::
        :context: close-figs

        sc.pl.paga(adata, node_size_scale=10, edge_width_scale=2)

    Notes
    -----
    When initializing the positions, note that – for some reason – igraph
    mirrors coordinates along the x axis... that is, you should increase the
    `maxiter` parameter by 1 if the layout is flipped.

    .. currentmodule:: scanpy

    See also
    --------
    tl.paga
    pl.paga_compare
    pl.paga_path
    Nz9`groups` is deprecated in `pl.paga`: use `labels` insteadr-   r.   c                    s<   t | tjo$t| t j jjk}|p:| d kp:t | tS N)r   cabc
Collectionr   rT   cat
categoriesstr)rC   Zhas_one_per_category)r&   
groups_keyr`   ra   is_flat  s    zpaga.<locals>.is_flatc                 S   s   i | ]\}}||qS r`   r`   )rl   irm   r`   r`   ra   ro     s     zpaga.<locals>.<dictcomp>c                    s   i | ]\}}  |||qS r`   )get)rl   rm   v)names_to_ixsr`   ra   ro     s     
 c                    s   g | ]} qS r`   r`   rl   r]   rG   r`   ra   r{     s     zpaga.<locals>.<listcomp>r*   c                 S   s   g | ]}|qS r`   r`   rl   cr`   r`   ra   r{     s     c                    s   g | ]} qS r`   r`   r   )r?   r`   ra   r{     s     c                 S   s   g | ]}d qS r   r`   r   r`   r`   ra   r{     s     c                    s2   g | ]*}|   kr& j| jjd kp,|kqS )category)obs_keysrT   Zdtypenamer   )r&   	var_namesr`   ra   r{     s   c                 S   s   g | ]}d qS )Fr`   r   r`   r`   ra   r{     s     z-If `root` is a string, it needs to be one of z not .r   c                    s   g | ]}t  |qS r`   )r   rF   )rl   rr   r`   ra   r{     s     r   >   rr   rp   rt_circularconnectivities_tree)r   r   r   rb   r   rs   )r3   r+   	colorbars)rK   r   r   r   r   r   adjacency_dashedrs   rG   rH   rI   rJ   r   r   r   r   r   r   r   r=   r   colorbarr   r   r?   r   r   r   r%   g~jtx?r   皙?)formatr   r%   z3added 'pos', the PAGA positions (adata.uns['paga'])rM   F))r   r   rO   r   r   r   nextiterr   rT   r   r   itemsr   Z_frameonranger   r   rawr   r   r   rF   r   r   dataeliminate_zerosr   r   rN   	set_title_paga_graphrX   ZgcfZadd_axesr   r   ZFuncFormatterZticks_formatterhintrZ   )=r&   r   r5   r   rb   r   rs   rG   r   r   r   r   rH   rI   rJ   r   r   r   r   r   r   r   r?   r[   r   r%   r   r   r   r   r   r=   r   r   r   rK   r.   r   r@   rA   r3   r   r   r   r   r   r\   Z	panel_posZdraw_region_widthZfigure_widthZicolorr   sctbottomheightwidthleftZ	rectangleZfigZax_cbr]   r`   )r&   r   rG   r   r?   r   ra   r-     s    F
 









!





r-   	reference)r   r   c           U   	      s   dd l }|
} | d k	rJt| trJ| | jd d krJtd| jd d | | jd d }!| d krn| j|! jj}  d ks |!kr|!d k	r|!d | jkst	| j|! jjt	| j|!d  krt
| |! | j|!d   t| j|! jjD ]\}"}#|#tjkrd |"< q||}$|d k	r"||}%t|ttfs8|}&nt|}|jdkrTtdd	}'| 4}(|(  |(D ] })|)d
r q|'|)7 }'qnW 5 Q R X ddlm}* tj|*|'dd}+|+ddg j}&dd t|&D }t trt r fddtt	| D  t tr dr dkrBdd |%jddD  n* dkrddd |$jddD  ntdt t  t  t    | j!d kr| j"n| j!j"},t trJ |,krJg }-| j|! jj}.t|.D ]f\}/}0|0| j|! kj}1| j!d k	r|r| j!d d  f }2n| d d  f }2|-#t$|2j%|1  q|- t trƈ | jkrt&| j  sg }-| j|! jj}.t|.D ]4\}/}0|0| j|! kj}1|-#| jj'|1 f $  q|- t tr4 | jkr4t&| j  r4t(j)| |! |rdndd\}3}4t
|   t(*| j d  |4}5|5 t	 t	| krdtdt	|  d t	  d!t+j,j-.|\}6}
|6d"kr|st/0d# |6d"kr^|r^t1|
}7t2|7|7  kd d }8|3 |
|8kd d f }|4 d d |
|8kf }t |
|8k  t| |
|8k } | j|! jj|
|8k 5 }9t/6d$|9  ||}$|d k	r^td%|d t7d&  }:|d k	rd'd |%j8d(d)D };|:t|; };|d k	rt9|;d |};|j:|%|||;dd*d+d, |d krPd-d |$j8d(d)D };|:t|; };|d k	s|d k	rt9|;||};t;< $ t;=d. |j:|$|||;d/d0 W 5 Q R X n| jd | > }<|d krpd1}d|<j?|<j?|k < |<@  |A|<jB}=d2d |=j8d(d)D };|:t|; };|d k	s|d k	rt9|;||};|j:|=|||;d/|d3 |rt d tCr$dd4lDmE fd5d D  t|$F D ]l\}>}?t| |> |$jG|> d6< t |> |$jG|> d7< tHtHd8||> d  d8||> d"  dd9d:|$jG|> d;< q0tjId< }@t/Jd=|@  tjIjKd(d(d> |L|$tjId<  |M| |Ng  |Og  |!d k	r"|!d? | jkr"| j|!d?  }AntPt	| }Ad@}B|BtQ|jRd dA  | }CtS|A}D|CtT|A|D | }A|d krt7dB }|d k	rtH|}tUjV|dCdDg|dE< t d tWjX	s>t	|&}E|jY|&d d df |&d d d"f  d |E dF|A|dG}Ft| D ]:\}>}G|jZ|&|>df |&|>d"f |GfdHdH||dI| qntt[|&d d df |&d d d"f D ]\\}H}It  tWjX	st   dJ  \ }J fdKd|JD }Kt]|K}L|Ld"k 	rt^|J}J|J#d |K#d"t]|K  n$t_|Ld"
stdL dM|L d!t`|K}M|M|Md  }Mdg|M5  }Mt[|Md d |Md"d  |JD ]\}N}O}PtadNtjb |N dNtjb |O dO}Qdgtc|Q5  }Rdgtd|Q5  }Ste|R|Sg}Ttf|T  }'|jY|Hg|Ig|T|'dN |A  |PdP}F
qR| d k		rd|jZ|H|I|  fdHdH||dI| 	qd|FS )QNr   r-   r.   z>Provide a list of group labels for the PAGA groups {}, not {}._colorsZgreyz.gdfzqCurrently only supporting reading positions from .gdf files. Consider generating them using, for instance, Gephi.r/   zedgedef>)StringIOru   )header      c                 S   s"   i | ]\}}||d  |d gqS rj   r`   rk   r`   r`   ra   ro     s      z_paga_graph.<locals>.<dictcomp>c                    s   g | ]} qS r`   r`   r   )rK   r`   ra   r{     s     z_paga_graph.<locals>.<listcomp>degreeZdegree_dashedc                 S   s   g | ]\}}|qS r`   r`   rl   r]   dr`   r`   ra   r{     s     rv   )rv   Zdegree_solidc                 S   s   g | ]\}}|qS r`   r`   r   r`   r`   ra   r{     s     z2`degree` either "degree_dashed" or "degree_solid".r   
prediction)r   r   Znormalizationz#Expected `colors` to be of length `z
`, found `z`.r*   znGraph has more than a single connected component. To restrict to this component, pass `single_component=True`.zHRestricting graph to largest connected component by dropping categories
z4`single_component` only if `dashed_edges` is `None`.zlines.linewidthc                 S   s   g | ]}|d  d qS ru   rv   r`   rl   rC   r`   r`   ra   r{   7  s     T)r   Zdashedry   )r3   r   
edge_colorstyler7   c                 S   s   g | ]}|d  d qS r   r`   r   r`   r`   ra   r{   G  s     ignoreblack)r3   r   r   r   c                 S   s   g | ]}|d  d qS r   r`   r   r`   r`   ra   r{   X  s     )r3   r   r   r   rgb2hexc                    s   g | ]} |qS r`   r`   r   r   r`   ra   r{   d  s     labelr5   i  )rC   rD   z)positionZvizzpaga_graph.gexfzexporting to )parentsexist_okZ_sizesi  
   zlegend.fontsizew)Z	linewidth
foregroundZpath_effectsZface)r   Z
edgecolorssr   center)verticalalignmenthorizontalalignmentr>   rI   zK is neither a dict of valid matplotlib colors nor a valid matplotlib color.c                    s   g | ]}  | qS r`   r`   r   )rK   ixr`   ra   r{     s     zExpected fractions for node `z` to be close to 1, found `r      )markerr   r5   )gr}   r   r   rO   r   r   rT   r   r   r   r   ,add_colors_for_categorical_sample_annotationr   r   Zcategories_to_ignorer~   r   suffixopenreadline
startswithior   rQ   Zread_csvvaluesr   r   r   r   r   minmaxr   r   appendZmeanXr   locr   Z$compute_association_matrix_of_groupsZget_associated_colors_of_groupsscipysparseZcsgraphZconnected_componentsr   debugZbincountwhereZtocsrZtocscr   infor   r6   ZclipZdraw_networkx_edgeswarningscatch_warningssimplefilterr   r   r   ZDiGraphTtuplematplotlib.colorsr   nodesnodedictZwritedirr   mkdirZ
write_gexfset_frame_on
set_xticks
set_yticksZonessqrtrP   rU   powerr   Z
withStroker   r   scattertextzipkeyssumr   isclosecumsumZlinspacepicossinZcolumn_stackabs)Ur&   r3   r   r   r   r   r   r   rs   rK   rG   rH   rI   rJ   r   r   r   r   r   r?   r%   r   r=   r   r   r   r   r   r   r   r   r   Znode_labelsr   Zinamer   r   Znx_g_dashedr   r   fliner   dfr   Zx_colorZcatsZicatr   ZsubsetZ
adata_geneZ
asso_namesZasso_matrixZasso_colorsZn_componentsZcomponent_sizesZlargest_componentZcats_droppedZbase_edge_widthwidthsZadjacency_transitionsZg_dirrz   rm   filenameZgroups_sizesZbase_scale_scatterZbase_pie_sizeZmedian_group_sizeZn_groupsr   groupZxxyyZcolor_singleZfracstotalr$  r1r2r5   ZanglesrC   rD   Zxyr`   )rK   r   r   ra   r   ~  s*   ! 







(
 







    
     




 




4


&"    


r   )dpt_pseudotimeGreysr*   )NN)r&   r  r!  r   annotationsr;   color_maps_annotationspalette_groupsn_avgr   r_   r?   ytick_fontsizetitle_fontsizeshow_node_namesshow_yticksshow_colorbarr(   r)   normalize_to_zero_one
as_heatmapreturn_datar@   rA   r3   r   c           >         s  |dk}|	dkr4d| j d kr&td| j d d }	| j|	 jj d| j krXtd|dkr|t| |	 | j |	 d }fdd	}|dkrt	
 n|}g }d
g}g }g }dd |D } t|d
 tr"g }!t }"|D ]>}#|#|"kr
td   d|	d|#d|! |# q|}$n|}! fdd|D }$| }%|rT| jdk	rT| j}%t|D ]B\}&}'g }(t|!D ]>\})}*t| j| j|	 j|$|) k }+t|+d
krtd|	dt|*d|	dt| jd j| j|	 j|$|) k },|+|, }+|'|  kr| j|' jn|%dd|'f j|+ }-|(t|-r:|-jn|- 7 }(|&d
krr||*gt|+ 7 }|t|( |D ]<}.| j|. }/t|/r|/jj}/| |.  t|/j|+ 7  < qrqrdkr ||(}(|&d
kr |D ]*}'t| |' d
 ts|| |' | |'< q|r"|(t |(8 }(|(t!|( }(||( |sP|j"|(|
d
 |
d  |'d |&d
kr\t|D ]:\})}*t d
kr|* kr |* }0n|*}0||0 qbq\t#|$ }|r\|j%|dd|d}1|r|&t't| |j(||d n
|&g  |)d |*g  |j+ddd
d |,d |r<t	j-|1|d  |dkrJd!n|}t	j.|d" n8|dkrjd#n|}t|dkrt	j/dd$| d%f|d& |	}2|s|0|2 t	1g  t|dkrTt	2|d
 d'  n~d
dl3}3|4 j5}4t	6|4d
 |4d |4d( t|  |4d) |4d( t| f}5t7|dddf }|5j%|dd|3j8j9|t |:t;d t;t!|d t | d*d |r|5j(d+|2d+g|d n
|5&g  |5)d |r|5< d |5< d
  d) }6t=j>|d)d,}t|D ],\}7}0|5j?||7 |6||7 t@d-d-d.d/ q|5*g  |5,d |5j+ddd
d |4d( t| }8t|D ]\}9}.|9d
krz|4d( t| d) }8t	6|4d
 |4d |9d) |8  |4d) |8f}:t7| |. dddf };|.|krt| j|. rd0nd1}<n||. }<|:j%|;dd|<d}1|r(|:j(d+|.d+g|d |:j+ddd
d n
|:&g  |:)d |:*g  |:,d qT|dk	rl|jA||d |dkr|sd}n|dkrtBjCn|}tjDd2||d3 |rtEjF|jG|d4}=|||=d< d| kr| d jG|=d5< ||r|s|=n|=fS |r|s|S dS dS )6a      Gene expression and annotation changes along paths in the abstracted graph.

    Parameters
    ----------
    adata
        An annotated data matrix.
    nodes
        A path through nodes of the abstracted graph, that is, names or indices
        (within `.categories`) of groups that have been used to run PAGA.
    keys
        Either variables in `adata.var_names` or annotations in
        `adata.obs`. They are plotted using `color_map`.
    use_raw
        Use `adata.raw` for retrieving gene expressions if it has been set.
    annotations
        Plot these keys with `color_maps_annotations`. Need to be keys for
        `adata.obs`.
    color_map
        Matplotlib colormap.
    color_maps_annotations
        Color maps for plotting the annotations. Keys of the dictionary must
        appear in `annotations`.
    palette_groups
        Ususally, use the same `sc.pl.palettes...` as used for coloring the
        abstracted graph.
    n_avg
        Number of data points to include in computation of running average.
    groups_key
        Key of the grouping used to run PAGA. If `None`, defaults to
        `adata.uns['paga']['groups']`.
    as_heatmap
        Plot the timeseries as heatmap. If not plotting as heatmap,
        `annotations` have no effect.
    show_node_names
        Plot the node names on the nodes bar.
    show_colorbar
        Show the colorbar.
    show_yticks
        Show the y ticks.
    normalize_to_zero_one
        Shift and scale the running average to [0, 1] per gene.
    return_data
        Return the timeseries data in addition to the axes if `True`.
    show
         Show the plot, do not return axis.
    save
        If `True` or a `str`, save the figure.
        A string is appended to the default filename.
        Infer the filetype if ending on \{`'.pdf'`, `'.png'`, `'.svg'`\}.
    ax
         A matplotlib axes object.

    Returns
    -------
    A :class:`~matplotlib.axes.Axes` object, if `ax` is `None`, else `None`.
    If `return_data`, return the timeseries data in addition to an axes.
    Nr.   r-   zWPass the key of the grouping with which you ran PAGA, using the parameter `groups_key`.r3  zc`pl.paga_path` requires computation of a pseudotime `tl.dpt` for ordering at single-cell resolutionr   c                    s   t |  S r   )r   moving_average)a)r8  r`   ra   rA  E  s    z!paga_path.<locals>.moving_averager   c                 S   s   i | ]
}|g qS r`   r`   )rl   annor`   r`   ra   ro   N  s      zpaga_path.<locals>.<dictcomp>zEach node/group needs to be in z (`groups_key`=z) not r   c                    s   g | ]} | qS r`   r`   )rl   r  )groups_namesr`   ra   r{   \  s     zpaga_path.<locals>.<listcomp>z/Did not find data points that match `adata.obs[z].values == z`. Check whether `adata.obs[z%]` actually contains what you expect.r*   )r   autoZnearest)Zaspectinterpolationr   )rH   FZboth)Zaxiswhichlength)r3   r   )r   g?zcenter leftry   )r=   r	  Zbbox_to_anchorrH   z (a.u.)r   r   )Nr/   )rm   r   )r   r   )ZfontdictZVega10r4  	paga_pathrM   )r   rE   Zdistance)HrO   KeyErrorrT   r   r   r!  r   r   r   rX   Zgcar   r   setr   r  Zget_locr   r   r   ZarangeZn_obsr  r   Zargsortr   r  r   Ar   codesr   r  r  r   ZasarrayZsqueezeZimshowr  r   Zset_yticklabelsr  r  Ztick_paramsgridr   Zsubplots_adjustZlegendZ
set_xlabelZyticksZylabelr  Zget_positionZboundsZaxesr   rK   ZListedColormapZastypeintrV   r   rA  r  r  r   r   ZautoshowrZ   rQ   rR   r  )>r&   r  r!  r   r5  r;   r6  r7  r8  r   r_   r?   r[   r9  r:  r;  r<  r=  r(   r)   r>  r?  r@  r@   rA   r3   Zax_was_nonerA  r  Zx_tick_locsZx_tick_labelsr.   Z	anno_dictZ
nodes_intsZgroups_names_setr  Z
nodes_strsZadata_XikeykeyrC   Zigroupr.  ZidcsZ
idcs_groupr  rC  Zseriesr   ZimgZxlabel
matplotlibZ	ax_boundsZgroups_axisZyposZilabelZy_shiftZiannoZ	anno_axisZarrZcolor_map_annor+  r`   )rD  r8  ra   rJ    s   X


*


"














	








rJ  r   c                    s  | j |  }| j | }|rpt||dd t|jd D ]4 |   d }	tj fdd|	D |	ddd q8nt  t	|D ]z\ }
 fd	dt	|
D } fd
dt	|
D }tj||ddd |   d }	tj fdd|	D |
|	 ddd qt
jd||d dS )zConnectivity of paga groups.F)r;   r@   r   r*   c                    s   g | ]} qS r`   r`   rl   jr   r`   ra   r{   $  s     z"paga_adjacency.<locals>.<listcomp>r   )r5   r   c                    s   g | ]\}} |kr qS r`   r`   )rl   rU  r   rV  r`   ra   r{   )  s      c                    s   g | ]\}} |kr|qS r`   r`   )rl   rU  r   rV  r`   ra   r{   *  s      grayc                    s   g | ]} qS r`   r`   rT  rV  r`   ra   r{   -  s     Zpaga_connectivityrM   N)rO   Ztoarrayr   r   rP   ZnonzerorX   r  Zfigurer   r   rZ   )r&   Z	adjacencyZadjacency_treer?  r;   r@   rA   ZconnectivityZconnectivity_selectZ	neighborscsrC   rD   r`   rV  ra   paga_adjacency  s    

$&rY  )NFNNNNr    r!   Nr"   NNNFNNNr#   NNNN)r   r   TNNN)Ar  collections.abcabcr   pathlibr   typesr   typingr   r   r   r   r   r	   r
   numpyr   ZpandasrQ   r
  Zanndatar   Zpandas.api.typesr   rS  r   rX   r   r   r   Zmatplotlib.axesr   r  r   r   Zscipy.sparser   Zsklearn.utilsr   r/   r   r   r   r   r   r   r   r   Z	_settingsr   Z_compatr   rP  floatrL   r   r   Zndarrayboolr-   r   r  rJ  rY  r`   r`   r`   ra   <module>   s  $                      
 
l&



  m

  `
  @      