I have a undirected graph with 47 nodes and 90 weighted edges. I want to get the image of this graph, but I get something weird[1]: nodes are on top of each other. I want to fix it but I don't know how. Here is the code for drawing:
import networkx as nx
import matplotlib.pyplot as plt
import pylab
def show_graph(G):
pos = nx.spring_layout(G)
nx.draw(G, pos, node_color='#A0CBE2', edge_color='#BB0000', width=2, edge_cmap=plt.cm.Blues, with_labels=True)
plt.savefig("graph.png", dpi=1000)
# 2 way
# nx.draw(G, with_labels=True)
# plt.draw()
# plt.show()
f = open("europe.txt")
G = nx.Graph()
lines = f.readlines()
edges = list()
for line in lines:
tmp = line.split(', ')
tmp[2] = int(tmp[2])
edges.append(tmp)
G.add_weighted_edges_from(edges)
show_graph(G)
Image [1]: https://i.stack.imgur.com/B5Slx.png
The solution for me was:
import networkx as nx
import matplotlib.pyplot as plt
and the function
def show_graph(G):
plt.subplot(111)
nx.draw(G, pos=nx.planar_layout(G), node_color='r', edge_color='b', with_labels=True)
plt.show()
A planar layout made sense for my situation
Related
I have written a code to create a graph from csv file as below
import matplotlib.pyplot as plt
import networkx as nx
import pandas as pd
df = pd.read_csv("pracmap.csv")
g = nx.Graph()
Vlandict = {}
for idx, e in df.iterrows():
edge_list = []
EL={}
ctr = 1
for dev in ['DEVICE1', 'DEVICE3', 'DEVICE4', 'DEVICE2']:
# print(e[dev])
if e[dev] == "NONE":
continue
edge_list.append(e[dev])
# print(edge_list)
if ctr == 2:
unode = edge_list[0]
vnode = edge_list[1]
Vlandict[(unode, vnode)] = e['VLAN']
edge_list.reverse()
edge_list.pop()
else:
ctr = ctr +1
print(g.nodes)
pos = nx.spring_layout(g, k=0.5, iterations=20)
nx.draw_networkx_edge_labels(g, pos, edge_labels=Vlandict, font_color='green',label_pos=0.5, rotate=False, font_size=8)
nx.draw(g, with_labels=1,node_shape="s",bbox=dict(facecolor="orange", edgecolor='black', boxstyle='round,pad=0.2'))
plt.savefig("pracmappp.png", format="PNG")
plt.show()
This kind of image i am getting where my edge labels are not positioned properly. I want to position these edges labels on edges:
link for csv file
this is the csv file i was using
instead of
nx.draw(g, with_labels=1,node_shape="s",bbox=dict(facecolor="orange", edgecolor='black', boxstyle='round,pad=0.2'))
use
nx.draw(g, pos=pos, with_labels=1,node_shape="s",bbox=dict(facecolor="orange", edgecolor='black', boxstyle='round,pad=0.2'))
I have a regular grid network made of NxN nodes. I am able to plot it, but I would also like to plot its minimum spanning tree, which is a "subgraph that contains all the vertices and is a tree".
This is how I create the network:
from __future__ import print_function, division
import numpy
from numpy import *
import networkx as nx
from networkx import *
import matplotlib.pyplot as plt
N=30
G=nx.grid_2d_graph(N,N)
pos = dict( (n, n) for n in G.nodes() )
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
nx.relabel_nodes(G,labels,False)
inds=labels.keys()
vals=labels.values()
inds.sort()
vals.sort()
pos2=dict(zip(vals,inds))
nx.draw_networkx(G, pos=pos2, with_labels=False, node_size = 15)
This is how I compute the Minimum Spanning Tree:
T=nx.minimum_spanning_tree(G)
This generates a graph just like G, with the difference that T has the same nodes as G and a selection of its edges. Therefore, I would like to plot T, and this is what I did:
plt.figure()
nx.draw_networkx(G, pos=pos2, with_labels=False, node_size = 15)
plt.show()
But I simply get the network plotted again. How can I amend the last lines to make sure my Minimum Spanning Tree is plotted?
plt.figure()
nx.draw_networkx(G, pos=pos2, with_labels=False, node_size = 15)
plt.show()
should be
plt.figure()
nx.draw_networkx(T, pos=pos2, with_labels=False, node_size = 15)
plt.show()
I use this piece of code to draw a bipartite graph using networkX:
import networkx as nx
G = bipartite.from_biadjacency_matrix(a_matrix, create_using=None, edge_attribute='weight')
X, Y = bipartite.sets(G)
pos = dict()
pos.update((n, (0, i*10)) for i, n in enumerate(X))
pos.update((n, (0.5, i*10)) for i, n in enumerate(Y))
nx.draw(G, pos=pos)
Is there a way to randomly change colours of different sets of nodes and edges between them?
Generate some random numbers:
edge_color=np.random.random(num_edges)
node_color=np.random.random(num_nodes)
and set the edge color map:
edge_cmap=plt.get_cmap('Blues')
and node color map:
cmap=plt.get_cmap('Reds')
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from networkx.algorithms import bipartite
import scipy.sparse as sparse
a_matrix = sparse.rand(10, 10, format='coo', density=0.8)
G = bipartite.from_biadjacency_matrix(a_matrix, create_using=None,
edge_attribute='weight')
X, Y = bipartite.sets(G)
pos = dict()
pos.update((n, (0, i*10)) for i, n in enumerate(X))
pos.update((n, (0.5, i*10)) for i, n in enumerate(Y))
num_edges = G.number_of_edges()
num_nodes = G.number_of_nodes()
nx.draw(G, pos=pos, with_labels=True,
edge_color=np.random.random(num_edges),
edge_cmap=plt.get_cmap('Blues'),
node_color=np.random.random(num_nodes),
cmap=plt.get_cmap('Reds'))
plt.show()
You could use subgraphs to color connected nodes:
C = nx.connected_component_subgraphs(G)
for g in C:
node_colors = [random.random()] * nx.number_of_nodes(g)
nx.draw(g, pos, node_size=40, node_color=node_colors, vmin=0.0, vmax=1.0, with_labels=False )
This is my code in Python 2.7.9:
import matplotlib.pyplot as plt
import networkx as nx
socialNetworl = nx.Graph()
socialNetworl.add_nodes_from([1,2,3,4,5,6])
socialNetworl.add_edges_from([(1,2),(1,3),(2,3),(2,5),(2,6)])
nx.draw(socialNetworl, node_size = 800, node_color="cyan")
plt.show()
But I can't see the node labels. Is there a line of code I forgot?
Just add with_labels=True to your code.
import matplotlib.pyplot as plt
import networkx as nx
socialNetworl = nx.Graph()
socialNetworl.add_nodes_from([1,2,3,4,5,6])
socialNetworl.add_edges_from([(1,2),(1,3),(2,3),(2,5),(2,6)])
nx.draw(socialNetworl, node_size = 800, node_color="cyan", with_labels = True)
plt.show()
If you want to change the labels, create a dict with the labels and pass labels=theLabelDict into nx.draw:
import matplotlib.pyplot as plt
import networkx as nx
socialNetworl = nx.Graph()
socialNetworl.add_nodes_from([1,2,3,4,5,6])
socialNetworl.add_edges_from([(1,2),(1,3),(2,3),(2,5),(2,6)])
labels = {1:'King Arthur', 2:'Lancelot', 3:'shopkeeper', 4:'dead parrot', 5:'Brian', 6:'Sir Robin'}
nx.draw(socialNetworl, node_size = 800, node_color="cyan", labels=labels, with_labels = True)
plt.show()
You can draw the node labels separately with nx.draw_networkx_labels (and control lots of other label options too). For example, after adding the nodes and edges, you could write:
pos=nx.spring_layout(socialNetworl)
nx.draw(socialNetworl, pos=pos, node_size = 800, node_color="cyan")
nx.draw_networkx_labels(socialNetworl, pos=pos);
plt.show()
Which draws:
I am trying to get a colorbar for edges in a networkx graph. Here is a code snippet
import networkx as nx
import matplotlib.colors as colors
import matplotlib.cm as cmx
n = 12 # Number of clusters
w = 21 # Number of weeks
m = Basemap(
projection='merc',
ellps = 'WGS84',
llcrnrlon=-98.5,
llcrnrlat=25,
urcrnrlon=-60,
urcrnrlat=50,
lat_ts=0,
resolution='i',
suppress_ticks=True)
mx, my = m(list(ccentroids['lon']), list(ccentroids['lat']))
# The NetworkX part
# put map projection coordinates in pos dictionary
G = nx.DiGraph()
G.add_nodes_from(range(n))
for i in range(n):
for j in range(n):
if P_opt[i,j] > 0.5 and i != j:
G.add_edge(i,j, weight = P_opt[i,j])
pos = {i : (mx[i], my[i]) for i in range(n)}
# Add a color_map for the edges
jet = cm = plt.get_cmap('jet')
cNorm = colors.Normalize(vmin=0, vmax=np.max(P_opt))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
colorList = []
weights_list = []
for i in G.edges():
a, b = i
colorVal = scalarMap.to_rgba(G.edge[a][b]['weight'])
colorList.append(colorVal)
weights_list.append(G.edge[a][b]['weight'])
plt.clf()
fig = plt.figure()
ax = fig.add_subplot(111, axisbg='w', frame_on=False)
fig.set_size_inches(18.5, 10.5)
# draw the network
nodes = nx.draw_networkx_nodes(G, pos, node_size=100, node_color=q[:,t], cmap = plt.cm.jet,
font_size=8, with_labels=False, label='Cluster centroids')
edges = nx.draw_networkx_edges(G, pos, edge_color=colorList)
m.drawcountries()
m.bluemarble()
This gives me the following image:
Now I want to add a colorbar for the edges. I tried doing something like,
plt.sci(edges)
edges.set_array(np.array(weights_list))
plt.colorbar(shrink = 0.8)
This gives me an image like:
The colours of the arrows and edges seem to differ. How can I correct that? Thanks.
EDIT: I tried to use the following code by modifying the edge line:
edges = nx.draw_networkx_edges(G, pos, edge_color=colorList, edge_cmap = plt.cm.jet)
plt.colorbar(edges)
This gives me an error TypeError: You must first set_array for mappable
Changing the edge_color to be the weights_list I get the following picture:
It seems you are getting the colomap/colorbar for the nodes. Here is how to set a colormap and draw a colorbar for edge colors:
![import networkx as nx
import matplotlib.pyplot as plt
G = nx.star_graph(20)
pos = nx.spring_layout(G)
colors = range(20)
nodes = nx.draw_networkx_nodes(G,pos,node_color='k', with_labels=False)
edges = nx.draw_networkx_edges(G,pos,edge_color=colors,width=4,
edge_cmap=plt.cm.Blues)
plt.colorbar(edges)
plt.axis('off')
I know this is an old one, but I spent some time figuring this out, and maybe it is still useful for someone.
nx.draw_networkx_edges
returns
matplotlib.collection.LineCollection
if there are no arrows.
returns
list of matplotlib.patches.FancyArrowPatch
if there are arrows.
docs
For my specific case I could get a colorbar like in Aric's answer only if I set arrows to False:
edges = nx.draw_networkx_edges(G, edge_color=colors, arrows=False)
plt.colorbar(edges)