U
    td5`                     @   sR   d Z ddlmZ ddlmZmZ dZG dd deeZG dd deZd	d
 Z	dS )a  
Drawing routines to draw graphs.

This module contains routines to draw graphs on:

  - Cairo surfaces (L{DefaultGraphDrawer})
  - Matplotlib axes (L{MatplotlibGraphDrawer})

It also contains routines to send an igraph graph directly to
(U{Cytoscape<http://www.cytoscape.org>}) using the
(U{CytoscapeRPC plugin<http://gforge.nbic.nl/projects/cytoscaperpc/>}), see
L{CytoscapeGraphDrawer}. L{CytoscapeGraphDrawer} can also fetch the current
network from Cytoscape and convert it to igraph format.
    )warn)AbstractGraphDrawerAbstractXMLRPCDrawer)CytoscapeGraphDrawer__plot__c                       sB   e Zd ZdZd fdd	ZdddZdddZedd Z  Z	S )r   a=  Graph drawer that sends/receives graphs to/from Cytoscape using
    CytoscapeRPC.

    This graph drawer cooperates with U{Cytoscape<http://www.cytoscape.org>}
    using U{CytoscapeRPC<http://wiki.nbic.nl/index.php/CytoscapeRPC>}.
    You need to install the CytoscapeRPC plugin first and start the
    XML-RPC server on a given port (port 9000 by default) from the
    appropriate Plugins submenu in Cytoscape.

    Graph, vertex and edge attributes are transferred to Cytoscape whenever
    possible (i.e. when a suitable mapping exists between a Python type
    and a Cytoscape type). If there is no suitable Cytoscape type for a
    Python type, the drawer will use a string attribute on the Cytoscape
    side and invoke C{str()} on the Python attributes.

    If an attribute to be created on the Cytoscape side already exists with
    a different type, an underscore will be appended to the attribute name
    to resolve the type conflict.

    You can use the C{network_id} attribute of this class to figure out the
    network ID of the last graph drawn with this drawer.
    http://localhost:9000/Cytoscapec                    s   t  |d d| _dS )zfConstructs a Cytoscape graph drawer using the XML-RPC interface
        of Cytoscape at the given URL.Z	CytoscapeN)super__init__
network_id)selfurl	__class__ M/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/drawing/graph.pyr	   /   s    zCytoscapeGraphDrawer.__init__Network from igraphTc              	   O   sF  ddl m} |rtdt | j}|s^z||d}W qh |k
rZ   td ||}Y qhX n
||}|| _d|kr|d }	t|	tr|j	|	 }	nt
t| }	dd |	D }	|||	 g g g}
| D ],\}}|
d |	|  |
d	 |	|  q|||
d |
d	 d
g|  | g|  d}d|kr| |d |}d| d  }|j||fdd || d | d  |j||	ft
tt
|   n
|| t| }| D ]}| || g\}}|d }|dkrqz*||kr|||kr|d7 }qW n |k
r0   Y nX |||||i qt| }|  D ]h}| |j	| \}}t!dd t|	|D }||kr|"||kr|d7 }q|#|||d q\t|$ }|% D ]f}| |j&| \}}t!dd t||D }||kr0|'||kr0|d7 }q
|(||| qdS )a,  Sends the given graph to Cytoscape as a new network.

        @param name: the name of the network in Cytoscape.
        @param create_view: whether to create a view for the network
          in Cytoscape.The default is C{True}.
        @keyword node_ids: specifies the identifiers of the nodes to
          be used in Cytoscape. This must either be the name of a
          vertex attribute or a list specifying the identifiers, one
          for each node in the graph. The default is C{None}, which
          simply uses the vertex index for each vertex.r   )FaultOPositional arguments to plot functions are ignored and will be deprecated soon.FznCytoscapeRPC too old, cannot create network without view. Consider upgrading CytoscapeRPC to use this feature.node_idsc                 S   s   g | ]}t |qS r   )str).0
identifierr   r   r   
<listcomp>a   s     z-CytoscapeGraphDrawer.draw.<locals>.<listcomp>   unknownlayoutd   g      ?T)Zkeep_aspect_ratiog       @N_c                 s   s   | ]}|d  dk	r|V  qdS r   Nr   r   pairr   r   r   	<genexpr>   s      z,CytoscapeGraphDrawer.draw.<locals>.<genexpr>c                 s   s   | ]}|d  dk	r|V  qdS r   r   r   r   r   r   r!      s      ))xmlrpc.clientr   r   DeprecationWarningserviceZcreateNetworkr
   
isinstancer   vslistrangeZvcountZcreateNodesZget_edgelistappendZcreateEdgesZecountZis_directedZensure_layoutZfit_into	translateZsetNodesPositionszipZperformDefaultLayoutsetZgetNetworkAttributeNames
attributesinfer_cytoscape_typeZgetNetworkAttributeTypeZaddNetworkAttributesgetNodeAttributeNamesZvertex_attributesdictZgetNodeAttributeTypeZaddNodeAttributesgetEdgeAttributeNamesZedge_attributesesZgetEdgeAttributeTypeZaddEdgeAttributes)r   graphnameZcreate_viewargskwdsr   cyr
   r   Z	edgelistsZv1Zv2Zedge_idsr   sizeZ
attr_namesattrZcy_typevaluevaluesr   r   r   draw5   s    

	
 

zCytoscapeGraphDrawer.drawNFc                    sv  ddl m} | j}| }d|kr0|dd }ttt|ddd }|dk r\td dkrn|	 }nL fd	d
|
  D }|std  nt|dkrtd  |d }||}||}	t|t|	 }
}||}| }i }|D ]}|dkr|sq|||}dd
 t|D }||dd
 t||D }dg|
 }t||D ]\}}|||< q^|||< q| }i }|D ]}|dkr|sq|||	}dd
 t|D }||dd
 t|	|D }dg| }t||D ]\}}|||< q|||< qtdd t|D }~g }|	D ],}| }|||d  ||d  f q2~	||
|||||dS )ag  Fetches the network with the given name from Cytoscape.

        When fetching networks from Cytoscape, the C{canonicalName} attributes
        of vertices and edges are not converted by default. Use the
        C{keep_canonical_names} parameter to retrieve these attributes as well.

        @param name: the name of the network in Cytoscape.
        @param directed: whether the network is directed.
        @param keep_canonical_names: whether to keep the C{canonicalName}
            vertex/edge attributes that are added automatically by Cytoscape
        @return: an appropriately constructed igraph L{Graph}.r   )Graph .N   )r      z8CytoscapeGraphDrawer requires Cytoscape-RPC 1.3 or newerc                    s   g | ]\}}| kr|qS r   r   r   kvr4   r   r   r      s      z.CytoscapeGraphDrawer.fetch.<locals>.<listcomp>zno such network: %rr   z*more than one network exists with name: %rZcanonicalNamec                 S   s   g | ]\}}|r|qS r   r   r   idxokr   r   r   r      s      c                 S   s   g | ]\}}|r|qS r   r   r   r4   rH   r   r   r   r      s      c                 S   s   g | ]\}}|r|qS r   r   rF   r   r   r   r      s      c                 S   s   g | ]\}}|r|qS r   r   rI   r   r   r   r      s      c                 s   s   | ]\}}||fV  qd S Nr   rB   r   r   r   r!      s     z-CytoscapeGraphDrawer.fetch.<locals>.<genexpr>)directedgraph_attrsvertex_attrs
edge_attrs)Zigraphr=   r$   versionsplittuplemapintNotImplementedErrorZgetNetworkIDZgetNetworkListitems
ValueErrorlenZgetNodesZgetEdgesZgetNetworkAttributesr/   ZnodesHaveAttribute	enumerateZgetNodesAttributesr+   r1   ZedgesHaveAttributeZgetEdgesAttributesr0   r)   )r   r4   rK   Zkeep_canonical_namesr=   r7   rO   r
   ZverticesedgesnmrL   Zvertex_attr_namesrM   	attr_nameZhas_attrfilteredr;   attrsrG   r:   Zedge_attr_namesrN   Zvertex_name_indexZ	edge_listedgepartsr   rE   r   fetch   s    



 

 
"zCytoscapeGraphDrawer.fetchc                 C   sn   dd | D }t dd |D r(d| fS t dd |D rBd| fS t dd |D r\d	| fS d
dd | D fS )a  Returns a Cytoscape type that can be used to represent all the
        values in C{values} and an appropriately converted copy of C{values} that
        is suitable for an XML-RPC call.  Note that the string type in
        Cytoscape is used as a catch-all type; if no other type fits, attribute
        values will be converted to string and then posted to Cytoscape.

        C{None} entries are allowed in C{values}, they will be ignored on the
        Cytoscape side.
        c                 S   s   g | ]}|d k	rt |qS rJ   )typer   r:   r   r   r   r     s      z=CytoscapeGraphDrawer.infer_cytoscape_type.<locals>.<listcomp>c                 s   s   | ]}|t kV  qd S rJ   )boolr   tr   r   r   r!     s     z<CytoscapeGraphDrawer.infer_cytoscape_type.<locals>.<genexpr>ZBOOLEANc                 s   s   | ]}t |ttfV  qd S rJ   )
issubclassrS   re   r   r   r   r!     s     ZINTEGERc                 s   s   | ]}t |tV  qd S rJ   )rg   floatre   r   r   r   r!     s     ZFLOATINGSTRINGc                 S   s"   g | ]}t |tst|n|qS r   )r%   r   rc   r   r   r   r     s    )all)r;   typesr   r   r   r.   
  s    z)CytoscapeGraphDrawer.infer_cytoscape_type)r   )r   T)NFF)
__name__
__module____qualname____doc__r	   r<   ra   staticmethodr.   __classcell__r   r   r   r   r      s   
t
ar   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )GephiGraphStreamingDrawera  Graph drawer that sends a graph to a file-like object (e.g., socket, URL
    connection, file) using the Gephi graph streaming format.

    The Gephi graph streaming format is a simple JSON-based format that can be used
    to post mutations to a graph (i.e. node and edge additions, removals and updates)
    to a remote component. For instance, one can open up Gephi
    (U{http://www.gephi.org}), install the Gephi graph streaming plugin and then
    send a graph from igraph straight into the Gephi window by using
    C{GephiGraphStreamingDrawer} with the appropriate URL where Gephi is
    listening.

    The C{connection} property exposes the L{GephiConnection} that the drawer
    uses. The drawer also has a property called C{streamer} which exposes the underlying
    L{GephiGraphStreamer} that is responsible for generating the JSON objects,
    encoding them and writing them to a file-like object. If you want to customize
    the encoding process, this is the object where you can tweak things to your taste.
    Nc                    s6   t    ddlm}m} |p&|||| _| | _dS )aB  Constructs a Gephi graph streaming drawer that will post graphs to the
        given Gephi connection. If C{conn} is C{None}, the remaining arguments of
        the constructor are forwarded intact to the constructor of
        L{GephiConnection} in order to create a connection. This means that any of
        the following are valid:

          - C{GephiGraphStreamingDrawer()} will construct a drawer that connects to
            workspace 0 of the local Gephi instance on port 8080.

          - C{GephiGraphStreamingDrawer(workspace=2)} will connect to workspace 2
            of the local Gephi instance on port 8080.

          - C{GephiGraphStreamingDrawer(port=1234)} will connect to workspace 0
            of the local Gephi instance on port 1234.

          - C{GephiGraphStreamingDrawer(host="remote", port=1234, workspace=7)}
            will connect to workspace 7 of the Gephi instance on host C{remote},
            port 1234.

          - C{GephiGraphStreamingDrawer(url="http://remote:1234/workspace7)} is
            the same as above, but with an explicit URL.
        r   )GephiGraphStreamerGephiConnectionN)r   r	   Zigraph.remote.gephirs   rt   
connectionstreamer)r   connr5   r6   rs   rt   r   r   r   r	   7  s    
z"GephiGraphStreamingDrawer.__init__c                 O   s,   |rt dt | jj|| j|dd dS )a9  Draws (i.e. sends) the given graph to the destination of the drawer using
        the Gephi graph streaming API.

        The following keyword arguments are allowed:

            - C{encoder} lets one specify an instance of C{json.JSONEncoder} that
              will be used to encode the JSON objects.
        r   encoder)rx   N)r   r#   rv   postru   get)r   r3   r5   r6   r   r   r   r<   U  s    
zGephiGraphStreamingDrawer.draw)N)rl   rm   rn   ro   r	   r<   rq   r   r   r   r   rr   $  s   rr   c                 O   s:   ddl m} |d|| ||}|j| f|| dS )a$  Plots the graph to the given Cairo context or matplotlib Axes.

    The visual style of vertices and edges can be modified at three
    places in the following order of precedence (lower indices override
    higher indices):

      1. Keyword arguments of this function (or of L{plot()} which is
         passed intact to C{Graph.__plot__()}.

      2. Vertex or edge attributes, specified later in the list of
         keyword arguments.

      3. igraph-wide plotting defaults (see
         L{igraph.config.Configuration})

      4. Built-in defaults.

    E.g., if the C{vertex_size} keyword attribute is not present,
    but there exists a vertex attribute named C{size}, the sizes of
    the vertices will be specified by that attribute.

    Besides the usual self-explanatory plotting parameters (C{context},
    C{bbox}, C{palette}), it accepts the following keyword arguments:

      - C{autocurve}: whether to use curves instead of straight lines for
        multiple edges on the graph plot. This argument may be C{True}
        or C{False}; when omitted, C{True} is assumed for graphs with
        less than 10.000 edges and C{False} otherwise.

      - C{drawer_factory}: a subclass of L{AbstractCairoGraphDrawer}
        which will be used to draw the graph. You may also provide
        a function here which takes two arguments: the Cairo context
        to draw on and a bounding box (an instance of L{BoundingBox}).
        If this keyword argument is missing, igraph will use the
        default graph drawer which should be suitable for most purposes.
        It is safe to omit this keyword argument unless you need to use
        a specific graph drawer.

      - C{keep_aspect_ratio}: whether to keep the aspect ratio of the layout
        that igraph calculates to place the nodes. C{True} means that the
        layout will be scaled proportionally to fit into the bounding box
        where the graph is to be drawn but the aspect ratio will be kept
        the same (potentially leaving empty space next to, below or above
        the graph). C{False} means that the layout will be scaled independently
        along the X and Y axis in order to fill the entire bounding box.
        The default is C{False}.

      - C{layout}: the layout to be used. If not an instance of
        L{Layout}, it will be passed to L{layout} to calculate
        the layout. Note that if you want a deterministic layout that
        does not change with every plot, you must either use a
        deterministic layout function (like L{GraphBase.layout_circle}) or
        calculate the layout in advance and pass a L{Layout} object here.

      - C{margin}: the top, right, bottom, left margins as a 4-tuple.
        If it has less than 4 elements or is a single float, the elements
        will be re-used until the length is at least 4.

      - C{mark_groups}: whether to highlight some of the vertex groups by
        colored polygons. This argument can be one of the following:

          - C{False}: no groups will be highlighted

          - C{True}: only valid if the object plotted is a
            L{VertexClustering} or L{VertexCover}. The vertex groups in the
            clutering or cover will be highlighted such that the i-th
            group will be colored by the i-th color from the current
            palette. If used when plotting a graph, it will throw an error.

          - A dict mapping tuples of vertex indices to color names.
            The given vertex groups will be highlighted by the given
            colors.

          - A list containing pairs or an iterable yielding pairs, where
            the first element of each pair is a list of vertex indices and
            the second element is a color.

          - A L{VertexClustering} or L{VertexCover} instance. The vertex
            groups in the clustering or cover will be highlighted such that
            the i-th group will be colored by the i-th color from the
            current palette.

        In place of lists of vertex indices, you may also use L{VertexSeq}
        instances.

        In place of color names, you may also use color indices into the
        current palette. C{None} as a color name will mean that the
        corresponding group is ignored.

      - C{vertex_size}: size of the vertices. The corresponding vertex
        attribute is called C{size}. The default is 10. Vertex sizes
        are measured in the unit of the Cairo context on which igraph
        is drawing.

      - C{vertex_color}: color of the vertices. The corresponding vertex
        attribute is C{color}, the default is red.  Colors can be
        specified either by common X11 color names (see the source
        code of L{igraph.drawing.colors} for a list of known colors), by
        3-tuples of floats (ranging between 0 and 255 for the R, G and
        B components), by CSS-style string specifications (C{#rrggbb})
        or by integer color indices of the specified palette.

      - C{vertex_frame_color}: color of the frame (i.e. stroke) of the
        vertices. The corresponding vertex attribute is C{frame_color},
        the default is black. See C{vertex_color} for the possible ways
        of specifying a color.

      - C{vertex_frame_width}: the width of the frame (i.e. stroke) of the
        vertices. The corresponding vertex attribute is C{frame_width}.
        The default is 1. Vertex frame widths are measured in the unit of the
        Cairo context on which igraph is drawing.

      - C{vertex_shape}: shape of the vertices. Alternatively it can
        be specified by the C{shape} vertex attribute. Possibilities
        are: C{square}, {circle}, {triangle}, {triangle-down} or
        C{hidden}. See the source code of L{igraph.drawing} for a
        list of alternative shape names that are also accepted and
        mapped to these.

      - C{vertex_label}: labels drawn next to the vertices.
        The corresponding vertex attribute is C{label}.

      - C{vertex_label_dist}: distance of the midpoint of the vertex
        label from the center of the corresponding vertex.
        The corresponding vertex attribute is C{label_dist}.

      - C{vertex_label_color}: color of the label. Corresponding
        vertex attribute: C{label_color}. See C{vertex_color} for
        color specification syntax.

      - C{vertex_label_size}: font size of the label, specified
        in the unit of the Cairo context on which we are drawing.
        Corresponding vertex attribute: C{label_size}.

      - C{vertex_label_angle}: the direction of the line connecting
        the midpoint of the vertex with the midpoint of the label.
        This can be used to position the labels relative to the
        vertices themselves in conjunction with C{vertex_label_dist}.
        Corresponding vertex attribute: C{label_angle}. The
        default is C{-math.pi/2}.

      - C{vertex_order}: drawing order of the vertices. This must be
        a list or tuple containing vertex indices; vertices are then
        drawn according to this order.

      - C{vertex_order_by}: an alternative way to specify the drawing
        order of the vertices; this attribute is interpreted as the name
        of a vertex attribute, and vertices are drawn such that those
        with a smaller attribute value are drawn first. You may also
        reverse the order by passing a tuple here; the first element of
        the tuple should be the name of the attribute, the second element
        specifies whether the order is reversed (C{True}, C{False},
        C{"asc"} and C{"desc"} are accepted values).

      - C{edge_color}: color of the edges. The corresponding edge
        attribute is C{color}, the default is red. See C{vertex_color}
        for color specification syntax.

      - C{edge_curved}: whether the edges should be curved. Positive
        numbers correspond to edges curved in a counter-clockwise
        direction, negative numbers correspond to edges curved in a
        clockwise direction. Zero represents straight edges. C{True}
        is interpreted as 0.5, C{False} is interpreted as 0. The
        default is 0 which makes all the edges straight.

      - C{edge_width}: width of the edges in the default unit of the
        Cairo context on which we are drawing. The corresponding
        edge attribute is C{width}, the default is 1.

      - C{edge_arrow_size}: arrow size of the edges. The
        corresponding edge attribute is C{arrow_size}, the default
        is 1.

      - C{edge_arrow_width}: width of the arrowhead on the edge. The
        corresponding edge attribute is C{arrow_width}, the default
        is 1.

      - C{edge_order}: drawing order of the edges. This must be
        a list or tuple containing edge indices; edges are then
        drawn according to this order.

      - C{edge_order_by}: an alternative way to specify the drawing
        order of the edges; this attribute is interpreted as the name
        of an edge attribute, and edges are drawn such that those
        with a smaller attribute value are drawn first. You may also
        reverse the order by passing a tuple here; the first element of
        the tuple should be the name of the attribute, the second element
        specifies whether the order is reversed (C{True}, C{False},
        C{"asc"} and C{"desc"} are accepted values).
    r   )DrawerDirectoryZdrawer_factoryN)Zigraph.drawingr{   popresolver<   )r   backendcontextr5   r6   r{   Zdrawerr   r   r   r   i  s     @r   N)
ro   warningsr   Zigraph.drawing.baseclassesr   r   __all__r   rr   r   r   r   r   r   <module>   s     E