NetworkX: 'Graph' - python

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

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.

Networkx: how to change a color and size of same edges?

I generated a graph using networkx
import networkx as nx
G = nx.grid_graph(dim=[5,5])
nx.draw(G);
Then I compute the minimal path between two nodes using the astar algorithm
def dist(a, b):
(x1, y1) = a
(x2, y2) = b
return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
nodes = list(G.nodes)
tmp = nx.astar_path(G,nodes[3],nodes[14],dist)
Now I would like to to modify the color and the size of the edges of the path between the nodes, where the nodes are defined by tmp
tmp
[(0, 3), (1, 3), (2, 3), (2, 4)]
You need to plot each of the network's components with its own commands. Here is a working code that demonstrates how to achieve such a plot.
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
# only relevant part is treated here
G = nx.grid_graph(dim=[5,5])
node_list = [(0, 3), (1, 3), (2, 3), (2, 4)]
edge_list = [[(0, 3), (1, 3)], [(1, 3), (2, 3)], [(2, 3), (2, 4)]]
pos = nx.spring_layout(G)
nx.draw(G, pos=pos, with_labels=True)
# draw selected nodes in green with triangle shape
nx.draw_networkx_nodes(G, pos=pos, nodelist=node_list, node_size=300, node_color='g', node_shape='^')
# draw selected edges in blue with solid line
nx.draw_networkx_edges(G, pos=pos, edgelist=edge_list, width=3.0, edge_color='blue', style='solid')
The output plot:

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: Drawing Graph

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')

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