NetworkX: Drawing Graph - python

I am trying to draw a graph using NetworkX in Python. I am using the following code:
G=nx.to_networkx_graph(adj)
pos=nx.spring_layout(G)
#G=nx.path_graph(8)
nx.draw(G,pos,labels)
plt.savefig("simple_path.png") # save as png
plt.show() # display
I get this output:
But I want to get the following output with Labels:
What can I do on the code? thank you.

So for the positioning, you've set pos based on spring_layout. pos gives the positions of your nodes. Check it out - once you've defined it, ask python to print pos for you and see what it's doing.
Here's an alternative code:
import networkx as nx
import pylab as py
blue_edges = [('B', 'C'), ('B', 'D'), ('B', 'E'), ('E', 'F')]
red_edges = [('A', 'B'), ('A', 'C'), ('C', 'E'), ('D', 'E'), ('D', 'F')]
G=nx.Graph() #define G
G.add_edges_from(blue_edges)
G.add_edges_from(red_edges)
pos = {'A':(0,0), 'B':(1,1), 'C':(1,-1), 'D':(2,1), 'E':(2,-1), 'F':(3,0)}
nx.draw_networkx(G, pos=pos, edgelist = [], node_color = 'k')
nx.draw_networkx(G, pos=pos, nodelist = [], edgelist = blue_edges, edge_color = 'b')
nx.draw_networkx(G, pos=pos, nodelist = [], edgelist = red_edges, edge_color = 'r')
and if you want it without the x and y axes showing, change the last bit to:
nx.draw(G, pos=pos, edgelist = [], node_color = 'k')
nx.draw(G, pos=pos, nodelist = [], edgelist = blue_edges, edge_color = 'b')
nx.draw(G, pos=pos, nodelist = [], edgelist = red_edges, edge_color = 'r')

Related

Unwanted edge displayed in the network which shouldn't exist in principle in hvplot.networkx

I'm using this code to make a network and have edges shown differently based on an edge attribute, in this case 'Polarity'. But the result I get has extra edge(s) which are not specified. Please have a look. I can't figure it out.
import networkx as nx
import hvplot.networkx as hvnx
G = nx.Graph()
G.add_edge('a', 'b', Polarity="positive")
G.add_edge('a', 'c', Polarity="positive")
G.add_edge('c', 'd', Polarity="positive")
G.add_edge('c', 'e', Polarity="negative")
G.add_edge('c', 'f', Polarity="negative")
G.add_edge('a', 'd', Polarity="negative")
elarge = [(u, v) for (u, v, attr) in G.edges(data=True) if attr['Polarity'] == "positive"]
esmall = [(u, v) for (u, v, attr) in G.edges(data=True) if attr['Polarity'] == "negative"]
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nodes = hvnx.draw_networkx_nodes(G, pos, node_size=700)
# edges
edges1 = hvnx.draw_networkx_edges(
G, pos, edgelist=elarge, edge_width=6)
edges2 = hvnx.draw_networkx_edges(
G, pos, edgelist=esmall, edge_width=6, alpha=0.5, edge_color='blue', style='dashed')
labels = hvnx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif')
edges2 * nodes * labels
Why do I get additional edge(s) 'c','d' in this case? Thanks.

Hypergraph with networkx

is anyone familiar with networkx?
I try to get a hypergraph, where i want to set the Hyperedges as other colored nodes (size dependent on their value) out of an list. And i want to set the Nodes out of an other list.
The documentation and examples on the networkx website are really spare, but i am sure it is possible.
I started with this example, but this is only an example for different edges. Can someone tell me how i can put up two different set of nodes with different color/size in networkx?
Did you want something like this use nx.draw_networkx_nodes using nodelist parameter:
# Author: Aric Hagberg (hagberg#lanl.gov)
import matplotlib.pyplot as plt
import networkx as nx
G = nx.Graph()
G.add_edge('a', 'b', weight=0.6)
G.add_edge('a', 'c', weight=0.2)
G.add_edge('c', 'd', weight=0.1)
G.add_edge('c', 'e', weight=0.7)
G.add_edge('c', 'f', weight=0.9)
G.add_edge('a', 'd', weight=0.3)
elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5]
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nx.draw_networkx_nodes(G, pos, node_size=700, nodelist=['e','f','b'])
nx.draw_networkx_nodes(G, pos, node_size=1400, nodelist=['c','a','d'], node_color='blue')
# edges
nx.draw_networkx_edges(G, pos, edgelist=elarge,
width=6)
nx.draw_networkx_edges(G, pos, edgelist=esmall,
width=6, alpha=0.5, edge_color='b', style='dashed')
# labels
nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif')
plt.axis('off')
plt.show()
Output:
And changing labels and shapes too:
# Author: Aric Hagberg (hagberg#lanl.gov)
import matplotlib.pyplot as plt
import networkx as nx
G = nx.Graph()
G.add_edge('a', 'b', weight=0.6)
G.add_edge('a', 'c', weight=0.2)
G.add_edge('c', 'd', weight=0.1)
G.add_edge('c', 'e', weight=0.7)
G.add_edge('c', 'f', weight=0.9)
G.add_edge('a', 'd', weight=0.3)
elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5]
esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5]
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nx.draw_networkx_nodes(G, pos, node_size=700, nodelist=['e','f','b'])
nx.draw_networkx_nodes(G, pos, node_size=1400, nodelist=['c','a','d'],
node_color='blue', node_shape='^')
# edges
nx.draw_networkx_edges(G, pos, edgelist=elarge,
width=6)
nx.draw_networkx_edges(G, pos, edgelist=esmall,
width=6, alpha=0.5, edge_color='b', style='dashed')
# labels
nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif',
labels={'f':'f','e':'e','b':'b'})
nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif', font_color='white',
labels={'d':'d','a':'a','c':'c'})
plt.axis('off')
plt.show()
Output:

Create input arrows in networkx

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:
Is that possible?
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"))
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()

NetworkX: 'Graph'

I have the following error:
Traceback (most recent call last):
File "net.py", line 6, in <module>
G=nx.Graph()
AttributeError: 'module' object has no attribute 'Graph'
when I run this code:
import networkx as nx
import pylab as py
blue_edges = [('B', 'C'), ('B', 'D'), ('B', 'E'), ('E', 'F')]
red_edges = [('A', 'B'), ('A', 'C'), ('C', 'E'), ('D', 'E'), ('D', 'F')]
G=nx.Graph() #define G
G.add_edges_from(blue_edges)
G.add_edges_from(red_edges)
pos = {'A':(0,0), 'B':(1,1), 'C':(1,-1), 'D':(2,1), 'E':(2,-1), 'F':(3,0)}
nx.draw_networkx(G, pos=pos, edgelist = [], node_color = 'k')
nx.draw_networkx(G, pos=pos, nodelist = [], edgelist = blue_edges, edge_color = 'b')
nx.draw_networkx(G, pos=pos, nodelist = [], edgelist = red_edges, edge_color = 'r')
I use python 2.7 and 1.11 networkx library all within anaconda

how to draw multigraph in networkx using matplotlib or graphviz

when I pass multigraph numpy adjacency matrix to networkx (using from_numpy_matrix function)
and then try to draw the graph using matplotlib, it ignores the multiple edges.
how can I make it draw multiple edges as well ?
Graphviz does a good job drawing parallel edges. You can use that with NetworkX by writing a dot file and then processing with Graphviz (e.g. neato layout below). You'll need pydot or pygraphviz in addition to NetworkX
In [1]: import networkx as nx
In [2]: G=nx.MultiGraph()
In [3]: G.add_edge(1,2)
In [4]: G.add_edge(1,2)
In [5]: nx.write_dot(G,'multi.dot')
In [6]: !neato -T png multi.dot > multi.png
On NetworkX 1.11 and newer, nx.write_dot doesn't work as per issue on networkx github. The workaround is to call write_dot using
from networkx.drawing.nx_pydot import write_dot
or
from networkx.drawing.nx_agraph import write_dot
You can use matplotlib directly using the node positions you calculate.
G=nx.MultiGraph ([(1,2),(1,2),(1,2),(3,1),(3,2)])
pos = nx.random_layout(G)
nx.draw_networkx_nodes(G, pos, node_color = 'r', node_size = 100, alpha = 1)
ax = plt.gca()
for e in G.edges:
ax.annotate("",
xy=pos[e[0]], xycoords='data',
xytext=pos[e[1]], textcoords='data',
arrowprops=dict(arrowstyle="->", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle="arc3,rad=rrr".replace('rrr',str(0.3*e[2])
),
),
)
plt.axis('off')
plt.show()
You can use pyvis package.
I just copy-paste this code from my actual project in Jupyter notebook.
from pyvis import network as pvnet
def plot_g_pyviz(G, name='out.html', height='300px', width='500px'):
g = G.copy() # some attributes added to nodes
net = pvnet.Network(notebook=True, directed=True, height=height, width=width)
opts = '''
var options = {
"physics": {
"forceAtlas2Based": {
"gravitationalConstant": -100,
"centralGravity": 0.11,
"springLength": 100,
"springConstant": 0.09,
"avoidOverlap": 1
},
"minVelocity": 0.75,
"solver": "forceAtlas2Based",
"timestep": 0.22
}
}
'''
net.set_options(opts)
# uncomment this to play with layout
# net.show_buttons(filter_=['physics'])
net.from_nx(g)
return net.show(name)
G = nx.MultiDiGraph()
[G.add_node(n) for n in range(5)]
G.add_edge(0, 1, label=1)
G.add_edge(0, 1, label=11)
G.add_edge(0, 2, label=2)
G.add_edge(0, 3, label=3)
G.add_edge(3, 4, label=34)
plot_g_pyviz(G)
result
Refer to atomh33ls's answer
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import random as rd
column_from = 'from_here'
column_to = 'to_there'
column_attribute = 'edges_count'
# test data
pdf = pd.DataFrame([
['a', 'b', 3],
['b', 'a', 1],
['a', 'c', 1],
['b', 'c', 1],
['a', 'd', 1],
['e', 'b', 2],
['c', 'f', 1],
['f', 'g', 1]],
columns=[column_from, column_to, column_attribute])
with pd.option_context('display.max_rows', None, 'display.max_columns', None): # more options can be specified also
print(pdf)
def get_adjacency_matrix(pdf):
id_set = set(pdf[column_from].drop_duplicates().values.tolist() +
pdf[column_to].drop_duplicates().values.tolist())
id_dict_kv = {k : v for k, v in enumerate(id_set)}
id_dict_vk = {v : k for k, v in id_dict_kv.items()}
count = len(id_set)
adjacency_matrix = np.zeros([count, count], dtype='int32')
for row in pdf.itertuples():
index_from = id_dict_vk[getattr(row, column_from)]
index_to = id_dict_vk[getattr(row, column_to)]
adjacency_matrix[index_from, index_to] += getattr(row, column_attribute)
label_mapping = id_dict_kv
return adjacency_matrix, label_mapping
def pdf_to_MDG(pdf):
adjacency_matrix, label_mapping = get_adjacency_matrix(pdf)
G = nx.from_numpy_matrix(adjacency_matrix, parallel_edges=True, create_using=nx.MultiDiGraph())
G = nx.relabel_nodes(G, label_mapping)
return G
MDG = pdf_to_MDG(pdf)
edges_data = MDG.edges.data(column_weight)
print(edges_data)
#—————————————————————————————just see the below: draw MultiDiGraph—————————————————————————————————
pos = nx.spring_layout(MDG, seed = 1)
nx.draw(MDG, pos, with_labels=True, edge_color = (1,1,1))
for e in MDG.edges:
plt.gca().annotate("",
xy=pos[e[1]],
xycoords='data',
xytext=pos[e[0]],
textcoords='data',
arrowprops=dict(arrowstyle="->", color="0",
shrinkA=15, shrinkB=15,
patchA=None, patchB=None,
connectionstyle="arc3,rad=rrr".replace('rrr',str(rd.random()*0.5+0.1)))
)
plt.axis('off')
plt.show()
output:
from_here to_there edges_count
0 a b 3
1 b a 1
2 a c 1
3 b c 1
4 a d 1
5 e b 2
6 c f 1
7 f g 1
[('c', 'f', 1), ('e', 'b', 1), ('e', 'b', 1), ('b', 'c', 1), ('b', 'a', 1), ('f', 'g', 1), ('a', 'c', 1), ('a', 'd', 1), ('a', 'b', 1), ('a', 'b', 1), ('a', 'b', 1)]
the output img

Categories