Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib and Networkx - drawing a self loop node

I have this function and I want to draw a self loop. How can I do that?
The edge exists but I think it's just a point in this exemple is (1,1) and I couldn't add the name of nodes. My goal is from adjacency matrix draw a graph. Is there there is better way to do this?

import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch, Circle
import numpy as np

def draw_network(G,pos,ax,sg=None):

    for n in G:
        c=Circle(pos[n],radius=0.05,alpha=0.7)
        ax.add_patch(c)
        G.node[n]['patch']=c
        x,y=pos[n]
    seen={}
    for (u,v,d) in G.edges(data=True):
        n1=G.node[u]['patch']
        n2=G.node[v]['patch']
        rad=0.1
        if (u,v) in seen:
            rad=seen.get((u,v))
            rad=(rad+np.sign(rad)*0.1)*-1
        alpha=0.5
        color='k'

        e = FancyArrowPatch(n1.center,n2.center,patchA=n1,patchB=n2,
                            arrowstyle='-|>',
                            connectionstyle='arc3,rad=%s'%rad,
                            mutation_scale=10.0,
                            lw=2,
                            alpha=alpha,
                            color=color)
        seen[(u,v)]=rad
        ax.add_patch(e)
    return e


G=nx.MultiDiGraph([(1,2),(1,1),(1,2),(2,3),(3,4),(2,4),
                (1,2),(1,2),(1,2),(2,3),(3,4),(2,4)]
                )

pos=nx.spring_layout(G)
ax=plt.gca()
draw_network(G,pos,ax)
ax.autoscale()
plt.axis('equal')
plt.axis('off')

plt.show()
like image 683
Athmane Ouzeriat Avatar asked Mar 17 '18 18:03

Athmane Ouzeriat


People also ask

Can DiGraphs have self loops?

A loop of an graph is degenerate edge that joins a vertex to itself, also called a self-loop. A simple graph cannot contain any loops, but a pseudograph can contain both multiple edges and loops.

What is a DiGraph Python?

A DiGraph stores nodes and edges with optional data, or attributes. DiGraphs hold directed edges. Self loops are allowed but multiple (parallel) edges are not. Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.

Does NetworkX have edge?

Returns True if the graph has an edge between nodes u and v. This is the same as v in G[u] or key in G[u][v] without KeyError exceptions.

Which data type can be used as the content of a node in NetworkX?

In NetworkX, nodes can be any hashable object e.g., a text string, an image, an XML object, another Graph, a customized node object, etc. Python's None object is not allowed to be used as a node.


1 Answers

It seems that your approach is quite advanced a use of matplotlib, but I would still recommend using a specialized graph plotting library (as does the networkx documentation). As graphs get bigger, more problems arise -- but problems that have already been solved in those libraries.

A "go-to" option is graphviz, which handles drawing multi-graphs reasonably well. You can write dot files from networkx graphs, and then use one of the graph drawing tools (e.g. dot, neato, etc).

Here is an example, building on graph attributes and multigraph edge attributes:

import networkx as nx
from networkx.drawing.nx_agraph import to_agraph 

# define the graph as per your question
G=nx.MultiDiGraph([(1,2),(1,1),(1,2),(2,3),(3,4),(2,4), 
    (1,2),(1,2),(1,2),(2,3),(3,4),(2,4)])

# add graphviz layout options (see https://stackoverflow.com/a/39662097)
G.graph['edge'] = {'arrowsize': '0.6', 'splines': 'curved'}
G.graph['graph'] = {'scale': '3'}
                                                                                
# adding attributes to edges in multigraphs is more complicated but see
# https://stackoverflow.com/a/26694158                    
G[1][1][0]['color']='red'
                                                                                
A = to_agraph(G) 
A.layout('dot')                                                                 
A.draw('multi.png')   

multi-graph with self loops

Note that you can also easily invoke the drawing from within an ipython shell: https://stackoverflow.com/a/14945560

like image 70
Bonlenfum Avatar answered Oct 24 '22 16:10

Bonlenfum