Skip to main content

Drawing basics

Draw methods

You can draw the graph using two drawing methods: draw() and draw_networkx(). With draw() you can draw a simple graph with no node labels or edge labels and using the full Matplotlib figure area and no axis labels by default, while draw_networkx() allows you to define more options and customize your graph.

Let's say we defined a complete bipartite graph as below:

import networkx as nx
import matplotlib.pyplot as plt

K33 = nx.complete_bipartite_graph(3, 3)

To draw it with draw() method, we use the following code:

nx.draw(K33)
plt.show()

The output:

visualization-basics-draw-simple

On the other hand, if we use draw_networkx() method, we need to run the following code for the default options:

nx.draw_networkx(K33)
plt.show()

The output:

visualization-basics-draw-customized

Layouts

Graph layout will define node position for your graph drawing. There are a bunch of predefined layouts in NetworkX. The default one is called spring_layout() which poistions nodes using Fruchterman-Reingold force-directed algorithm.

Let's show the basic usage of graph layouts on a simple graph example.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.dodecahedral_graph()
nx.draw(G)
plt.show()

Since we did not define any layout above, the default spring_layout() will be used.

If we want to draw the same graph with the shell_layout() that positiones nodes in concentric circles, we would use the following code:

nx.draw(G, pos=nx.shell_layout(G))
plt.show()

For spiral_layout() run:

nx.draw(G, pos=nx.spiral_layout(G))
plt.show()

Here is how these three layouts look like:

visualization-basics-layout

Positions

You can use the exact positions of the nodes, instead of using predefined layouts. To do that, you need to define a dictionary with nodes as keys and positions as values.

Example

import networkx as nx
import matplotlib.pyplot as plt

K33 = nx.complete_bipartite_graph(3, 3)

positions = {0: [-1, 1], 1: [0, 1], 2: [1, 1], 3: [-1, -1], 4: [0, -1], 5: [1, -1]}
ax = plt.figure().gca()
ax.set_axis_off()
options = {"node_size": 300, "node_color": "red"}
nx.draw_networkx(K33, positions, with_labels=False, **options)
plt.show()

Graph styling

There are numerous styling options which let you customize your graph. For example, you can define colors of the nodes, draw node and edge labels, change font size, etc. Below you can check out a simple example of graph styling.

Let's say we want to read a graph from the following graph.gaphml file:

<?xml version='1.0' encoding='utf-8'?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key id="d8" for="edge" attr.name="type" attr.type="string" />
<key id="d7" for="node" attr.name="followers" attr.type="int" />
<key id="d6" for="node" attr.name="platform" attr.type="string" />
<key id="d5" for="node" attr.name="username" attr.type="string" />
<key id="d4" for="node" attr.name="fraudReported" attr.type="boolean" />
<key id="d3" for="node" attr.name="compromised" attr.type="boolean" />
<key id="d2" for="node" attr.name="age" attr.type="int" />
<key id="d1" for="node" attr.name="name" attr.type="string" />
<key id="d0" for="node" attr.name="label" attr.type="string" />
<graph edgedefault="directed">
<node id="1">
<data key="d0">Person</data>
<data key="d1">John Doe</data>
<data key="d2">40</data>
</node>
<node id="2">
<data key="d0">CreditCard</data>
<data key="d1">Visa</data>
<data key="d3">False</data>
</node>
<node id="3">
<data key="d0">Store</data>
<data key="d1">Walmart</data>
</node>
<node id="4">
<data key="d0">Category</data>
<data key="d1">Grocery store</data>
</node>
<node id="5">
<data key="d0">Pos</data>
<data key="d3">False</data>
</node>
<node id="6">
<data key="d0">Transaction</data>
<data key="d4">False</data>
</node>
<node id="22">
<data key="d0">SocialMedia</data>
<data key="d5">john_doe</data>
<data key="d6">Facebook</data>
<data key="d7">2000</data>
</node>
<edge source="1" target="2">
<data key="d8">OWNS</data>
</edge>
<edge source="1" target="22">
<data key="d8">HAS_ACCOUNT</data>
</edge>
<edge source="2" target="6">
<data key="d8">HAS_TRANSACTION</data>
</edge>
<edge source="3" target="4">
<data key="d8">IS_OF_CATEGORY</data>
</edge>
<edge source="3" target="5">
<data key="d8">HAS_POS_DEVICE</data>
</edge>
<edge source="6" target="5">
<data key="d8">TRANSACTION_AT</data>
</edge>
</graph>
</graphml>

Other examples

Here is an example of how to draw a simple graph:

import matplotlib.pyplot as plt
import networkx as nx

G = nx.petersen_graph()
plt.subplot(121)

nx.draw(G, with_labels=True, font_weight='bold', node_color='orange')
plt.subplot(122)

nx.draw_shell(G, nlist=[range(5, 10), range(5)], with_labels=True, font_weight='bold', node_color='orange')

plt.show()

Here are some other options for drawing graphs:

import matplotlib.pyplot as plt
import networkx as nx

options = {
'node_color': 'orange',
'node_size': 100,
'width': 3,
}

G = nx.petersen_graph()

plt.subplot(221)
nx.draw_random(G, **options)

plt.subplot(222)
nx.draw_circular(G, **options)

plt.subplot(223)
nx.draw_spectral(G, **options)

plt.subplot(224)
nx.draw_shell(G, nlist=[range(5,10), range(5)], **options)

plt.show()

Useful tips

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.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
[('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

nx.draw(G)

plt.show()

How to draw a NetworkX graph with labels?

If you want the node labels to be visible in your drawing, just add with_labels=True to the nx.draw call.

import networkx as nx
import matplotlib.pyplot as plt

G=nx.Graph()
G.add_edge("Node1", "Node2")
nx.draw(G, with_labels = True)

plt.show()

How to change the color and width of edges in NetworkX graphs according to edge attributes?

Dictionaries are the underlying data structure used for NetworkX graphs, and as of Python 3.7+ they maintain insertion order. You can use the nx.get_edge_attributes() function to retrieve edge attributes. For every run, we are guaranteed to have the same edge order.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edge(1, 2, color='r' ,weight=3)
G.add_edge(2, 3, color='b', weight=5)
G.add_edge(3, 4, color='g', weight=7)

pos = nx.circular_layout(G)

colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()

nx.draw(G, pos, edge_color=colors, width=list(weights))

plt.show()

How to color nodes in NetworkX graphs?

You need to define a color map that assigns a color to each node. For example, if were to color the first 15 nodes of a graph in orange, and the rest in blue, then the code would be:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
color_map = []
for node in G:
if node < 15:
color_map.append('orange')
else:
color_map.append('blue')

nx.draw(G, node_color=color_map, with_labels=True)

plt.show()

How to color nodes in NetworkX graphs according to their attributes?

You need to define a color map that assigns a color to each node.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_node('A', color='red')
G.add_node('B', color='green')
G.add_node('C', color='blue')

G.add_edges_from(
[('A', 'B'), ('A', 'C'), ('B', 'C')])

colors = [node[1]['color'] for node in G.nodes(data=True)]

nx.draw(G, node_color=colors, with_labels=True, font_color='white')

plt.show()

Where to next?

If you wish to learn more about drawing graphs with NetworkX, visit the draw_networkx() and Graph Layout sections in the NetworkX reference guide. If you find this kind of drawing complicated and it is not working that well for your scale, check out how to visualise your graphs easy here.