ó
 ,µ[c           @   s
  d  Z  d d l m Z d d l m Z m Z d d l m Z d d l Z	 d d d d	 d
 d g Z
 d Z y e Wn e k
 r e Z e Z n Xe d d d ƒd „  ƒ Z e d d d ƒd „  ƒ Z d „  Z d „  Z d d d „ Z d d d „ Z d „  Z d „  Z d S(   sa  
*****
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.

See Also
--------
pydot:         https://github.com/erocarrera/pydot
Graphviz:      http://www.research.att.com/sw/tools/graphviz/
DOT Language:  http://www.graphviz.org/doc/info/lang.html
iÿÿÿÿ(   t   getpreferredencoding(   t	   open_filet   make_str(   t   parse_versionNt	   write_dott   read_dott   graphviz_layoutt   pydot_layoutt   to_pydott
   from_pydots   1.2.3i   t   modet   wc         C   s#   t  |  ƒ } | j | j ƒ  ƒ d S(   sg   Write NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    N(   R   t   writet	   to_string(   t   Gt   patht   P(    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR   0   s    i    t   rc         C   s2   t  ƒ  } |  j ƒ  } | j | ƒ } t | d ƒ S(   sB  Return 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(read_dot(path))` to return a :class:`Graph` instead of a
    :class:`MultiGraph`.
    i    (   t   _import_pydott   readt   graph_from_dot_dataR	   (   R   t   pydott   datat   P_list(    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR   ;   s    	c         C   sˆ  |  j  d ƒ r t } n t } |  j ƒ  d k rT | rE t j ƒ  } qu t j ƒ  } n! | ri t j ƒ  } n t j	 ƒ  } |  j
 ƒ  j d ƒ } | d k r¢ | | _ n  xQ |  j ƒ  D]C } | j
 ƒ  j d ƒ } | d	 k rÜ q¯ n  | j | | j ƒ   q¯ Wx|  j ƒ  D]} | j ƒ  } | j ƒ  } | j ƒ  }	 g  }
 g  } t | t ƒ ra|
 j | j d ƒ ƒ n+ x( | d D] } |
 j | j d ƒ ƒ qlWt | t ƒ r´| j | j d ƒ ƒ n+ x( | d D] } | j | j d ƒ ƒ q¿Wx2 |
 D]* } x! | D] } | j | | |	  qóWqæWqW|  j ƒ  } | r:| | j d <n  y |  j ƒ  d | j d <Wn n Xy |  j ƒ  d | j d <Wn n X| S(
   sÖ  Return 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))

    t   grapht   "t    t   nodet   edget   nodesi    N(   R   R   R   (   t
   get_strictt   Nonet   Falset   Truet   get_typet   nxt
   MultiGrapht   Grapht   MultiDiGrapht   DiGrapht   get_namet   stript   namet   get_node_listt   add_nodet   get_attributest   get_edge_listt
   get_sourcet   get_destinationt
   isinstancet
   basestringt   appendt   add_edgeR   t   get_node_defaultst   get_edge_defaults(   R   t
   multiedgest   NR*   t   pt   nt   et   ut   vt   attrt   st   dt   unodest   vnodest   source_nodet   destination_nodet   pattr(    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR	   \   s^    	c         C   sw  t  ƒ  } |  j ƒ  r d } n d } t j |  ƒ d k oC |  j ƒ  } |  j } |  j j d i  ƒ } | d k r‘ | j d d | d | | } n" | j d | d | d | | } y | j	 |  j d   Wn t
 k
 rÞ n Xy | j |  j d	   Wn t
 k
 r
n Xxa |  j d
 t ƒ D]M \ } } t d „  | j ƒ  Dƒ ƒ }	 | j t | ƒ |	  }
 | j |
 ƒ qW|  j ƒ  rxõ |  j d
 t d t ƒ D]h \ } } } } t d „  | j ƒ  Dƒ ƒ } | j t | ƒ t | ƒ d t | ƒ | } | j | ƒ q”Wnp xm |  j d
 t ƒ D]Y \ } } } t d „  | j ƒ  Dƒ ƒ } | j t | ƒ t | ƒ |  } | j | ƒ qW| S(   s  Return 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
    -----

    t   digraphR   i    R   t
   graph_typet   stricts   "%s"R   R   R   c         s   s'   |  ] \ } } | t  | ƒ f Vq d  S(   N(   R   (   t   .0t   kR=   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pys	   <genexpr>â   s    t   keysc         s   s3   |  ]) \ } } | d  k r | t  | ƒ f Vq d S(   t   keyN(   R   (   RI   RJ   R=   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pys	   <genexpr>è   s    	RL   c         s   s'   |  ] \ } } | t  | ƒ f Vq d  S(   N(   R   (   RI   RJ   R=   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pys	   <genexpr>ð   s    (   R   t   is_directedR#   t   number_of_selfloopst   is_multigraphR*   R   t   gett   Dott   set_node_defaultst   KeyErrort   set_edge_defaultsR   R!   t   dictt   itemst   NodeR   R,   t   edgest   EdgeR4   (   R8   R   RG   RH   R*   t   graph_defaultsR   R:   t   nodedatat   str_nodedataR9   R<   R=   RL   t   edgedatat   str_edgedataR   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR   ¶   sF    		"		+"!t   neatoc         K   s   t  d |  d | d | |  S(   sI  Create node positions using Pydot and Graphviz.

    Returns a dictionary of 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.
    R   t   progt   root(   R   (   R   R`   Ra   t   kwds(    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR   ö   s    c         K   s‚  t  ƒ  } t |  ƒ } | d
 k	 r: | j d t | ƒ ƒ n  | j d | ƒ } t | d t ƒ  ƒ} | d k r— d | GHd GHd GHd GHd GHd	 | GHd
 S| j | ƒ } t	 | ƒ d k s¾ t
 ‚ | d }	 i  }
 x­ |  j ƒ  D]Ÿ } | j t | ƒ ƒ j ƒ  } |	 j | ƒ } t | t ƒ r'| d } n  | j ƒ  d d !} | d
 k	 rÛ | j d ƒ \ } } t | ƒ t | ƒ f |
 | <qÛ qÛ W|
 S(   sh  Create node positions using :mod:`pydot` and Graphviz.

    Parameters
    --------
    G : Graph
        NetworkX graph to be laid out.
    prog : optional[str]
        Basename of the GraphViz command with which to layout this graph.
        Defaults to `neato`: default GraphViz command for undirected graphs.

    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()}

    Ra   R`   t   encodingR   s   Graphviz layout with %s faileds   To debug what happened try:s   P = nx.nx_pydot.to_pydot(G)s   P.write_dot("file.dot")s   And then run %s on file.dotNi   i    iÿÿÿÿt   ,(    (   R   R   R   t   setR   t
   create_dott   unicodeR    R   t   lent   AssertionErrorR   RW   R(   t   get_nodeR1   t   listt   get_post   splitt   float(   R   R`   Ra   Rb   R   R   t   D_bytest   Dt   Q_listt   Qt   node_posR:   t
   pydot_nodeR   t   post   xxt   yy(    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR     s8    #			
#c          C   sG   d d l  }  t |  j ƒ t t ƒ k  rC t d |  j t f ƒ ‚ n  |  S(   sƒ  
    Import and return the `pydot` module if the currently installed version of
    this module satisfies NetworkX requirements _or_ raise an exception.

    Returns
    --------
    :mod:`pydot`
        Imported `pydot` module object.

    Raises
    --------
    ImportError
        If the `pydot` module is either unimportable _or_ importable but of
        insufficient version.
    iÿÿÿÿNs   pydot %s < %s(   R   R   t   __version__t   PYDOT_VERSION_MINt   ImportError(   R   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyR   Y  s
    c         C   s?   d d l  m } y t ƒ  SWn t k
 r: | d ƒ ‚ n Xd  S(   Niÿÿÿÿ(   t   SkipTests   pydot not available(   t   noseR{   R   Rz   (   t   moduleR{   (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyt   setup_moduley  s
    (   t   __doc__t   localeR    t   networkx.utilsR   R   t   pkg_resourcesR   t   networkxR#   t   __all__Ry   R2   t	   NameErrort   strRg   R   R   R	   R   R   R   R   R   R~   (    (    (    s8   lib/python2.7/site-packages/networkx/drawing/nx_pydot.pyt   <module>   s(   

!	Z	@M	 