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()
# Add nodes:
nodes = ['A', 'B', 'C', 'D', 'E']
G.add_nodes_from(nodes)
# Add edges or links between the nodes:
edges = [('A','B'), ('B','C'), ('B', 'D'), ('D', 'E')]
G.add_edges_from(edges)
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[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)))
plotly.offline.plot(fig)