Black Lives Matter. Please consider donating to Campaign Zero's mission of ending police violence in America.

How to add arrowheads to edges between nodes in a directed network diagram?

I want to draw a graphical network using Plotly in Python. Using a similar approach to the examples at and I have been able to draw my own network of circular nodes connected by edges. But now I want to add an arrowhead to one end of each edge to show which node is the ‘parent’ of another node. How do I do that please?

Intuitively, I was hoping to find an arrowhead attribute on the Line object for Scatter but no such luck:(.

I can see there’s an option to annotate graphs but it seems a lot of work to define annotations for every single edge since those edges already exist and have been drawn.

Here’s my code so far:

import networkx as nx
import plotly.offline
import plotly.graph_objs as go

def createDiGraph():
    # Create a directed graph (digraph) object; i.e., a graph in which the edges
    # have a direction associated with them.
    G = nx.DiGraph()

    # Add nodes:
    nodes = ['A', 'B', 'C', 'D', 'E']

    # Add edges or links between the nodes:
    edges = [('A','B'), ('B','C'), ('B', 'D'), ('D', 'E')]
    return G

g = createDiGraph()

# Get a layout for the nodes according to some algorithm.
# See
# for alternative algorithms that are available.
# Set random_state (default=None) if you want the layout to be deterministic
# and repeatable.
node_positions = nx.spring_layout(g, random_state=779)

# The nodes will be plotted as a scatter plot of markers with their names
# above each circle:
node_trace = go.Scatter(
    textposition='top center',
            line=go.Line(width=1, color='rgb(0,0,0)')))

for node in node_positions:
    x, y = node_positions[node]

# The edges will be drawn as lines:
edge_trace = go.Scatter(
    line=go.Line(width=1, color='rgb(150,150,150)'),

for edge in g.edges:
    x0, y0 = node_positions[edge[0]]
    x1, y1 = node_positions[edge[1]]
    edge_trace['x'].extend([x0, x1, None])
    edge_trace['y'].extend([y0, y1, None])

# Create figure:
fig = go.Figure(data = go.Data([edge_trace, node_trace]),
             layout = go.Layout(
                title = 'Sample Network',
                titlefont = dict(size=16),
                showlegend = False,
                hovermode = 'closest',
                margin = dict(b=20,l=5,r=5,t=40),
                xaxis = go.XAxis(showgrid=False, zeroline=False, showticklabels=False),
                yaxis = go.YAxis(showgrid=False, zeroline=False, showticklabels=False)))


+1 this question. It’d be awesome to have the ability to show the direction within directed graphs. I’ve seen people do hacks with cones (3D Vector Arrows, but seems like there could be a more elegant solution out of the box.

1 Like

Hi @MattH,

There’s nothing built in the create directed graph arrows. The annotations approach is probably the most straightforward at the moment. It would be interesting to add a directed graph figure factory to, basically as a way to to automate one of the ‘hacks’ for creating arrows. Sort of like the create_streamline figure factory, which just draws arrow heads as separate scatter lines.

Let me know if anyone is interested in working on this!


1 Like

Any updates on directed graphs with arrows on edges?

Any update on this question? I will like to have it as well.

I needed this too; does this work for your use case:

Example output:

@redransil - that looks good. However I needed something over 2 years ago and ended up using Matplotlib to do it all instead!