U
    md2W                    @   s  d 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 ddlmZmZmZ ddlmZ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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% ddl&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl+m-Z. ddl/m0Z0 ddl1m2Z2m3Z3m4Z4 ddl5m6Z6 ddl+m1Z1 ddl1m7Z7m8Z8m9Z9m:Z: ddl1m;Z;m<Z<m=Z= ddl>m?Z?m@Z@mAZAmBZB dddd d!d"d#d$d%d&d'd(d)d*d+hZCe6d, ZDe
eEeeE f ZFe3e?e@d-dzee	eE e	eE e
eEeeE f e	eG e
eEeeE f eGe	eH e	eD e
eEeeE f e
eEeeE f e6d0 eEe
eIeHe=df e
eIe<df eHe
eEe(f e
ee)e;ee; f e	eG e	eH e	eH e
eIeHdf e	eE e	eG e
eEeGdf e	e d1d2d3ZJd{ee6d0 d4d5d6ZKd|ee6d: e
eEeeE f d;d<d=ZLe3e@d>d}ee
eEeeE f e	eE eGe	eG eGe
eHeGf eIe	eE e6dA e	eeE  e	eG eEe	e
eEeeE f  e	eH e	eG e
eGeEdf e	e dBdCdDZMe3e@d>d~eeEe	eG e	eG e
eGeEdf dEdFdGZNe3eBe@eAdHdee
eFeeEeFf f e
eEeeE f e	eG eGeIe
eGeEf e	eE e	eeeIeIf   e	eeE  e	eH e	eE e	e6dJ  eGe	eG e	eG e
eEeGdf e	eeHeHf  e	eH e	eH e	eH e	e* dKdLdMZOe3e@eAdNdee
eFeeEeFf f e
eEeeE f e	eG eGe
eGeEf e	eE e	eeeIeIf   e	eeE  e	eE e	eG e
eEeGdf e	eeHeHf  dOdPdQZPe3e@d>ddRd9ddddSeeEe	eE e6dT eGe	eG e
eEeGdf e	e dUdVdWZQe3e@eBdXdeeEeGe
eGeEdf e	eeHeHf  e	eG e
eEeGdf e	e e	eH e	eH e	eH e	e* e
eee f dYdZd[ZRdee
eFeeEeFf f e	e
eEeeE f  e	eG eGeIe	eE d\d]d^ZSdeeeeIeIf  eeE eHeHe	eH e6da dbdcddZTdededfdgZUdhdi ZVdjdk ZWdeeeEe	eE e6dT eGe	eeH  dldmdnZXdeejYe6dT eEdqdrdsZZdeHdudvdwZ[dxdy Z\dS )z Plotting functions for AnnData.
    Nproduct)OrderedDict)OptionalUnionMapping)Sequence
CollectionIterable)TupleList)AnnData)Cycler)Axes)is_categorical_dtypeis_numeric_dtypeissparse)pyplot)rcParams)gridspec)patheffects)is_color_likeColormapListedColormap	Normalize   )get)logging)settings)sanitize_anndata_doc_params_check_use_raw)Literal   )_utils)scatter_basescatter_group
setup_axescheck_colornorm)	ColorLike_FontWeight	_FontSize)doc_scatter_basicdoc_show_save_axdoc_common_plot_argsdoc_vboundnormnoneright marginon dataon data exportbestzupper rightz
upper leftz
lower leftzlower rightrightcenter leftzcenter rightzlower centerzupper centercenter)pcatsneumapdiffmapZdraw_graph_fr)Zscatter_tempshow_save_axT2d)r>   3d)adataxycoloruse_rawlayers
sort_orderalphabasisgroups
components
projection
legend_loclegend_fontsizelegend_fontweightlegend_fontoutline	color_mappaletteframeonright_marginleft_marginsizetitleshowsaveaxc                 C   s<  t  }t| |r| jjj}n| jj}|dk	r6tf |S |dksF|dkrNtd|| j ksd||kr|| j ksz||kr|dks|| j ks||krtf |S || j ks|| jjkr0|| j ks|| jjkr0|dks|| j ks|| jjkr0| j	}tf d|idd |
 D }|j| _|S tddS )a      Scatter plot along observations or variables axes.

    Color the plot using annotations of observations (`.obs`), variables
    (`.var`) or expression of genes (`.var_names`).

    Parameters
    ----------
    adata
        Annotated data matrix.
    x
        x coordinate.
    y
        y coordinate.
    color
        Keys for annotations of observations/cells or variables/genes,
        or a hex color specification, e.g.,
        `'ann1'`, `'#fe57a1'`, or `['ann1', 'ann2']`.
    use_raw
        Whether to use `raw` attribute of `adata`. Defaults to `True` if `.raw` is present.
    layers
        Use the `layers` attribute of `adata` if present: specify the layer for
        `x`, `y` and `color`. If `layers` is a string, then it is expanded to
        `(layers, layers, layers)`.
    basis
        String that denotes a plotting tool that computed coordinates.
    {scatter_temp}
    {show_save_ax}

    Returns
    -------
    If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it.
    N(Either provide a `basis` or `x` and `y`.r@   c                 S   s   i | ]\}}|d kr||qS r@    ).0namevalr\   r\   Q/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/plotting/_anndata.py
<dictcomp>   s       zscatter.<locals>.<dictcomp>zQ`x`, `y`, and potential `color` inputs must all come from either `.obs` or `.var`)localsr"   rawvarindex_scatter_obs
ValueErrorobskeysTitemsuns)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   argsZ	var_indexZadata_Taxsr\   r\   r`   scatter=   s`    >





ro   )r@   rK   c           >         s	  t |  ddlm} t| |}|dks>t|trJ|| j krJ|||f}nZt|tj	rt
|dkrt|}|D ]"}|| j krn|dkrntdqnntd| d|r|dkrtd	 |tkrtd
t d|
dkrd|krdnd}
t|
tr|
d}
t|
td }
|dkr dgnt|ts6t|r<|gn|}|dk	r\t|tr\|g}d| jkrr| jd ng }|dk	rzB|dkr|
d7 }
| jd|  dd|
f }|dkr|
d8 }
W n& tk
r   td| dY nX n|dk	r|dk	r|rT|| jjkr | |}n| j|}|| jjkrF| |} n| j|} n$| j||d d}| j||d d} tj|| f }ntddkr|jd }!d|! |dr|dkrtd }n|dkrtd }d}" dkrd}"t tjrt d s }#n g}#n fdd t t
|D }#t!|#D ]\}$ t"# |#|$< q<|dk	r|dkrnd!nT|d"kr|d#nF|d$krd%n8|d&krd'n*|d(krd)nd*|kr|$d+d,% n|}%nd}%|%dkr||fnd}&|%dkrdnd}'g }(g })g }*t!|D ]\}+},d-}-d}.d}/|,| & krJt'| j|, r>d}.n
| j|, }-n|rx| jdk	rx|,| jj(krx| j|,}-nT|,| j(kr| j|,|d. d}-n4t|,r|,}-d}/n td/|,d0| &  d1| j( |/dkr|. }/|*)|/ |.r|))|+ |()|- q|dkr*t
|)dkr*|d2kr*d3}|dkrP|d dk	rPd4d  |D }t*||||%|&|
d ||(||*||fd5d |D ||'|d6}0d7d8 }1t!|)D ]\}$}+|#|$  ||+ },t"j+| |, |" d9 tj,|jd t-d:}2i }3|	dkrTt!| j|, j.j/D ]T\}4}5|5t0j1krt2|0|+ |,|4| |||d;}6d|2|6< |dr|1|3|5||6 qnt|	trf|	gn|	}	|	D ]}5|5t3| j|, j.j/krt|5d<| j|, j.j/ n\t4| j|, j.j/j5|5kd }4t2|0|+ |,|4| |||d;}6|dr|1|3|5||6 d|2|6< qn|26 dkrf||2df ||2df g}7|d=krJ|7)||2d.f  |0|+ j7|7dd>d?d@dA d}8|dr|dkrdB}|dk	rt8j9|dCdDg}9nd}9|3: D ]0\}5}:|0|+ j;|:d |:d |5|dEdE||9dF qt<t
| j|, j.j/d.f};t!| j|, j.j/D ]2\}4}5|5|3kr,|3|5 |;|4< ntj=tj=g|;|4< q|dGk	r t0j>dH }<t?@dI|<  t0j>jAdddJ tjB|<|;ddK nz|d2kr|0|+ jCddLdMt
| j|, j.j/dNkrdnt
| j|, j.j/dOkrd.nd|dP}8n|d?k	r |0|+ jCd||dQ}8|8dk	r|8jDD ]}=|=EdRg 	qq|dk	r8t0jFn|}|	s|dk	r|dk	r|0D ]$}|Gd, |Hd, |Id 	qZ|dk	rt0jJn|}t"jK|dk	rdSn|||dT |	st
|dk	r|0S |0d S dS )UzSee docstring of scatter.r   r   )XN   zM`layers` should have elements that are either None or in adata.layers.keys().zQ`layers` should be a string or a collection of strings with length 3, had value ''))rp   rp   rp   )NNNz-`use_raw` must be `False` if layers are used.z)Invalid `legend_loc`, need to be one of: .Nr>   z1,2z1,2,3,r$   Zgrey
highlightsr<   ZX_z-compute coordinates using visualization tool z first)layerrZ   i r3   zlegend.fontsizeFTc                    s   g | ]} qS r\   r\   r]   _)rQ   r\   r`   
<listcomp>  s     z _scatter_obs.<locals>.<listcomp>ZDCr:   ZtSNEr;   ZUMAPr9   PCZtrimapZTriMapZ
draw_graphZdraw_graph_ whiter   zkey z7 is invalid! pass valid observation annotation, one of z or a gene name r2         ?c                 S   s$   g | ]}t |s|d dndqS )rx    r{   )r   replace)r]   keyr\   r\   r`   ry   X  s    c                    s   g | ]} qS r\   r\   rw   )rU   r\   r`   ry   i  s     )rV   rG   component_nameaxis_labelsZcomponent_indexnamesrK   colorsru   	colorbarsrS   rT   sizesrP   
show_ticksrY   c                 S   sV   || }|j d dkrd S tj|dd}ttjt|| dd}|| | |< d S )Nr   axisr$   )shapenpmedianZargminsumabs)	centroidsr^   YmaskZY_maskr   ir\   r\   r`   add_centroido  s    z"_scatter_obs.<locals>.add_centroid)Zforce_update_colors)dtype)rU   rG   z( is invalid! specify valid name, one of r?   Z	lightgreyr1   )markercs
edgecolorszorderboldw)	linewidth
foregroundr8   )weightverticalalignmenthorizontalalignmentfontsizeZpath_effectsr4   zpos.csvzexporting label positions to )parentsexist_ok)	delimiterr7   )r$   r}         )rR   locZbbox_to_anchorZncolr   )rR   r   r   g     r@ro   rW   rX   )Lr    scipy.sparser   r"   
isinstancestrrE   ri   cabcr	   lentuplerg   VALID_LEGENDLOCSsplitr   arrayastypeintr   rl   obsmKeyErrorrh   columnsZ
obs_vectorrc   Zc_r   
startswithr   r   range	enumerater%   Zdefault_paletter   upperobs_keysr   	var_namesappendr&   ,add_colors_for_categorical_sample_annotationZonesboolcat
categoriesr   Zcategories_to_ignorer'   setZflatnonzerovaluesr   ro   r   Z
withStrokerk   textZzerosnanZwritedirloggwarningmkdirZsavetxtlegendZlegendHandlesZ	set_sizesZ_frameon
set_xlabel
set_ylabelZset_frame_onautoshowsavefig_or_show)>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   r   rv   ri   ru   r   Zx_arrZy_arrnZpalette_was_noneZpalettesr   r   r   r   Z	color_idsZcategoricalsr   ikeyr   r   categoricalcolorbarrn   r   Zmask_remainingr   Zinamer^   r   datar   Zpath_effectposZall_posfilenamehandler\   )rQ   rU   r`   rf      s&   
















 




	   











  



rf   blackr   F)rd   rh   rl   varmr   )r@   attrri   c              
      s  t  tr@|dk	r@t| |  dd|f } fdd|D  n*|dkrXt| |  }nt| ||   }t  tr|t nd}|dkr|dddf  g } |rt|}dkr|dkr| jnt|j	d 
tt trfddt|j	d D |dkrd| }}nd	t|d	 d
  }}tj|td d  |td d  fd}d| d|  }}tjd||||d|d |  d|  d|d |  d|  d}t|jD ]\}}t||  t|ddd }|	s|d|d  }n&|d|d	  }|||d	   d }t|ddddd}t|D ]$\}}tj||| | f| q6|	r&|| ||d   d	 }t|t| t|k rtjt||df| t|D ]0\}}tj|t| d	 || | f| qn6t|D ],\}}tj|t| || | f| qtg  t | dd |dksP||krZtd td|d |	rpdnd  t||	r|n| t||  }}t|dkrdnd| |dkrdnd|  q|
dkrt j!n|
}
|
s|S dS ) ao      Plot rankings.

    See, for example, how this is used in pl.pca_ranking.

    Parameters
    ----------
    adata
        The data.
    attr
        The attribute of AnnData that contains the score.
    keys
        The scores to look up an array from the attribute of adata.

    Returns
    -------
    Returns matplotlib gridspec with access to the axes.
    Nc                    s$   g | ]} d d  |d  qS )Nr   r$   r\   r]   r   )ri   r\   r`   ry     s     zranking.<locals>.<listcomp>r$   >   rd   r   r   c                    s   g | ]} t |d   qS r$   )r   r   )labelsr\   r`   ry   .  s        r   r}   zfigure.figsizefigsize皙?p=
ף?{Gz?皙?)wspacenrowsncolsleftbottomr6   topr   verticalr   r8      )rC   rotationr   r   r   u   ⋮rx   r~   rankinggg?gffffff?g?)"r   r   getattrlistr   r   logr   aranger   r   r   r   plfigurer   r   GridSpecr   rj   ZsubplotZargsortdictr   ZxticksrV   r   xlabelZxlimminmaxZylimr   r   )r@   r   ri   
dictionaryindicesr   rC   Zn_pointsr   Zinclude_lowestrW   ZscoresZn_panelsZn_rowsZn_colsrx   r   r   gsZiscoreZscoreZorder_scoresZneg_indicesZtxt_argsZiggZ	score_midZ	score_minZ	score_maxr\   )ri   r   r`   r     s    

	,&

r   )r=   widthr{   )Zareacountr   )r@   ri   groupbyr   rD   	stripplotjitterrU   rv   scaleordermulti_panelr   ylabelr   rW   rX   rY   c                  K   s  ddl }t|  t| |}t|tr*|g}tt|}t|ttdfrd|g|dkrZdnt	| }|dkrt	|dkrt
dt	| dn.t	|t	|krt
dt	| dt	| d|dk	rRtj| |g| ||d}|d	ddkrdt| j| st
d
|d| j| j dt| | tt|| jj| j| d |d	< ntj| |||d}|dkrtj||d}d}dg}n|}|}|}|r|dkrt	|dkr|d }|jf ||d|	||d|ddd
|}|r8||}tt|jjd |D ]0\}}|j|||||d|jd|f d q|rJ|j dd |j!dd"d |dk	r|jd D ]}|j#d|d qpn|$dd |$d |dkrt%||dkrdgn|dd d!\}}}}n|g}t|||D ]\}}}|j&f ||||
d"|	|d#|}|r0|j||||
|d||d$}|dkrZ|dk	rZ|dkrZ|'d%d&}|(| |dk	rx|)| |r|*d |dk	r|j#d|d q|dkrt+j,n|}tj-d||d' |s
|r|dkrt	|dkr|S t	|dkr|d S |S dS )(u      Violin plot.

    Wraps :func:`seaborn.violinplot` for :class:`~anndata.AnnData`.

    Parameters
    ----------
    adata
        Annotated data matrix.
    keys
        Keys for accessing variables of `.var_names` or fields of `.obs`.
    groupby
        The key of the observation grouping to consider.
    log
        Plot on logarithmic axis.
    use_raw
        Whether to use `raw` attribute of `adata`. Defaults to `True` if `.raw` is present.
    stripplot
        Add a stripplot on top of the violin plot.
        See :func:`~seaborn.stripplot`.
    jitter
        Add jitter to the stripplot (only when stripplot is True)
        See :func:`~seaborn.stripplot`.
    size
        Size of the jitter points.
    layer
        Name of the AnnData object layer that wants to be plotted. By
        default adata.raw.X is plotted. If `use_raw=False` is set,
        then `adata.X` is plotted. If `layer` is set to a valid layer name,
        then the layer is plotted. `layer` takes precedence over `use_raw`.
    scale
        The method used to scale the width of each violin.
        If 'width' (the default), each violin will have the same width.
        If 'area', each violin will have the same area.
        If 'count', a violin’s width corresponds to the number of observations.
    order
        Order in which to show the categories.
    multi_panel
        Display keys in multiple panels also when `groupby is not None`.
    xlabel
        Label of the x axis. Defaults to `groupby` if `rotation` is `None`,
        otherwise, no label is shown.
    ylabel
        Label of the y axis. If `None` and `groupby` is `None`, defaults
        to `'value'`. If `None` and `groubpy` is not `None`, defaults to `keys`.
    rotation
        Rotation of xtick labels.
    {show_save_ax}
    **kwds
        Are passed to :func:`~seaborn.violinplot`.

    Returns
    -------
    A :class:`~matplotlib.axes.Axes` object if `ax` is `None` else `None`.

    Examples
    --------

    .. plot::
        :context: close-figs

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        sc.pl.violin(adata, keys='S_score')

    Plot by category. Rotate x-axis labels so that they do not overlap.

    .. plot::
        :context: close-figs

        sc.pl.violin(adata, keys='S_score', groupby='bulk_labels', rotation=90)

    Set order of categories to be plotted or select specific categories to be plotted.

    .. plot::
        :context: close-figs

        groupby_order = ['CD34+', 'CD19+ B']
        sc.pl.violin(adata, keys='S_score', groupby='bulk_labels', rotation=90,
            order=groupby_order)

    Plot multiple keys.

    .. plot::
        :context: close-figs

        sc.pl.violin(adata, keys=['S_score', 'G2M_score'], groupby='bulk_labels',
            rotation=90)

    For large datasets consider omitting the overlaid scatter plot.

    .. plot::
        :context: close-figs

        sc.pl.violin(adata, keys='S_score', stripplot=False)

    .. currentmodule:: scanpy

    See also
    --------
    pl.stacked_violin
    r   Nr$   z.Expected number of y-labels to be `1`, found `z`.z#Expected number of y-labels to be `z
`, found `)ri   rv   rD   rQ   zThe column `adata.obs[z,]` needs to be categorical, but is of dtype rs   _colors)Z
value_varsvariablevalueviolinF)
rB   r   kindr  colZ	col_ordershareyr  cutinnerr   )rB   r   r   rU   rC   rY   r   )Zyscalez
{col_name})Zcol_templater{   rA   )r   Zlabelrotationr  r  T333333?)rY   Zpanelsr   rS   r   )rA   rB   r   r  Zorientr  rY   )rA   rB   r   r  r   rC   rU   rY   rx   r~   r   ).seabornr    r"   r   r   r   r   fromkeystyper   rg   r   obs_dfr   rh   r   r%   r   r   zipr   r   rl   pdZmeltZcatplotr   r   axesr   r   Z	get_groupr   Z
set_titlesZset_xlabelstick_params
setdefaultr(   Z
violinplotr   r   r   
set_yscaler   r   r   ) r@   ri   r   r   rD   r   r   rU   rv   r  r  r  r   r  r   rW   rX   rY   kwdssnsr  obs_tidyrA   ysrB   r   Z
grouped_dfZax_idr   rn   rx   Zylabr\   r\   r`   r  o  s    |
















r  )r@   r   rD   rW   rX   c                 K   s  ddl }t|ttdfs"tdt|  t| |}|r@| jjn| j}t	|rV|
 }tj|| j| jd}|dk	r| j| }	t| | tt|	jj| j|d  }
| j| |
}	|j|fd|	ji|}n|j|f|}|dkrtjn|}tjd||d |rt  n|S dS )	aj      Hierarchically-clustered heatmap.

    Wraps :func:`seaborn.clustermap` for :class:`~anndata.AnnData`.

    Parameters
    ----------
    adata
        Annotated data matrix.
    obs_keys
        Categorical annotation to plot with a different color map.
        Currently, only a single key is supported.
    use_raw
        Whether to use `raw` attribute of `adata`. Defaults to `True` if `.raw` is present.
    {show_save_ax}
    **kwds
        Keyword arguments passed to :func:`~seaborn.clustermap`.

    Returns
    -------
    If `show` is `False`, a :class:`~seaborn.ClusterGrid` object
    (see :func:`~seaborn.clustermap`).

    Examples
    --------
    Soon to come with figures. In the meanwile, see :func:`~seaborn.clustermap`.

    >>> import scanpy as sc
    >>> adata = sc.datasets.krumsiek11()
    >>> sc.pl.clustermap(adata, obs_keys='cell_type')
    r   Nz*Currently, only a single key is supported.)re   r   r  
row_colors
clustermapr   )r  r   r   r  rg   r    r"   rc   rp   r   Ztoarrayr  	DataFrameZ	obs_namesr   rh   r%   r   r   r  r   r   rl   mapr  r   r   r   r   r   rW   )r@   r   rD   rW   rX   r  r  rp   Zdfr  Zlutr   r\   r\   r`   r  u  s*    (


r  )vminmaxr=   common_plot_args   )rd   rh   )r@   r   r   rD   r   num_categories
dendrogramgene_symbolsvar_group_positionsvar_group_labelsvar_group_rotationrv   standard_scale	swap_axesshow_gene_labelsrW   rX   r   vminvmaxvcenternormc           9   
      s  t |	|\}	}t| ||||||d\ }|	dk	rNt|	 rJd}nd}|dkr|j|ddd}|j|dddd}n@|d	kr||d8 }||d d}n|dkrn
t	
d
 |dkst dkrd}d}nZd}t|tr:t| j| r:|d | jkr*ddlm} || | | j|d  nd|rt| |||	| d}|d }	|d }|d dk	r|jdd|d f }fdd|d D |jj fdd|d D dd|_dk	rfdd|d D |dkrtdkrd}nd}t	
d |r"| }d}t||||}|s|rDdnd}|rRdnd}|dkrd}|rxtd } nd} | | | }!n|\}!}|!||  } |dk	rt|dkrd|g}"nd|g}"|| ||g}#tj|!|fd}$tjdd |#d|! d!| |"d"}%|$|%d# }&|d$d% |&j|j fd&|d'|}'|&!|j"d d( d) |&#d)|j"d d(  |&j$d*ddd+ |&%d, |&&d |r|&j$d-d.d/ |&'t()t |&j*d0d1 n|&j$d-ddd2 t+|'|$|%d3  |rL|$|%d4 }(t,|(|d5d6\})}*}+},}t(-|jj.dd7dd8 d( }-|&j/|-d)td( dd9d:dd; |rv|$j|%d< |&d=}.t0|.| ||*|d> |dk	rt|dkr|$j|%d? |&d@}/t1|/||	|
dAddB n|rdCnd}0|rd!nd}1|dkr|rtdD }2nd }2d:}!|2|0 |1 }n|\}!}||0|1  }2|0|2|1g}"|dk	rJt|dkrJ|!dE|g}#n
|!d|g}#tj|!|fd}$tjdFdFdG|! d| |#|"dH}%|$|%d4 }&|d$d% |&j|j2j fd&|d'|}'|&#d)|j"d d(  |&!|j"d d( d) |&j$d-dddI |&3d, |&&d |rB|&j$d*d.ddJ |&4t()t |&j5dd1 n|&j$d*dddK |r|$|%dL }(t,|(|dMd6\})}*}+},}t(-|jj.dd7dd8 d( }-|&j6|-d)td( dd9d:dd; |r|$j|%dN |&d@}.t0|.| |||*dOdP |dk	rt|dkr|$|%d# }/g }3t7t8|	|D ]@\}4\}5}6|r@|)|5 }7n|4}7|3|7g|6d d |6d   7 }3q$|/jt(9|3gj2d&|,|dQ |/:dR t+|'|$|%d<  dS|&i}8|r|(|8dT< |r|.|8dU< |dk	rt|dkr|/|8dV< t;j<dW||dX |dkr t=j>n|}|s|8S dS )Ya"      Heatmap of the expression values of genes.

    If `groupby` is given, the heatmap is ordered by the respective group. For
    example, a list of marker genes can be plotted, ordered by clustering. If
    the `groupby` observation annotation is not categorical the observation
    annotation is turned into a categorical by binning the data into the number
    specified in `num_categories`.

    Parameters
    ----------
    {common_plot_args}
    standard_scale
        Whether or not to standardize that dimension between 0 and 1, meaning for each variable or observation,
        subtract the minimum and divide each by its maximum.
    swap_axes
         By default, the x axis contains `var_names` (e.g. genes) and the y axis the `groupby`
         categories (if any). By setting `swap_axes` then x are the `groupby` categories and y the `var_names`.
    show_gene_labels
         By default gene labels are shown when there are 50 or less genes. Otherwise the labels are removed.
    {show_save_ax}
    {vminmax}
    **kwds
        Are passed to :func:`matplotlib.pyplot.imshow`.

    Returns
    -------
    List of :class:`~matplotlib.axes.Axes`

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

        import scanpy as sc
        adata = sc.datasets.pbmc68k_reduced()
        markers = ['C1QA', 'PSAP', 'CD79A', 'CD79B', 'CST3', 'LYZ']
        sc.pl.heatmap(adata, markers, groupby='bulk_labels', swap_axes=True)

    .. currentmodule:: scanpy

    See also
    --------
    pl.rank_genes_groups_heatmap
    tl.rank_genes_groups
    r&  rv   NTFrh   r$   r   r   rd   z(Unknown type for standard_scale, ignoredr  )_get_paletter   r(  r'  r   r(  r'  var_names_idx_orderedc                    s   g | ]} | qS r\   r\   r]   rA   r   r\   r`   ry   O  s     zheatmap.<locals>.<listcomp>c                    s   g | ]} | qS r\   r\   r5  r   r\   r`   ry   R  s     categories_idx_orderedZorderedc                    s   g | ]} | qS r\   r\   r5  groupby_colorsr\   r`   ry   X  s    2   zqGene labels are not shown when more than 50 genes are visualized. To show gene labels set `show_gene_labels=True`r      r  r   333333?r   r      r   )r   r   width_ratiosr   hspaceheight_ratios)r$   r$   interpolationZnearestauto)aspectr0  r}   g      rB   r   r   	labelleftr{   rA   small)r   	labelsizeZ   r   )r   labelbottomr   )r$   rq   )r$   r   r   r   orientationsortr   r   
   )lwrC   r   Zclip_on)r$   r   r  )ticksdendrogram_key)r   r$   Zsharex333333ӿ)group_positionsgroup_labelsr   left_adjustmentright_adjustmentg?g
ףp=
?Q?rq         ?)r   r   r   rA  r@  rB  r   r   rL  )r   rI  length)r   rG  r   )r   r   r   )r   r   r   )rU  rT  rN  rE  cmapr0  off
heatmap_ax
groupby_axdendrogram_axgene_groups_axheatmapr   )?_check_var_names_type_prepare_dataframer   issubsetsubr   divr   Zfillnar   r   r   r   r   r   rh   rl   Z_tools.scatterplotsr2  $_reorder_categories_after_dendrogramilocre   reorder_categories
sort_indexr)   r   r   r   r   add_subplotr  imshowr   set_ylimr   set_xlimr  r   grid
set_xticksr   r   set_xticklabels_plot_colorbar_plot_categories_as_colorblockscumsumvalue_countsZhlines_plot_dendrogram_plot_gene_groups_bracketsrj   r   
set_yticksset_yticklabelsvlinesr   r  r   r   r%   r   r   r   )9r@   r   r   rD   r   r$  r%  r&  r'  r(  r)  rv   r*  r+  r,  rW   rX   r   r-  r.  r/  r0  r  r  Zvar_groups_subset_of_groupbyr   r2  dendro_dataZcolorbar_widthZdendro_widthZgroupby_widthheightZheatmap_widthr   rB  r@  figrn   rc  Zimrd  
label2coderT  r   groupby_cmapline_positions	dendro_axrf  dendro_heightgroupby_heightZheatmap_heightarridxlabelr   Z
label_codereturn_ax_dictr\   )r   r;  r   r`   rg    s   L  










	

   

    






   



"   
rg  )r=   r"  )r@   r   r   rD   r   r%  r&  r'  r(  rv   rW   rX   r   c           6         s  |   ks j| jjdkrDtd| d fdd   D  t||\}}t |||d||	d\}|d  jkrd	d
lm	} | |  j|d  |rHt
 ||||d}|d dk	r|jdd|d f }fdd|d D |jjfdd|d D dd|_fdd|d D fdd|d D | }dgtt|jjdd }dd t|dd |d	d D }|rd	nd}d}td }|dkrd}d}n|\}}|||  t }|g|gt  |g }t|}|j}tj||fd}tjd|d| d||dgd }g }d}tD ]\}}|d	 } |dkrz||| df }!|!}n|j|| df |d!}!||! tD ]B\}"}#||" \}$}%|!jt|$|%d|j||$|%f d"|" d# q|td	 k r|!j ddddd$ |!!d% |r$|!"d& |!j#d' $d |!j#d( $d |!j#d) $d |!%d |!& \}&}'t'|'}'|!(|'g |!j)t*|'gd'd(d* |!j#d+ +d, |!j d-d.dddd/ddd0d1	 |!j,|dd2d+d)d3 |!j-.d4d" qF|!/d|% |!j d5ddd6 tj0dd	||d	 df d	d	gd7}(||(d	 })t1|)|jd)d8\}*}+},}-}.|j|d	ddf |d!}/t|jjjdddd }0|/j2|0dd	d9d:d; |/3d< |/4dd	 |r|j|d |d!}1t5|1 ||d(|+d= |dk	rft|dkrf||d	dd	f }2g }3t|D ](\}}4|3|g|4d	 d	 |4d   7 }3q|2j6t7|3gjd>|-|.d? |23d< ||)d@}5|r~|1|5dA< |dk	rt|dkr|2|5dB< tj8dC|
|dD |
dkrt9j:n|
}
|
s|5S dS )Ea      In this type of plot each var_name is plotted as a filled line plot where the
    y values correspond to the var_name values and x is each of the cells. Best results
    are obtained when using raw counts that are not log.

    `groupby` is required to sort and order the values using the respective group
    and should be a categorical value.

    Parameters
    ----------
    {common_plot_args}
    {show_save_ax}
    **kwds
        Are passed to :func:`~seaborn.heatmap`.

    Returns
    -------
    A list of :class:`~matplotlib.axes.Axes`.

    Examples
    --------
    >>> import scanpy as sc
    >>> adata = sc.datasets.pbmc68k_reduced()
    >>> markers = ['C1QA', 'PSAP', 'CD79A', 'CD79B', 'CST3', 'LYZ']
    >>> sc.pl.tracksplot(adata, markers, 'bulk_labels', dendrogram=True)

    Using var_names as dict:

    >>> markers = {{'T-cell': 'CD3D', 'B-cell': 'CD79A', 'myeloid': 'CST3'}}
    >>> sc.pl.heatmap(adata, markers, groupby='bulk_labels', dendrogram=True)

    .. currentmodule:: scanpy

    See also
    --------
    pl.rank_genes_groups_tracksplot: to plot marker genes identified using the :func:`~scanpy.tl.rank_genes_groups` function.
    categoryz@groupby has to be a valid categorical observation. Given value: z", valid categorical observations: c                    s"   g | ]} j | jjd kr|qS )r  )rh   r   r^   r5  r[   r\   r`   ry     s      ztracksplot.<locals>.<listcomp>Nr1  r  r$   )'_set_default_colors_for_categorical_obsr3  r4  c                    s   g | ]} | qS r\   r\   r5  r6  r\   r`   ry     s     c                    s   g | ]} | qS r\   r\   r5  r7  r\   r`   ry     s     r8  Tr9  c                    s   g | ]} | qS r\   r\   r5  r7  r\   r`   ry     s     c                    s   g | ]} | qS r\   r\   r5  r:  r\   r`   ry     s    r   FrO  c                 S   s   g | ]\}}||fqS r\   r\   )r]   rA   rB   r\   r\   r`   ry     s     r   gQ?r      r]  r   g      ?r\  )r   r   r   rA  rB  r@  rV  r   )rR  rC   )rL  labeltopr   r   r{   r   r   r   r   havar6   )r  g)\(?rB   zx-smallbothin)	r   rI  r6   r   r_  which
labelrightrG  	directionrH  )r   r   r  r  g{GztrA   r^  subplot_specrB  rM  r}   z--)rR  Z	linestylerb  )rU  rN  rT  rD  r`  )Z
track_axesrd  re  rf  
tracksplotr   );r   rh   r   r^   rg   rh  ri  rl   r%   r  rm  rn  re   ro  rp  r   r   rz  r{  r  r   r   rj   r   r   r   r   r   rq  r   Zfill_betweenr   r  r   r  spinesset_visibleru  get_ylimr   r~  r  r   Zset_positionr   yaxisZset_label_coordsrt  GridSpecFromSubplotSpecry  r  r   rs  r|  rr  r   r   r   r   )6r@   r   r   rD   r   r%  r&  r'  r(  rv   rW   rX   r   r  r  r  r  rz  Zx_valuesr  r  num_rowsr   Ztrack_heightr  rB  r  rn   Zaxs_listZfirst_axr  rd   Zax_idxrY   Zcat_idxr  Zx_startZx_endyminymaxaxs2rd  r  rT  r   r  r0  Z
overlay_axr  r  rf  r  r   r  r\   )r@   r   r;  r   r`   r  W  sF   7   




$






      
	"   

r  r   )rU  rN  remove_labelsrW   rX   rY   )r   r   r   r6   )r@   r   rU  rN  r  rW   rX   rY   c          	      C   s<   |dkrt  \}}t|| ||||d tjd||d |S )u      Plots a dendrogram of the categories defined in `groupby`.

    See :func:`~scanpy.tl.dendrogram`.

    Parameters
    ----------
    adata
        Annotated data matrix.
    groupby
        Categorical data column used to create the dendrogram
    dendrogram_key
        Key under with the dendrogram information was stored.
        By default the dendrogram information is stored under
        `.uns[f'dendrogram_{{groupby}}']`.
    orientation
        Origin of the tree. Will grow into the opposite direction.
    remove_labels
        Don’t draw labels. Used e.g. by :func:`scanpy.pl.matrixplot`
        to annotate matrix columns/rows.
    {show_save_ax}

    Returns
    -------
    :class:`matplotlib.axes.Axes`

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

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

    .. currentmodule:: scanpy

    N)rU  r  rN  r%  r   )r   Zsubplotsr|  r%   r   )	r@   r   rU  rN  r  rW   rX   rY   rx   r\   r\   r`   r%  Q  s    3r%  )r=   r!  )r@   r   show_correlation_numbersr%  r   rW   rX   rY   r-  r.  r/  r0  returnc           "      K   s  t | ||}| j| d }| j| d }|dkr8|dk}|r|dk	rLtdt||jd ksbt||ddf }|dd|f }t| j| jj	}t
|d| }n| j| jj	}|jd }d}|rd}nd}|dkr|d	 }|| }|| }n|\}}|| }|dkr tj||fd
nd}tjdd||g||gddd}g }|dkr^||d n|}|r|j|d |d}t|| ||ddt
|jd d d || d|kr|jd dkrd|d< nd|d< |dd |	dkr|dkr|dkrd}	d}t||	|
|}d|kr(d|d< |j|fd|i|}|d| |d| |j  |t
|jd d  || |jjdd |jjdd  | t
|jd d  |j!|d!dd" d#D ]}|j"|d$ddd% q|r2t#t$|dd&D ]2\}}|j%|d |d |||f d'd(d(d) q|| |dkrz||d* } tj&|| d+d,}!|!j'(d- ||  |dkrt)j*n|}t+j,d||d. |dkr|s|S dS )/a      Plots the correlation matrix computed as part of `sc.tl.dendrogram`.

    Parameters
    ----------
    adata
    groupby
        Categorical data column used to create the dendrogram
    show_correlation_numbers
        If `show_correlation=True`, plot the correlation on top of each cell.
    dendrogram
        If True or a valid dendrogram key, a dendrogram based on the
        hierarchical clustering between the `groupby` categories is added.
        The dendrogram is computed using :func:`scanpy.tl.dendrogram`.
        If `tl.dendrogram` has not been called previously,
        the function is called with default parameters.
    figsize
        By default a figure size that aims to produce a squared correlation
        matrix plot is used. Format is (width, height)
    {show_save_ax}
    {vminmax}
    **kwds
        Only if `show_correlation` is True:
        Are passed to :func:`matplotlib.pyplot.pcolormesh` when plotting the
        correlation heatmap. `cmap` can be used to change the color palette.

    Returns
    -------

    Examples
    --------
    >>> import scanpy as sc
    >>> adata = sc.datasets.pbmc68k_reduced()
    >>> sc.tl.dendrogram(adata, 'bulk_labels')
    >>> sc.pl.correlation_matrix(adata, 'bulk_labels')
    r8  correlation_matrixNz5Can only plot dendrogram when not plotting to an axisr   r   r   g?333333?r   r   r   g?)r   r   r@  rB  r   rA  r$   rS  Tr   r}   )rU  r  rN  rT  r   r   r1   r   r   r   ra  Zbwrr0  )r  F)rL  -   )r   r  Zxyr  )r   r  r   r   )repeatz.2fr8   r  rq   
horizontal)caxrN  Zfacer   )-_get_dendrogram_keyrl   rg   r   r   AssertionErrorr   rh   r   r   r   r   r   r   r   r   r   rq  r|  r   r   r  r)   Z
pcolormeshrt  rs  r  Z
tick_rightr~  r  ZxaxisZset_tick_paramsrv  rw  r  r   r   r   r   ZsolidsZset_edgecolorr   r   r%   r   )"r@   r   r  r%  r   rW   rX   rY   r-  r.  r/  r0  r  rU  re   Zcorr_matrixr   r  Zcolorbar_heightZdendrogram_widthZcorr_matrix_heightr  r   r  r   rn   Zcorr_matrix_axr  Zimg_matZax_namerowr
  Zcolormap_axZcobarr\   r\   r`   r    s    5

		









r  )r@   r   r   rD   r   r$  r&  c                    s  t |  t| |}|dk	rd}t|tr.|g}d}|dk	rt|trJ|g}|D ]}	|	t|  | jjjg kr| jjjdk	rd| jjj d}
nd}
t	d|	 d|   |
 |	| j
 kr|	| jjjkrt	d|	 d	|	| jjjkrN|	}qN|dk	r| }|| t|tt| }tj| ||||d
 tt|t jksXt|dk	rx jdd || |dkrttdt d}nt|dkrt |d  rt |d  |}nt|dkr |d  d}|d |_nv | jdjddd}d||_ddl m!} dd t"| fdd|D  D |j#$t%|j#j&fddd} | '|  jj&}|rt(  | fS )aU  
    Given the anndata object, prepares a data frame in which the row index are the categories
    defined by group by and the columns correspond to var_names.

    Parameters
    ----------
    adata
        Annotated data matrix.
    var_names
        `var_names` should be a valid subset of  `adata.var_names`.
    groupby
        The key of the observation grouping to consider. It is expected that
        groupby is a categorical. If groupby is not a categorical observation,
        it would be subdivided into `num_categories`.
    use_raw
        Whether to use `raw` attribute of `adata`. Defaults to `True` if `.raw` is present.
    log
        Use the log of the values.
    layer
        AnnData layer to use. Takes precedence over `use_raw`
    num_categories
        Only used if groupby observation is not categorical. This value
        determines the number of groups into which the groupby observation
        should be subdivided.
    gene_symbols
        Key for field in .var that stores gene symbols.

    Returns
    -------
    Tuple of `pandas.DataFrame` and list of categories.
    NFz or index name ""r{   z-groupby has to be a valid observation. Given z, is not in observations: zGiven group z: is both and index and a column level, which is ambiguous.)ri   rv   rD   r&  T)Zinplacer  r$   r   rx   r   r   c                 S   s   i | ]\}}d  ||qS )rx   )join)r]   r  kr\   r\   r`   ra     s    z&_prepare_dataframe.<locals>.<dictcomp>c                 3   s   | ]} | j jV  qd S N)r   r   )r]   r   )r  r\   r`   	<genexpr>  s     z%_prepare_dataframe.<locals>.<genexpr>c                    s    |  S r  r\   )rA   )r  r\   r`   <lambda>      z$_prepare_dataframe.<locals>.<lambda>)r   ))r    r"   r   r   r   r   rh   re   r^   rg   ri   copyremover   uniquer   r  allr   r   r  Zreset_indexr   r  ZSeriesr  r   r   r   r  applyr  	itertoolsr   r   r   ro  sortedr   Z	set_indexlog1p)r@   r   r   rD   r   r$  rv   r&  Zgroupby_indexgroupmsgri   r   r   r   r\   )r  r  r`   ri  :  s    *





    "


 
ri  rW  r  )r   r6   )rf  rX  rY  rZ  r[  r   rN  c                    s   ddl m} ddlm}  fdd|D }	fdd|D }
g }g }|dkr^|dkrz|rztdd |D d	krvd
}nd}tt|	D ]}||	| df ||	| df ||
| df ||
| df ||j ||j	 ||j	 ||j	 z>|	| t
|
| |	|  d  }| j|d|| dd|d W q tk
rV   Y qX qnD|	}|
}tt|D ],}|d|| f |d|| f |d|| f |d|| f ||j ||j	 ||j	 ||j	 zz|| ||  }|| t
|d  }|d t|| k rL|| dt|d  d ||< | jd||| ddddd W n2 tk
r } ztd| W 5 d}~X Y nX qr|||}|j|ddd}| | | d | d | jdddd | jddddd  dS )!au      Draws brackets that represent groups of genes on the give axis.
    For best results, this axis is located on top of an image whose
    x axis contains gene names.

    The gene_groups_ax should share the x axis with the main ax.

    Eg: gene_groups_ax = fig.add_subplot(axs[0, 0], sharex=dot_ax)

    This function is used by dotplot, heatmap etc.

    Parameters
    ----------
    gene_groups_ax
        In this axis the gene marks are drawn
    group_positions
        Each item in the list, should contain the start and end position that the
        bracket should cover.
        Eg. [(0, 4), (5, 8)] means that there are two brackets, one for the var_names (eg genes)
        in positions 0-4 and other for positions 5-8
    group_labels
        List of group labels
    left_adjustment
        adjustment to plot the bracket start slightly before or after the first gene position.
        If the value is negative the start is moved before.
    right_adjustment
        adjustment to plot the bracket end slightly before or after the last gene position
        If the value is negative the start is moved before.
    rotation
        rotation degrees for the labels. If not given, small labels (<4 characters) are not
        rotated, otherwise, they are rotated 90 degrees
    orientation
        location of the brackets. Either `top` or `right`
    Returns
    -------
    None
    r   N)Pathc                    s   g | ]}|d    qS )r   r\   r5  )rZ  r\   r`   ry     s     z._plot_gene_groups_brackets.<locals>.<listcomp>c                    s   g | ]}|d    qS r   r\   r5  )r[  r\   r`   ry     s     r   c                 S   s   g | ]}t |qS r\   )r   r5  r\   r\   r`   ry     s     r?  rJ  r  r   g?r8   r   )r  r  r   r>  rs   r6   i  rH  )r  r  r   r   zproblems {}r1   g      ?)Z	facecolorrR  Frb  rB   rF  rA   )r   r   rL  r  )Zmatplotlib.patchespatchesZmatplotlib.pathr  r   r   r   r   ZMOVETOZLINETOfloatr   	Exceptionr   printformatZ	PathPatchZ	add_patchru  r   r  )rf  rX  rY  rZ  r[  r   rN  r  r  r   r6   Zvertscodesr  Zgroup_x_centerr   r   diffZgroup_y_centerepathpatchr\   )rZ  r[  r`   r}    s    .
 
 
	



   r}  r[   c                    s  t | ||}t|tr|g}| j| }||d krLtd| d|d  d|dkrf| j|d  jj}|d }	|d }
t|t|	krtdt|	 d	|d
t| d dk	rt	t
t }|rt|t|krxg }g }d}g }|
D ]~}||}|| } |d |d d  }|t
|d |d d  |||t| d f |t|7 }|||  q|}|}ntdt| dt|  nd}|dk	r fdd|D }nd}t|	|d ||||dS )a#      Function used by plotting functions that need to reorder the the groupby
    observations based on the dendrogram results.

    The function checks if a dendrogram has already been precomputed.
    If not, `sc.tl.dendrogram` is run with default parameters.

    The results found in `.uns[dendrogram_key]` are used to reorder
    `var_group_labels` and `var_group_positions`.


    Returns
    -------
    dictionary with keys:
    'categories_idx_ordered', 'var_group_names_idx_ordered',
    'var_group_labels', and 'var_group_positions'
    r   zaIncompatible observations. The precomputed dendrogram contains information for the observation: 'z/' while the plot is made for the observation: 'z=. Please run `sc.tl.dendrogram` using the right observation.'Nr8  categories_orderedz/Incompatible observations. Dendrogram data has z, categories but current groupby observation z
 contains z categories. Most likely the underlying groupby observation changed after the initial computation of `sc.tl.dendrogram`. Please run `sc.tl.dendrogram` again.'r   r$   zpGroups are not reordered because the `groupby` categories and the `var_group_labels` are different.
categories: z
var_group_labels: c                    s   g | ]} | qS r\   r\   r5  r6  r\   r`   ry     s     z8_reorder_categories_after_dendrogram.<locals>.<listcomp>)r8  r  r4  var_names_orderedr(  r'  )r  r   r   rl   rg   rh   r   r   r   r   r   r   re   extendr   r   r   _format_first_three_categoriesr   )r@   r   r%  r   r(  r'  r   r   dendro_infor8  r  r4  Zpositions_orderedZlabels_orderedZposition_startZcat_namer  position
_var_namesr  r\   r6  r`   rm  ;  sf    




rm  c                 C   s0   t | } t| dkr&| d d dg } d| S )Nrq   zetc.z, )r   r   r  r7  r\   r\   r`   r    s    r  c                 C   s   t |ts:t |tr d| }nt |tr:dd| }|| jkrpddlm} td| d || ||d d| j| krt	d	|d
|S )NZdendrogram_rx   r   )r%  z%dendrogram data not found (using key=z). Running `sc.tl.dendrogram` with default parameters. For fine tuning it is recommended to run `sc.tl.dendrogram` independently.)Z	key_addeddendrogram_infozThe given dendrogram key (z0) does not contain valid dendrogram information.)
r   r   r   r  rl   Ztools._dendrogramr%  r   r   rg   )r@   rU  r   r%  r\   r\   r`   r    s     





r  )r  r@   r   rU  rN  r  rT  c                 C   s  t |||}dd }|j| d }|d }	t|d }
t|d }tdt|	d d dt}|d	k	rt|t|krt	d
 d	}t
|
|D ]>\}}|d	k	r||||}|dkr|| }}| j||dd q| jddddd |d	k	r|n|}|dkr\| | | j|	ddd | jddd |dkr|  \}}| || | jddd nX| | | j|	ddd | jddd |dkr|  \}}| || | jddd |r| jddddd | d | jd d | jd d | jd d | jd d d	S )z}    Plots a dendrogram on the given ax using the precomputed dendrogram
    information stored in `.uns[dendrogram_key]`
    c                 S   s   t |ts| }g }| D ]z}||kr6||| }nTtj||dd}|d }|| }|| }	|| }
|| }|| |	|  ||
  |
 }|| q|S )a          transforms the dendrogram coordinates to a given new position.
        The xlabel_pos and orig_ticks should be of the same
        length.

        This is mostly done for the heatmap case, where the position of the
        dendrogram leaves needs to be adjusted depending on the category size.

        Parameters
        ----------
        pos_list
            list of dendrogram positions that should be translated
        new_ticks
            sorted list of goal tick positions (e.g. [0,1,2,3] )
        old_ticks
            sorted list of original tick positions (e.g. [5, 15, 25, 35]),
            This list is usually the default position used by
            `scipy.cluster.hierarchy.dendrogram`.

        Returns
        -------
        translated list of positions

        Examples
        --------
        >>> translate_pos(
        ...     [5, 15, 20, 21],
        ...     [0,  1,  2, 3 ],
        ...     [5, 15, 25, 35],
        ... )
        [0, 1, 1.5, 1.6]
        r   )Zsider$   )r   r   tolistre   r   Zsearchsortedr   )Zpos_listZ	new_ticksZ	old_ticksZnew_xsZx_valZ	new_x_valZidx_nextZidx_prevZold_minZold_maxZnew_minZnew_maxr\   r\   r`   translate_pos  s&    #
z'_plot_dendrogram.<locals>.translate_posr  Zivlicoorddcoordr   rQ  NzVticks argument does not have the same size as orig_ticks. The argument will be ignored)r6   r   z#555555)rC   F)r   r   r   r6   rH  r   )r   r   )rL  r  r   T)rG  r  rJ  r   )r  rL  )rL  r  rG  r  r6   r   )r  rl   r   r   r   r   r   r  r   r   r  Zplotr  r~  r  Zget_xlimrt  rv  rw  r  rs  ru  r  r  )r  r@   r   rU  rN  r  rT  r  r  leavesr  r  Z
orig_ticksZxsr  ZxminZxmaxr  r  r\   r\   r`   r|    s^    8 





   
r|  r   tab20)rd  r  rN  	cmap_namec                    sn  |j j}ddlm}m} |dkr,t|}n|||d }|t|j	d d |j	}	d}
g }g }i  t
|j jdd D ]8\}\}}||
|d	   || |
|7 }
| |< q|| d |d
kr| jt fdd|j D gjd||	d t|dkr| | | | | jdddd | jdddd | jd d | jd d | jd
 d | jd d | | n| jt fdd|j D gd||	d t|dkr| | tdd |D dk rd}nd}| j||d | jdddd | jdddd | jd d | jd d | jd
 d | jd d | |  ||||	fS )a      Plots categories as colored blocks. If orientation is 'left', the categories
    are plotted vertically, otherwise they are plotted horizontally.

    Parameters
    ----------
    groupby_ax
    obs_tidy
    colors
        Sequence of valid color names to use for each category.
    orientation
    cmap_name
        Name of colormap to use, in case colors is None

    Returns
    -------
    ticks position, labels, colormap
    r   )r   BoundaryNormNZ_cmapr$   r}   FrO  r   r   c                    s   g | ]} | qS r\   r\   r]   Zlabr  r\   r`   ry   y	  s     z3_plot_categories_as_colorblocks.<locals>.<listcomp>rD  r`  rB   rH  )r   r   rI  rA   r^  r6   r   r   c                    s   g | ]} | qS r\   r\   r  r  r\   r`   ry   	  s     c                 S   s   g | ]}t t|qS r\   )r   r   r5  r\   r\   r`   ry   	  s     rq   rJ  rK  )r   r   rI  rF  )re   r^   matplotlib.colorsr   r  r   Zget_cmapr   r   Nr   r{  rk   r   ru  rr  r   rj   r   r~  r  r  r  r  r   rv  r   rw  r   )rd  r  r   rN  r  r   r   r  r  r0  Z	value_sumrT  r   coder  r  r   r\   r  r`   ry  D	  sn    







ry        @)max_cbar_heightc                 C   sZ   |  \}}||kr>tjdd||| |gd}||d }n
||}tj| |d |S )a  
    Plots a vertical color bar based on mappable.
    The height of the colorbar is min(figure-height, max_cmap_height)

    Parameters
    ----------
    mappable
        The image to which the colorbar applies.
    fig
        The figure object
    subplot_spec
        The gridspec subplot. Eg. axs[1,2]
    max_cbar_height
        The maximum colorbar height

    Returns
    -------
    color bar ax
    r   r$   r  )r  )Zget_size_inchesr   r  rq  r   r   )Zmappabler  r  r  r   r  r  Zheatmap_cbar_axr\   r\   r`   rx  	  s    

rx  c                 C   s   t | tjr|dk	s|dk	r&td g }g }g }d}|  D ]V\}}t |trV|g}|t| |	| |	||t
| d f |t
|7 }q>|} nt | tr| g} | ||fS )z
    checks if var_names is a dict. Is this is the cases, then set the
    correct values for var_group_labels and var_group_positions

    Returns
    -------
    var_names, var_group_labels, var_group_positions

    Nzo`var_names` is a dictionary. This will reset the current value of `var_group_labels` and `var_group_positions`.r   r$   )r   r   r   r   r   rk   r   r  r   r   r   )r   r(  r'  r  startr  Z	vars_listr\   r\   r`   rh  	  s(    



rh  )NNNNNTNNNNr>   r2   NNNNNNNNNNNNN)NNNNNTNNNNr>   r2   NNNNNNNNNNNNN)NNNr   r   FFN)NFNTTr$   Nr   NNr{   NNNNN)NNNN)NFr#  FNNNNNNFNNNNNNNN)
NFFNNNNNNN)
FNNNNNNNNN)NNFr#  NN)rW  r  Nr   )NNNN)Nr6   TN)Nr   r  )r  )]__doc__collections.abcabcr   r  r   collectionsr   typingr   r   r   r   r	   r
   r   r   numpyr   Zpandasr  Zanndatar   Zcyclerr   Zmatplotlib.axesr   Zpandas.api.typesr   r   r   r   Z
matplotlibr   r   r   r   r   r  r   r   r   r   r{   r   r   r   Z	_settingsr   r%   r    r!   r"   Z_compatr#   r&   r'   r(   r)   r*   r+   r,   Z_docsr-   r.   r/   r0   r   Z_Basisr   Z	_VarNamesr   r  r   ro   rf   r   r  r  rg  r  r%  r  ri  r}  rm  r  r  r|  r  ry  rx  rh  r\   r\   r\   r`   <module>   s  
                         
a                           d        t                

      B	                   


   
          

 z@
           +      ~         i     
    j%