0

I'm wondering if is possible to create some sort of notation to indicate inputs for a graph in networkx / Python.

For example, taking the image presented here, supposed I want to be able to identify sources and sinks. I would be interested in creating a representation such as:

enter image description here

Is that possible?

pceccon
  • 9,379
  • 26
  • 82
  • 158
  • 1
    As a side note, the new version of networkx has the implementation of real arrows: [example](https://networkx.github.io/documentation/stable/auto_examples/drawing/plot_directed.html#sphx-glr-auto-examples-drawing-plot-directed-py) – rodgdor Mar 08 '18 at 10:41

1 Answers1

1

The annotate functionality does exactly what you want. (See also the annotate intro)

Given the example you linked, you could just add the following to annotate selected nodes. (It depends on the positions dictionary pos to know where the nodes are located).

ax = plt.gca()
ax.annotate("3", xy=pos.get('B'), xytext=(0, 40), textcoords='offset points',
    arrowprops=dict(facecolor='black', shrink=0.15),  
    bbox=dict(boxstyle="round", fc="cyan"))
ax.annotate("4", xy=pos.get('F'), xytext=(0, 40), textcoords='offset points',
    arrowprops=dict(facecolor='black', shrink=0.15),
    bbox=dict(boxstyle="round", fc="cyan"))

example networkx with annotation

So that this answer is self-contained, Full code including linked example:

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

# Specify the edges you want here
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]

# Need to create a layout when doing
# separate calls to draw nodes and 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)

# add annotations for selected nodes.
ax = plt.gca()
ax.annotate("3", xy=pos.get('B'), xytext=(0, 40), textcoords='offset points',
        arrowprops=dict(facecolor='black', shrink=0.15),  
        bbox=dict(boxstyle="round", fc="cyan"))
ax.annotate("4", xy=pos.get('F'), xytext=(0, 40), textcoords='offset points', 
        arrowprops=dict(facecolor='black', shrink=0.15),  
        bbox=dict(boxstyle="round", fc="cyan"))

plt.show()
Bonlenfum
  • 19,101
  • 2
  • 53
  • 56