U
    ¹mœdá6  ã                   @   s”   d Z ddlZddlmZ ddlZddlmZ ddddd	d
gZeddd�dd„ ƒZ	eddd�dd„ ƒZ
dd
„ Zdd„ Zdd	„ Zddd„Zddd„ZdS )aÈ  
*****
Pydot
*****

Import and export NetworkX graphs in Graphviz dot format using pydot.

Either this module or nx_agraph can be used to interface with graphviz.

Examples
--------
>>> G = nx.complete_graph(5)
>>> PG = nx.nx_pydot.to_pydot(G)
>>> H = nx.nx_pydot.from_pydot(PG)

See Also
--------
 - pydot:         https://github.com/erocarrera/pydot
 - Graphviz:      https://www.graphviz.org
 - DOT Language:  http://www.graphviz.org/doc/info/lang.html
é    N)Úgetpreferredencoding)Ú	open_fileÚ	write_dotÚread_dotÚgraphviz_layoutÚpydot_layoutÚto_pydotÚ
from_pydoté   Úw)Úmodec                 C   s.   d}t j|tdd� t| ƒ}| | ¡ ¡ dS )zgWrite NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    zÍnx.nx_pydot.write_dot depends on the pydot package, which hasknown issues and is not actively maintained. Consider usingnx.nx_agraph.write_dot instead.

See https://github.com/networkx/networkx/issues/5723é   ©Ú
stacklevelN)ÚwarningsÚwarnÚDeprecationWarningr   ÚwriteZ	to_string)ÚGÚpathÚmsgÚP© r   úR/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/networkx/drawing/nx_pydot.pyr   &   s    ÿÚrc                 C   s:   ddl }d}tj|tdd� |  ¡ }| |¡}t|d ƒS )aO  Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
    dot file with the passed path.

    If this file contains multiple graphs, only the first such graph is
    returned. All graphs _except_ the first are silently ignored.

    Parameters
    ----------
    path : str or file
        Filename or file handle.

    Returns
    -------
    G : MultiGraph or MultiDiGraph
        A :class:`MultiGraph` or :class:`MultiDiGraph`.

    Notes
    -----
    Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
    :class:`MultiGraph`.
    r   NzËnx.nx_pydot.read_dot depends on the pydot package, which hasknown issues and is not actively maintained. Consider usingnx.nx_agraph.read_dot instead.

See https://github.com/networkx/networkx/issues/5723r   r   )Úpydotr   r   r   ÚreadÚgraph_from_dot_datar	   )r   r   r   ÚdataZP_listr   r   r   r   8   s    ÿ
c              	   C   s  d}t j|tdd� |  d¡r$d}nd}|  ¡ dkrL|rBt ¡ }qbt ¡ }n|rZt ¡ }nt 	¡ }|  
¡  d¡}|d	kr~||_|  ¡ D ].}| 
¡  d¡}|d
kr¢q†|j|f| ¡ Ž q†|  ¡ D ]Æ}| ¡ }| ¡ }	| ¡ }
g }g }t|tƒrþ| | d¡¡ n |d D ]}| | d¡¡ �qt|	tƒ�r<| |	 d¡¡ n |	d D ]}| | d¡¡ �qD|D ]"}|D ]}|j||f|
Ž �qh�q`q¾|  ¡ }|�rž||jd< z|  ¡ d |jd< W n ttfk
�rÎ   Y nX z|  ¡ d |jd< W n ttfk
�r    Y nX |S )aØ  Returns a NetworkX graph from a Pydot graph.

    Parameters
    ----------
    P : Pydot graph
      A graph created with Pydot

    Returns
    -------
    G : NetworkX multigraph
        A MultiGraph or MultiDiGraph.

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> A = nx.nx_pydot.to_pydot(K5)
    >>> G = nx.nx_pydot.from_pydot(A)  # return MultiGraph

    # make a Graph instead of MultiGraph
    >>> G = nx.Graph(nx.nx_pydot.from_pydot(A))

    z nx.nx_pydot.from_pydot depends on the pydot package, which hasknown issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   NFTÚgraphú"Ú )Únoder   ÚedgeÚnodesr   r"   r#   )r   r   r   Z
get_strictÚget_typeÚnxZ
MultiGraphZGraphZMultiDiGraphZDiGraphÚget_nameÚstripÚnameZget_node_listÚadd_nodeZget_attributesZget_edge_listÚ
get_sourceZget_destinationÚ
isinstanceÚstrÚappendÚadd_edger   Zget_node_defaultsÚ
IndexErrorÚ	TypeErrorZget_edge_defaults)r   r   Z
multiedgesÚNr)   ÚpÚnÚeÚuÚvÚattrÚsÚdZunodesZvnodesZsource_nodeZdestination_nodeZpattrr   r   r   r	   b   sd    ÿ





c                 C   s    d| ko| d dkp| d dkS )Nú:r   r    éÿÿÿÿr   )r9   r   r   r   Ú_check_colon_quotesÃ   s    r=   c                 C   sª  ddl }d}tj|tdd� |  ¡ r*d}nd}t | ¡dkoD|  ¡  }| j}| j	 
di ¡}|dkrz|jd||d	œ|—Ž}n |jd
|› d
�f||d	œ|—Ž}z|jf | j	d Ž W n tk
rÄ   Y nX z|jf | j	d Ž W n tk
rð   Y nX | jdd�D ]j\}}	dd„ |	 ¡ D ƒ}
t|ƒ}t|ƒ�p>tdd„ |
 ¡ D ƒƒ}|�rNtdƒ‚|j|f|
Ž}| |¡ � qþ|  ¡ �r| jddd�D ]�\}}}}dd„ | ¡ D ƒ}t|ƒt|ƒ }}t|ƒ�pÚt|ƒ�pÚtdd„ | ¡ D ƒƒ}|�rêtdƒ‚|j||fdt|ƒi|—Ž}| |¡ �q‚n�| jdd�D ]‚\}}}dd„ | ¡ D ƒ}t|ƒt|ƒ }}t|ƒ�pxt|ƒ�pxtdd„ | ¡ D ƒƒ}|�rˆtdƒ‚|j||f|Ž}| |¡ �q"|S )a  Returns a pydot graph from a NetworkX graph N.

    Parameters
    ----------
    N : NetworkX graph
      A graph created with NetworkX

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> P = nx.nx_pydot.to_pydot(K5)

    Notes
    -----

    r   Nzžnx.nx_pydot.to_pydot depends on the pydot package, which hasknown issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   Zdigraphr   r!   )Ú
graph_typeÚstrictr    r"   r#   T)r   c                 S   s   i | ]\}}t |ƒt |ƒ“qS r   ©r-   ©Ú.0Úkr7   r   r   r   Ú
<dictcomp>ý   s      zto_pydot.<locals>.<dictcomp>c                 s   s"   | ]\}}t |ƒpt |ƒV  qd S ©N©r=   rA   r   r   r   Ú	<genexpr>  s   ÿzto_pydot.<locals>.<genexpr>zøNode names and attributes should not contain ":" unless they are quoted with "".                For example the string 'attribute:data1' should be written as '"attribute:data1"'.                Please refer https://github.com/pydot/pydot/issues/258)r   Úkeysc                 S   s&   i | ]\}}|d krt |ƒt |ƒ“qS )Úkeyr@   rA   r   r   r   rD     s       c                 s   s"   | ]\}}t |ƒpt |ƒV  qd S rE   rF   ©rB   rC   Úvalr   r   r   rG     s   ÿa   Node names and attributes should not contain ":" unless they are quoted with "".                    For example the string 'attribute:data1' should be written as '"attribute:data1"'.                    Please refer https://github.com/pydot/pydot/issues/258rI   c                 S   s   i | ]\}}t |ƒt |ƒ“qS r   r@   rA   r   r   r   rD   (  s      c                 s   s"   | ]\}}t |ƒpt |ƒV  qd S rE   rF   rJ   r   r   r   rG   .  s   ÿ)r!   )r   r   r   r   Zis_directedr&   Znumber_of_selfloopsZis_multigraphr)   r   ÚgetZDotZset_node_defaultsÚKeyErrorZset_edge_defaultsr$   Úitemsr-   r=   ÚanyÚ
ValueErrorÚNoder*   ÚedgesÚEdger/   )r2   r   r   r>   r?   r)   Zgraph_defaultsr   r4   ZnodedataZstr_nodedataZraise_errorr3   r6   r7   rI   ZedgedataZstr_edgedatar#   r   r   r   r   Ê   s˜    ÿ
ÿ ÿÿ
þÿÿ

ÿþü
ÿ
ÿþü
ÿÚneatoc                 C   s"   d}t j|tdd� t| ||d�S )a=  Create node positions using Pydot and Graphviz.

    Returns a dictionary of positions keyed by node.

    Parameters
    ----------
    G : NetworkX Graph
        The graph for which the layout is computed.
    prog : string (default: 'neato')
        The name of the GraphViz program to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
      Dictionary of (x, y) positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.graphviz_layout(G)
    >>> pos = nx.nx_pydot.graphviz_layout(G, prog="dot")

    Notes
    -----
    This is a wrapper for pydot_layout.
    zÙnx.nx_pydot.graphviz_layout depends on the pydot package, which hasknown issues and is not actively maintained. Consider usingnx.nx_agraph.graphviz_layout instead.

See https://github.com/networkx/networkx/issues/5723r   r   )r   ÚprogÚroot)r   r   r   r   )r   rU   rV   r   r   r   r   r   ?  s    ÿc                 C   sV  ddl }d}tj|tdd� t| ƒ}|dk	r<| dt|ƒ¡ |j|d�}t|tƒ d�}|d	kr t	d
|› d�ƒ t	ƒ  t	dƒ t	dƒ t	dƒ t	d|› d�ƒ dS | 
|¡}t|ƒdksºt‚|d }	i }
|  ¡ D ]‚}t|ƒ}t|ƒrêtdƒ‚| |¡ ¡ }|	 |¡}t|tƒ�r|d }| ¡ dd… }|dk	rÎ| d¡\}}t|ƒt|ƒf|
|< qÎ|
S )aô  Create node positions using :mod:`pydot` and Graphviz.

    Parameters
    ----------
    G : Graph
        NetworkX graph to be laid out.
    prog : string  (default: 'neato')
        Name of the GraphViz command to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
    dict
        Dictionary of positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.pydot_layout(G)
    >>> pos = nx.nx_pydot.pydot_layout(G, prog="dot")

    Notes
    -----
    If you use complex node objects, they may have the same string
    representation and GraphViz could treat them as the same node.
    The layout may assign both nodes a single location. See Issue #1568
    If this occurs in your case, consider relabeling the nodes just
    for the layout computation using something similar to::

        H = nx.convert_node_labels_to_integers(G, label_attribute='node_label')
        H_layout = nx.nx_pydot.pydot_layout(G, prog='dot')
        G_layout = {H.nodes[n]['node_label']: p for n, p in H_layout.items()}

    r   Nz¢nx.nx_pydot.pydot_layout depends on the pydot package, which hasknown issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   rV   )rU   )Úencodingr!   zGraphviz layout with z failedzTo debug what happened try:zP = nx.nx_pydot.to_pydot(G)zP.write_dot("file.dot")zAnd then run z on file.dotr
   zýNode names and node attributes should not contain ":" unless they are quoted with "".                For example the string 'attribute:data1' should be written as '"attribute:data1"'.                Please refer https://github.com/pydot/pydot/issues/258r<   ú,)r   r   r   r   r   Úsetr-   Z
create_dotr   Úprintr   ÚlenÚAssertionErrorr$   r=   rP   rQ   r'   Zget_noder,   ÚlistZget_posÚsplitÚfloat)r   rU   rV   r   r   r   ZD_bytesÚDZQ_listÚQZnode_posr4   Zstr_nZ
pydot_noder"   ÚposZxxÚyyr   r   r   r   h  sH    &ÿ
ÿ
)rT   N)rT   N)Ú__doc__r   Úlocaler   Znetworkxr&   Znetworkx.utilsr   Ú__all__r   r   r	   r=   r   r   r   r   r   r   r   Ú<module>   s(   ú




)au
)