Drawing Directed Graphs with Arrows Using NetworkX in Python

Nov 23, 2025 · Programming · 9 views · 7.8

Keywords: NetworkX | Directed Graph | Python Plotting

Abstract: This article provides a comprehensive guide on drawing directed graphs with arrows in Python using the NetworkX library. It covers creating directed graph objects, setting node colors, customizing edge colors, and adding directional indicators. Complete code examples and step-by-step explanations demonstrate how to visualize paths from specific nodes to targets, with comparisons of different drawing methods.

Introduction

In data visualization and network analysis, drawing directed graphs is a common requirement. NetworkX, as a powerful graph theory library in Python, offers extensive plotting capabilities. Based on a typical question from Stack Overflow, this article details how to use NetworkX to draw directed graphs with arrows and customize edge colors.

Basic Concepts of Directed Graphs

A directed graph (digraph) consists of nodes and directed edges, often used to represent directional relationships such as one-way traffic between cities or workflow processes. Unlike undirected graphs, edges in directed graphs have clear start and end points, typically indicated by arrows.

Creating a Directed Graph Object

In NetworkX, use nx.DiGraph() to create a directed graph object instead of the undirected nx.Graph(). This is fundamental for displaying arrows. The following code shows how to create and initialize a directed graph:

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')
])

Here, multiple edges are added, each representing a directed connection from one node to another.

Setting Node Properties

To enhance the informational value of the visualization, node color mapping can be applied. The following code defines a value map and colors nodes accordingly:

val_map = {'A': 1.0, 'D': 0.5714285714285714, 'H': 0.0}
values = [val_map.get(node, 0.25) for node in G.nodes()]

Using plt.get_cmap('jet') colormap, node colors will vary from blue (low values) to red (high values).

Customizing Edge Colors and Arrows

A key step is customizing the color of specific edges and adding arrows. The following code defines a list of red edges and draws edges with different colors separately:

red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red' for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), node_color=values, node_size=500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

Explanation:

Complete Code Example

Integrating the above steps, here is the complete executable code:

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')
])

val_map = {'A': 1.0, 'D': 0.5714285714285714, 'H': 0.0}
values = [val_map.get(node, 0.25) for node in G.nodes()]

red_edges = [('A', 'C'), ('E', 'C')]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), node_color=values, node_size=500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

Running this code will generate a visualization where edges from A to C and E to C are red with arrows, and other edges are black without arrows.

Comparison with Other Methods

Referencing other answers, the nx.draw_networkx function can simplify plotting but offers less customization. For example, using the arrows=True parameter may add arrows to all edges, preventing partial color differentiation. The step-by-step drawing method (as shown in this article) provides greater flexibility.

Common Issues and Optimizations

Issue 1: Arrows not showing? Ensure nx.DiGraph() is used instead of nx.Graph(), and set arrows=True when drawing edges.

Issue 2: Layout messy? Try different layout algorithms like nx.circular_layout or nx.random_layout, or adjust parameters of spring_layout.

Optimization suggestion: For complex graphs, integrate with Graphviz for better rendering quality, or use edge_labels to add edge weight labels.

Conclusion

Through NetworkX's step-by-step plotting functions, flexible customization of arrows and colors in directed graphs can be achieved. This method is suitable for scenarios like path analysis and network flow visualization, providing an extensible code base. Readers can adjust edge lists and visual parameters based on actual needs to further optimize graph effects.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.