Plotting directed graphs in Python in a way that show all edges separately

前端 未结 4 1734
Happy的楠姐
Happy的楠姐 2020-12-01 04:44

I\'m using Python to simulate a process that takes place on directed graphs. I would like to produce an animation of this process.

The problem that I\'ve run into i

相关标签:
4条回答
  • 2020-12-01 05:04

    Using NetworkX, a possible workaround which avoids file I/O and uses dot via pydot for layout is:

    import networkx as nx
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    from io import BytesIO
    
    g = nx.dodecahedral_graph()
    d = nx.drawing.nx_pydot.to_pydot(g) # d is a pydot graph object, dot options can be easily set
    # attributes get converted from networkx,
    # use set methods to control dot attributes after creation
    
    png_str = d.create_png()
    sio = BytesIO() # file-like string, appropriate for imread below
    sio.write(png_str)
    sio.seek(0)
    
    img = mpimg.imread(sio)
    imgplot = plt.imshow(img)
    

    for why seek(0) is needed, see How to create an image from a string in python

    If within IPython (qt)console, then the above will print inline and a more direct approach is:

    import networkx as nx
    from IPython.display import Image
    
    g = nx.dodecahedral_graph()
    d = nx.drawing.nx_pydot.to_pydot(g)
    
    png_str = d.create_png()
    Image(data=png_str)
    
    0 讨论(0)
  • 2020-12-01 05:10

    The Graphviz tools appear to display distinct edges.

    For example, giving this:

    digraph G {
      A -> B;
      A -> B;
      A -> B;
      B -> C;
    
      B -> A;
      C -> B;
    }
    

    to dot produces:

    example graph

    Graphviz's input language is pretty simple so you can generate it on your own, though searching for "python graphviz" does turn up a couple of libraries including a graphviz module on PyPI.

    Here's python that generates the above graph using the graphviz module:

    from graphviz import Digraph
    
    dot = Digraph()
    dot.node('A', 'A')
    dot.node('B', 'B')
    dot.node('C', 'C')
    dot.edges(['AB', 'AB', 'AB', 'BC', 'BA', 'CB'])
    
    print(dot.source)
    dot.render(file_name, view=True)
    
    0 讨论(0)
  • 2020-12-01 05:18

    You can do it by using the matplotlib interface:

    G=nx.MultiGraph ([(1, 2),
       (2, 3),
       (3, 2),
       (2, 1)])
    pos = {1: (0.4,0.5), 2: (0.5,0.5), 3: (0.6,0.5)}
    nx.draw_networkx_nodes(G, pos, node_color = 'k', node_size = 100, alpha = 1)
    ax = plt.gca()
    for e in G.edges:
        ax.annotate("",
                    xy=pos[e[0]], xycoords='data',
                    xytext=pos[e[1]], textcoords='data',
                    arrowprops=dict(arrowstyle="->", color="0.5",
                                    shrinkA=5, shrinkB=5,
                                    patchA=None, patchB=None,
                                    connectionstyle="arc3,rad=rrr".replace('rrr',str(2*(e[2]-0.5))
                                    ),
                                    ),
                    )
    plt.axis('off')
    plt.show()
    

    0 讨论(0)
  • 2020-12-01 05:22

    Maybe I am a little late but I found another solution to you issue, so I post it so that can be helpful if somebody has the same problem. This is adding the connectionstyle argument to nx.draw:

    import networkx as nx
    import matplotlib.pyplot as plt 
    
    G = nx.MultiDiGraph()
    
    G.add_edges_from([
        (1, 2),
        (2, 3),
        (3, 2),
        (2, 1),
    ])
    
    plt.figure(figsize=(8,8))
    nx.draw(G, connectionstyle='arc3, rad = 0.1',)
    

    Here you see the result:

    The result

    0 讨论(0)
提交回复
热议问题