o
    RŀgT                     @   sV   d Z ddlZddlZddlmZ dd ZdddZdd
dZedddddfddZ	dS )zUtilities for handling, displaying and exporting Phylo trees.

Third-party libraries are loaded when the corresponding function is called.
    N)MissingPythonDependencyErrorc                    s   zddl }W n ty   tddw |jdkrdd  n|jdkr'dd  nd	d   fd
d| jr:| }n| }|| j || j |S )a.  Convert a Tree object to a networkx graph.

    The result is useful for graph-oriented analysis, and also interactive
    plotting with pylab, matplotlib or pygraphviz, though the resulting diagram
    is usually not ideal for displaying a phylogeny.

    Requires NetworkX version 0.99 or later.
    r   Nz0Install NetworkX if you want to use to_networkx.z1.0c                 S   s   | j |||jpdd t|dr!|jd ur!|j | | | d< nt|dr:|jd ur:|j | | | d< |j|_t|drO|jd urO|j| | | d< d S t|drh|jd urj|j| | | d< |j|_d S d S d S )N      ?)weightcolorwidth)add_edgebranch_lengthhasattrr   to_hexr   graphn1n2 r   D/var/www/html/myenv/lib/python3.10/site-packages/Bio/Phylo/_utils.pyr   *   s   zto_networkx.<locals>.add_edgez0.99c                 S   s   |  |||jpd d S )Nr   )r   r   r   r   r   r   r   =   s   c                 S   s   |  || d S N)r   r   r   r   r   r   B   s   c                    s4   |D ]}|  |j  | |j|j | | qdS )z5Walk down the Tree, building graphs, edges and nodes.N)add_noderoot)r   topclader   build_subgraphr   r   r   E   s
   z#to_networkx.<locals>.build_subgraph)	networkxImportErrorr   __version__rootedDiGraphGraphr   r   )treer   Gr   r   r   to_networkx   s*   	





r    r   r   c           	         s  zddl }W n ty   tddw |jdk rtdtdd |  D dkr/| S  fdd	 g }|du r>d
}dd |D }dd |D } | jdd||| |D ]}t|| dkre||= qX|D ]}t|| dkru||= qh|j|||t	| j
d}|S )a  Convert a Tree object to an igraph Graph.

    The result is useful for graph-oriented analysis and interactive plotting
    with matplotlib, Cairo, and plotly.

    Requires python-igraph version 0.10.0 or later.

    :Parameters:
        vertex_attributes : sequence of strings
            A sequence of strings containing the Clade properties that are to
            be stored as vertex attributes, e.g. "name".
        edge_attributes : sequence of strings
            A sequence of strings containing the Clade properties that are to
            be stored as edge attributes, e.g. "color" and "width".

    In both cases, if a property is not found it will be ignored.
    r   Nz,Install igraph if you want to use to_igraph.z0.10z<Update igraph to 0.10 or later if you want to use to_igraph.c                 s   s    | ]}d V  qdS )   Nr   .0xr   r   r   	<genexpr>t   s    zto_igraph.<locals>.<genexpr>c                    s   |D ]}t | |r!t|| dkrdg ||< t| ||| |< qd}t| D ])\}}	|d | }
|d7 }|||
f |D ]}t |	|rP|| t|	| q?q(|}|| }t| D ]\}}	|d | }
 |	|
||||}q\|S )z*Add edges from this subtree, breath-first.r   Nr"   )r	   lengetattr	enumerateappend)noden_nodecounteredges
edge_attrsvertex_attrsattrnamedelta_counterichildn_childold_counteradd_subtreen_nodesr   r   r8   |   s0   

zto_igraph.<locals>.add_subtreer   c                 S      i | ]}|g qS r   r   r$   r1   r   r   r   
<dictcomp>       zto_igraph.<locals>.<dictcomp>c                 S   r:   r   r   r;   r   r   r   r<      r=   )r.   r0   r/   directed)igraphr   r   r   sumfind_cladesr   r   r'   boolr   )	r   vertex_attributesedge_attributesigr.   r/   r0   r1   r   r   r7   r   	to_igraphU   sL   
&rF   P   c           
         s  |du rt j}|  tdd D }|| d dt d }fdd}fdd	}|| || fd
dt|D   fdd| jd t D ]$\}}d|	 }	|d dkrr|	dt
|d   7 }	||	d  qU|d dS )a  Draw an ascii-art phylogram of the given tree.

    The printed result looks like::

                                        _________ Orange
                         ______________|
                        |              |______________ Tangerine
          ______________|
         |              |          _________________________ Grapefruit
        _|              |_________|
         |                        |______________ Pummelo
         |
         |__________________________________ Apple


    :Parameters:
        file : file-like object
            File handle opened for writing the output drawing. (Default:
            standard output)
        column_width : int
            Total number of text columns used by the drawing.

    Nc                 s   s    | ]	}t t|V  qd S r   )r'   str)r$   taxonr   r   r   r&      s    zdraw_ascii.<locals>.<genexpr>r"      c                    sh   |   }t| dkr| j dd}ttttd}| t|    fdd| D S )z6Create a mapping of each clade to its column position.r   Tunit_branch_lengthsrJ   c                    s"   i | ]\}}|t |  d  qS )r   )int)r$   r   blencols_per_branch_unitr   r   r<      s    z9draw_ascii.<locals>.get_col_positions.<locals>.<dictcomp>)	depthsmaxvaluesrM   mathceillogr'   items)r   rQ   fudge_margin)drawing_widthtaxarO   r   get_col_positions   s   
z%draw_ascii.<locals>.get_col_positionsc                    s.   dd t D  fdd  | j S )Nc                 S   s   i | ]	\}}|d | qS )rJ   r   )r$   idxrI   r   r   r   r<      s    z9draw_ascii.<locals>.get_row_positions.<locals>.<dictcomp>c                    sB   | D ]
}|vr | q| j d  | j d   d | < d S )Nr   rJ   cladesr   subcladecalc_row	positionsr   r   rc      s   z7draw_ascii.<locals>.get_row_positions.<locals>.calc_row)r)   r   r   )rZ   rb   r   get_row_positions   s   
z%draw_ascii.<locals>.get_row_positionsc                    s   g | ]}d d t  D qS )c                 S   s   g | ]}d qS ) r   r#   r   r   r   
<listcomp>   s    z)draw_ascii.<locals>.<listcomp>.<listcomp>)range)r$   y)rY   r   r   rh      s    zdraw_ascii.<locals>.<listcomp>c           	         s   |  }|  }t ||D ]}d | |< q| jrV| jd  }| jd  }t |d |d D ]}d | |< q0| jd  | dk rJd | |< | D ]}||d  qLd S d S )N_r   r]   r"   |rJ   ,)ri   r_   )	r   startcolthiscolthisrowcoltoprowbotrowrowr4   )char_matrixcol_positions
draw_claderow_positionsr   r   rw      s   
zdraw_ascii.<locals>.draw_clader    rg   
)sysstdoutget_terminalsrR   r'   ri   r   r)   joinrstriprH   write)
r   filecolumn_widthmax_label_widthdrawing_heightr[   rf   r\   rt   liner   )ru   rv   rw   rY   rx   rZ   r   
draw_ascii   s&   r   Tc                    s  zddl m W n ty$   zddlW n ty!   tddw Y nw ddlm
 g g dd sC|r>fddndd nttrOfd	dn
t	sWt
d
rmt	rffddnfddndd dd }	dd }
|	| |
|  du r }|ddd nt jjjstd  									d& 
fdd	 	f	dd| jddjd  D ]} | qΈD ]} | qz| j}W n	 ty   Y nw |r |  d  d  t } d!| d"|   t d# d$ | D ]`\}}zt| W n t
y;   td%||f dw t|trRtt |d'i t| q t|d t!sett ||  q t|d t!rtt ||d i t|d  q |r"  dS dS )(a
  Plot the given tree using matplotlib (or pylab).

    The graphic is a rooted tree, drawn with roughly the same algorithm as
    draw_ascii.

    Additional keyword arguments passed into this function are used as pyplot
    options. The input format should be in the form of:
    pyplot_option_name=(tuple), pyplot_option_name=(tuple, dict), or
    pyplot_option_name=(dict).

    Example using the pyplot options 'axhspan' and 'axvline'::

        from Bio import Phylo, AlignIO
        from Bio.Phylo.TreeConstruction import DistanceCalculator, DistanceTreeConstructor
        constructor = DistanceTreeConstructor()
        aln = AlignIO.read(open('TreeConstruction/msa.phy'), 'phylip')
        calculator = DistanceCalculator('identity')
        dm = calculator.get_distance(aln)
        tree = constructor.upgma(dm)
        Phylo.draw(tree, axhspan=((0.25, 7.75), {'facecolor':'0.5'}),
        ... axvline={'x':0, 'ymin':0, 'ymax':1})

    Visual aspects of the plot can also be modified using pyplot's own functions
    and objects (via pylab or matplotlib). In particular, the pyplot.rcParams
    object can be used to scale the font size (rcParams["font.size"]) and line
    width (rcParams["lines.linewidth"]).

    :Parameters:
        label_func : callable
            A function to extract a label from a node. By default this is str(),
            but you can use a different function to select another string
            associated with each node. If this function returns None for a node,
            no label will be shown for that node.
        do_show : bool
            Whether to show() the plot automatically.
        show_confidence : bool
            Whether to display confidence values, if present on the tree.
        axes : matplotlib/pylab axes
            If a valid matplotlib.axes.Axes instance, the phylogram is plotted
            in that Axes. By default (None), a new figure is created.
        branch_labels : dict or callable
            A mapping of each clade to the label that will be shown along the
            branch leading to it. By default this is the confidence value(s) of
            the clade, taken from the ``confidence`` attribute, and can be
            easily toggled off with this function's ``show_confidence`` option.
            But if you would like to alter the formatting of confidence values,
            or label the branches with something other than confidence, then use
            this option.
        label_colors : dict or callable
            A function or a dictionary specifying the color of the tip label.
            If the tip label can't be found in the dict or label_colors is
            None, the label will be shown in black.

    r   Nz4Install matplotlib or pylab if you want to use draw.c                 S   s    t | | krtt | S t| S r   )rM   rH   )confr   r   r   conf2strm  s   zdraw.<locals>.conf2strc                    sN   z| j }W n	 ty   Y nw d fdd|D S | jd ur% | jS d S )N/c                 3   s    | ]} |j V  qd S r   )value)r$   cnfr   r   r   r&   |  s    z4draw.<locals>.format_branch_label.<locals>.<genexpr>)confidencesAttributeErrorr~   
confidence)r   r   r   r   r   format_branch_labelu  s   


z!draw.<locals>.format_branch_labelc                 S   s   d S r   r   r   r   r   r   r     s   c                    s
     | S r   getr   )branch_labelsr   r   r     s   
z<branch_labels must be either a dict or a callable (function)c                    s    | S r   r   labellabel_colorsr   r   get_label_color  s   zdraw.<locals>.get_label_colorc                    s     | dS Nblackr   r   r   r   r   r     s   c                 S   s   dS r   r   r   r   r   r   r     s   c                 S   s$   |   }t| s| j dd}|S )zeCreate a mapping of each clade to its horizontal position.

        Dict of {clade: x-coord}
        TrK   )rQ   rR   rS   )r   rQ   r   r   r   get_x_positions  s   zdraw.<locals>.get_x_positionsc                    sJ   |   fddtt|  D  fdd | jjr# | j S )zCreate a mapping of each clade to its vertical position.

        Dict of {clade: y-coord}.
        Coordinates are negative, and integers for tips.
        c                    s   i | ]	\}}| | qS r   r   )r$   r3   tip)	maxheightr   r   r<     s    z1draw.<locals>.get_y_positions.<locals>.<dictcomp>c                    sB   | D ]
}|vr | q| j d  | j d   d | < d S )Nr   r]   g       @r^   r`   )rc   heightsr   r   rc     s   z/draw.<locals>.get_y_positions.<locals>.calc_row)count_terminalsr)   reversedr}   r   r_   re   r   )rc   r   r   r   get_y_positions  s   
	
zdraw.<locals>.get_y_positionsr"   zInvalid argument for axes: F
horizontalr   .1c	           	         s   | s|dkr j |||||d dS | r,|dkr,j||f||fgg||d dS | s=|dkr= j||||d dS | rW|dkrYj||f||fgg||d dS dS dS )zCreate a line with or without a line collection object.

        Graphical formatting of the lines representing clades in the plot can be
        customized by altering this function.
        r   )r   lwvertical)r   N)hlinesr*   LineCollectionvlines)	use_linecollectionorientationy_herex_startx_herey_boty_topr   r   )axeshorizontal_linecollectionsmpcollectionsvertical_linecollectionsr   r   draw_clade_lines  s"   zdraw.<locals>.draw_clade_linesc              	      s  |  }|  }t | dr| jdur| j }t | dr)| jdur)| jjd  }dd|||||d | }|d| jjfvrO j||d| d	|d
 | }|rc jd||  ||dd	d | jr| jd  }| jd  }	dd||	|||d | D ]}
|
||| qdS dS )z3Recursively draw a tree, down from the given clade.r   Nr   lines.linewidthTr   )r   r   r   r   r   r   r   rg   center)verticalalignmentr   g      ?small)fontsizehorizontalalignmentr   r]   r   )r   r   r   r   r   r   r   )	r	   r   r
   r   rcParams	__class____name__textr_   )r   r   r   r   r   r   r   
conf_labelr   r   r4   )	r   rw   r   r   r   
label_funcpltx_posnsy_posnsr   r   rw     sb   



zdraw.<locals>.draw_cladekr   zbranch lengthrZ   gg      ?g?g?zKeyword argument "%s=%s" is not in the format pyplot_option_name=(tuple), pyplot_option_name=(tuple, dict), or pyplot_option_name=(dict) )	Fr   r   r   r   r   r   r   r   r   )#matplotlib.pyplotpyplotr   pylabr   matplotlib.collectionscollections
isinstancedictcallable	TypeErrorfigureadd_subplot
matplotlibr   Axes
ValueErrorr   r   add_collectionnamer   	set_title
set_xlabel
set_ylabelrR   rS   set_xlimset_ylimrW   listr(   rH   tupleshow)r   r   do_showshow_confidencer   r   r   argskwargsr   r   figr3   r   xmaxkeyr   r   )r   r   r   rw   r   r   r   r   r   r   r   r   r   r   r   r   draw  s   B

!9



 $r   )Nr!   )NrG   )
__doc__rT   r{   Bior   r    rF   r   rH   r   r   r   r   r   <module>   s   
B
fa