# NetworkX Application Notes: Draw a graph with matplotlib

This article takes notes from my experiences of drawing a graph with the python 2D plotting library, matplotlib.

# 1. Draw a graph

Use nx.draw() and nx.draw_networkx()to draw a graph,

# simple version of draw_networkx, drawing without labels or axes
draw(G, pos=None, ax=None, hold=None, **kwds)

# more full-featured drawing that allows title, axis labels etc.
draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds)


The optional keywords **kwds is described Here or in section 3.

# 1.1 Draw node labels

nx.draw_networkx() draws a graph whose node labels is node ids (with_labels=True). To specify node labels (from node attributes), we can add the with_labels=False keyword to suppress drawing of the labels and then draw specific labels with nx.draw_networkx_labels(G, pos, labels). For instance,

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import networkx as nx
import matplotlib.pyplot as plt

# Step 1: Build up a graph
G = nx.Graph()

# Step 2: Draw the graph and suppress node labels (node id)
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos, with_labels=False) # OR: nx.draw(G, pos)

# Step 3: Draw the graph with the specific node labels
node_labels = nx.get_node_attributes(G, 'alias') # a dict of attributes keyed by node
nx.draw_networkx_labels(G, pos, node_labels)

#plt.axis('off')
plt.show()


Refer to nx.draw_networkx_labels() for the detailed description.

draw_networkx_labels(G, pos, labels=None, font_size=12, font_color='k', font_family='sans-serif', font_weight='normal', alpha=1.0, bbox=None, ax=None, **kwds)


# 1.2 Draw edge labels

Use nx.nx.draw_networkx_edge_labels() to display the specified edge labels. Here is an example to draw a graph with specific node labels and edge labels.

# Step 1: Build up a graph
G = nx.Graph()

# Step 2: Draw a graph and suppress node labels (node id)
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos, with_labels=False) # OR: nx.draw(G, pos)

# Step 3: Draw the graph with the specific node labels and edge labels
# node labels
node_labels = nx.get_node_attributes(G, 'alias')
nx.draw_networkx_labels(G, pos, node_labels)

# edge labels
edge_labels = nx.get_edge_attributes(G, 'route')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)

#plt.axis('off')
plt.show()


Refer to nx.draw_networkx_edge_labels() for the detailed description.

draw_networkx_edge_labels(G, pos, edge_labels=None, label_pos=0.5, font_size=10, font_color='k', font_family='sans-serif', font_weight='normal', alpha=1.0, bbox=None, ax=None, rotate=True, **kwds)


# 2. Something unfulfilling, MultiGraph

NetworkX performs badly on drawing multigraph (MultiGraph and MultiDiGraph)as it does not display distinct edges, not to mention to label edges separately. For instance,

# Step 1: Build up a graph
G = nx.MultiGraph()

# Step 2: Draw the graph and suppress node labels (node id)
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos, with_labels=False) # OR: nx.draw(G, pos)

# Step 3: Draw the graph with the specific node labels
node_labels = nx.get_node_attributes(G, 'alias')
nx.draw_networkx_labels(G, pos, node_labels)

edge_labels = nx.get_edge_attributes(G, 'route')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)

plt.show()


Running the above code, the interpreter complains:

    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
File "/usr/local/lib/python2.7/dist-packages/networkx/drawing/nx_pylab.py", line 836, in draw_networkx_edge_labels
for (n1, n2), label in labels.items():
ValueError: too many values to unpack


The error is caused by the edge labels keyed by three-tuple in multigraph. It doen’t meet the requirement of nx.draw_networkx_edge_labels().

# edge labels in multigraph
{('n1', 'n2', 'r2'): 'route 2', ('n1', 'n2', 'r1'): 'route 1'}

# the description of edge_labels in draw_networkx_edge_labels
edge_labels (dictionary)
– Edge labels in a dictionary keyed by edge two-tuple of text labels (default=None). Only labels for the keys in the dictionary are drawn.


# 3. Basic functions and optional keywords

The networkx provides several functions to visualize a graph listed below. Refer to NetworkX documnentation: drawing for more infomation.

draw(G, pos=None, ax=None, hold=None, **kwds)                       # simple version of draw_networkx. Draw the graph as a simple representation with no node labels or edge labels and using the full Matplotlib figure area and no axis labels by default.
draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds)   # more full-featured drawing that allows title, axis labels etc.

## only draw nodes/edges
draw_networkx_nodes(G, pos, nodelist=None, node_size=300, node_color='r', node_shape='o', alpha=1.0, cmap=None, vmin=None, vmax=None, ax=None, linewidths=None, label=None, **kwds)             # only draw the nodes of the graph G
draw_networkx_edges(G, pos, edgelist=None, width=1.0, edge_color='k', style='solid', alpha=1.0, edge_cmap=None, edge_vmin=None, edge_vmax=None, ax=None, arrows=True, label=None, **kwds)       # only draw the edges of the graph G.

## draw labels
draw_networkx_labels(G, pos, labels=None, font_size=12, font_color='k', font_family='sans-serif', font_weight='normal', alpha=1.0, bbox=None, ax=None, **kwds)      # Draw node labels
draw_networkx_edge_labels(G, pos, edge_labels=None, label_pos=0.5, font_size=10, font_color='k', font_family='sans-serif', font_weight='normal', alpha=1.0, bbox=None, ax=None, rotate=True, **kwds)        # Draw edge labels


Here is the description of optional keywords.

G (graph)                                           # A networkx graph
pos (dictionary, optional)                          # A dictionary with nodes as keys and positions as values. If not specified a spring layout positioning will be computed. See networkx.layout for functions that compute node positions.

arrows (bool, optional (default=True))              # For directed graphs, if True draw arrowheads.
with_labels (bool, optional (default=True))         # Set to True to draw labels on the nodes.
ax (Matplotlib Axes object, optional)               # Draw the graph in the specified Matplotlib axes.
nodelist (list, optional (default G.nodes()))       # Draw only specified nodes
edgelist (list, optional (default=G.edges()))       # Draw only specified edges
node_size (scalar or array, optional (default=300)) # Size of nodes. If an array is specified it must be the same length as nodelist.

node_color (color string, or array of floats, (default=’r’))    # Node color. Can be a single color format string, or a sequence of colors with the same length as nodelist. If numeric values are specified they will be mapped to colors using the cmap and vmin,vmax parameters. See matplotlib.scatter for more details.

node_shape (string, optional (default=’o’))         # The shape of the node. Specification is as matplotlib.scatter marker.
alpha (float, optional (default=1.0))               # The node and edge transparency
cmap (Matplotlib colormap, optional (default=None)) # Colormap for mapping intensities of nodes

vmin,vmax (float, optional (default=None))          # Minimum and maximum for node colormap scaling
linewidths ([None | scalar | sequence])             # Line width of symbol border (default =1.0)
width (float, optional (default=1.0))               # Line width of edges

edge_color (color string, or array of floats (default=’r’)) # Edge color. Can be a single color format string, or a sequence of colors with the same length as edgelist. If numeric values are specified they will be mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters.

edge_cmap (Matplotlib colormap, optional (default=None))    # Colormap for mapping intensities of edges
edge_vmin,edge_vmax (floats, optional (default=None))       # Minimum and maximum for edge colormap scaling
style (string, optional (default=’solid’))                  # Edge line style (solid|dashed|dotted,dashdot)
labels (dictionary, optional (default=None))                # Node labels in a dictionary keyed by node of text labels
font_size (int, optional (default=12))                      # Font size for text labels
font_color (string, optional (default=’k’ black))           # Font color string
font_weight (string, optional (default=’normal’))           # Font weight
font_family (string, optional (default=’sans-serif’))       # Font family
label (string, optional)                                    # Label for graph legend