Curious
Curious

Reputation: 825

How to draw a weighted bidirectional graph with at least 3 edges going from one node to the central node?

I would like to draw the following graph using networkx with random edge weights. enter image description here

The point is that at least 3 edges have to go from nodes 2 and 3 to node 1.

I followed the code from here and got the following:

G = nx.DiGraph()
edge_list = [(1,2,{'w':'A1'}),(2,1,{'w':'A2'}), (2, 1, {'w':'A3'}), (1,3,{'w':'B'}),(3,1,{'w':'C'})]
G.add_edges_from(edge_list)
pos=nx.spring_layout(G,seed=5)
fig, ax = plt.subplots()
nx.draw_networkx_nodes(G, pos, ax=ax)
nx.draw_networkx_labels(G, pos, ax=ax)

curved_edges = [edge for edge in G.edges() if reversed(edge) in G.edges()]
straight_edges = list(set(G.edges()) - set(curved_edges))
nx.draw_networkx_edges(G, pos, ax=ax, edgelist=straight_edges)
arc_rad = 0.25
nx.draw_networkx_edges(G, pos, ax=ax, edgelist=curved_edges, connectionstyle=f'arc3, rad = {arc_rad}')

enter image description here

The first issue is that all the edges have to be undirected or at least bidirectional. Secondly, I added one more edge from 1 to 2 but it does not show up in the final graph.

How do I fix these two issues?

Upvotes: 0

Views: 304

Answers (1)

Curious
Curious

Reputation: 825

Okay, I discovered some code that closely resembles what I require here (refer to Lee's response) and was able to modify it to meet my needs. Here's the code and the outcome.

G=nx.MultiGraph()
edge_list = [(1,2,{'w':'A1'}),(2,1,{'w':'A2'}), (2, 1, {'w':'A3'}), (1,3,{'w':'B'}),(3,1,{'w':'C'}), (3, 1, {'w':'D'})]

G.add_edges_from(edge_list)
pos = nx.random_layout(G) # pos=nx.spring_layout(G,seed=5)

nx.draw_networkx_nodes(G, pos, node_color = 'b', node_size = 500, alpha = 1)
nx.draw_networkx_labels(G, pos, font_color='w') 

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(0.3*e[2])
                                ),
                                ),
                )
plt.axis('off')
plt.show()

enter image description here

To put the node in "front" (so you can't see the multiple edges pointing at the node), you need to set the shrinkA and shrinkB higher (10).

Upvotes: 0

Related Questions