Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change size of arrowheads in networkx based on list/dict

I can dynamically change the node size or node color by passing a list of values to the draw_network function. But how can i do it with ArrowStyle? Say I wanted to change the ArrowStyle (width & length) based on a list of values. The arrowsize doesn't either accept anything else than a single int value.

Here is an example code:

import matplotlib.patches
import networkx as nx
G = nx.DiGraph()
G.add_edge("reddit", "youtube")
G.add_edge("reddit", "google")
G.add_edge("google", "reddit")
G.add_edge("youtube", "reddit")
print(G.adj)

testArrow = matplotlib.patches.ArrowStyle.Fancy(head_length=.4, head_width=.4, tail_width=.1)


nx.draw_networkx(G,
             arrowsize=30,
             node_size=[5000,50,300],
             arrowstyle=testArrow)

enter image description here

like image 278
Anton Avatar asked Jan 07 '19 11:01

Anton


People also ask

How do I change the size of nodes in NetworkX?

Node Size. Altering node size globally is, again, quite simple via a keyword argument in the . draw() method — just specify node_size!

How do you draw a directed graph using NetworkX in Python?

1. How to draw directed graphs using NetworkX in Python? ​ By using the base class for directed graphs, DiGraph(), we are able to draw a directed graph with arrows to indicate the direction of edges.

How do I add edges to NetworkX?

Add an edge between u and v. The nodes u and v will be automatically added if they are not already in the graph. Edge attributes can be specified with keywords or by directly accessing the edge's attribute dictionary.


1 Answers

For changing the dimensions of arrows:

According to the documentation there is no option to do that in a single call. However, it can be done by drawing the edges one by one as follows:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edge("reddit", "youtube", w=5)
G.add_edge("reddit", "google", w=10)
G.add_edge("google", "reddit", w=30)
G.add_edge("youtube", "reddit", w=20)
print(G.adj)

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size=[5000, 50, 300])
nx.draw_networkx_labels(G, pos)
for edge in G.edges(data=True):
    w = edge[2]['w']
    nx.draw_networkx_edges(G, pos, edgelist=[(edge[0],edge[1])], arrowsize=w, node_size=[5000, 50, 300])
plt.show()

Which will bring to something like this:

enter image description here

For changing the dimensions of edges:

There's a conceptual difference between edges' width and length. While width is configurable and can be easily set per edge, length is defined by the position of nodes.

For changing edges' width in a similar manner to nodes' size and color, you can call draw_networkx_edges, and the argument 'width' accepts either float, or an array of floats.

For changing the edges' length you'll have to change the layout, set by 'pos' argument in nx.draw_networkx. The default is using a spring layout positioning.

like image 162
zohar.kom Avatar answered Sep 23 '22 14:09

zohar.kom