Black Lives Matter. Please consider donating to Campaign Zero's mission of ending police violence in America.
https://www.joincampaignzero.org # 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 https://plot.ly/python/network-graphs/#create-network-graph and https://plot.ly/python/igraph-networkx-comparison/ 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()

nodes = ['A', 'B', 'C', 'D', 'E']

edges = [('A','B'), ('B','C'), ('B', 'D'), ('D', 'E')]
return G

g = createDiGraph()

# Get a layout for the nodes according to some algorithm.
# See https://networkx.github.io/documentation/stable/reference/drawing.html#layout
# 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(
x=[],
y=[],
text=[],
mode='markers+text',
textposition='top center',
textfont=dict(
family='arial',
size=18,
color='rgb(0,0,0)'
),
hoverinfo='none',
marker=go.Marker(
showscale=False,
color='rgb(200,0,0)',
size=25,
line=go.Line(width=1, color='rgb(0,0,0)')))

for node in node_positions:
x, y = node_positions[node]
node_trace['x'].append(x)
node_trace['y'].append(y)
node_trace['text'].append(node)

# The edges will be drawn as lines:
edge_trace = go.Scatter(
x=[],
y=[],
line=go.Line(width=1, color='rgb(150,150,150)'),
hoverinfo='none',
mode='lines')

for edge in g.edges:
x0, y0 = node_positions[edge]
x1, y1 = node_positions[edge]
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)))

plotly.offline.plot(fig)``````

+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, https://stackoverflow.com/questions/51410283/how-to-efficiently-create-interactive-directed-network-graphs-with-arrows-on-p) 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 plotly.py, 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!

-Jon

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: https://github.com/redransil/plotly-dirgraph

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