Reputation: 331
I want to represent a series of data using the networkx
library for Python3 but I do not know how to approach the problem.
Basically I have a relation
between two entities
which is in a csv file called nations.csv
. It looks like this:
China, Economicaid, Egypt
China, Economicaid, Indonesia
USSR, Economicaid, Cuba
USSR, Economicaid, India
USSR, Economicaid, Poland
UK, Economicaid, India
UK, Economicaid, Jordan
USA, Economicaid, Brazil
Understanding that the first row is one of the entity which is related to the third row (entity 2) between the second one:
I've parsed the csv file in order to store each of the rows in a dictionary, as follows:
d = {}
d['entity1'] = []
d['relation'] = []
d['entity2'] = []
dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames =
['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')
for row in dictReader:
for key in row:
d[key].append(row[key])
What I've managed to do is plot the nodes using the function add_node()
like the following example:
import csv
import networkx as nx
import matplotlib.pyplot as plt
d = {}
d['entity1'] = []
d['relation'] = []
d['entity2'] = []
dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames = ['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')
for row in dictReader:
for key in row:
d[key].append(row[key])
print()
for i in range (1, len(d['entity1'])):
r.append(d['entity1'][i])
for k in range (1, len(d['entity2'])):
o.append(d['entity2'][k])
G=nx.Graph()
for j in range(len(r)):
G.add_node(r[j])
G.add_node(o[j])
nx.draw_networkx(G, with_labels = True, node_size = 500)
plt.show()
But the problem comes when I want to represent the edges between the nodes, because it is not only the edge itself, it also has its own label with the meaning.
Upvotes: 2
Views: 1325
Reputation: 13031
Basically, the flag with_labels
should really be called with_node_labels
as it triggers only the plotting of the node labels. Hence you need to manually add the edge labels (networkx.draw_networkx_edge_labels
) after having drawn the graph (networkx.draw`), and you need to 1) plot on the same axis, and 2) use the same graph layout for both plots.
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
import csv
# load data
dictReader = csv.DictReader(open('nations.csv', 'rt'), fieldnames = ['entity1', 'relation', 'entity2'], delimiter = ',', quotechar = '"')
# create a more amenable data structure
edge_to_label = {(d['entity1'], d['entity2']) : d['relation'] for d in dictReader}
# create graph
G = nx.from_edgelist(edge_to_label.keys())
# precompute layout (default layout used here)
layout = nx.layout.fruchterman_reingold_layout(G)
# create figure so we plot the graph and labels on the same plot
fig, ax = plt.subplots(1,1)
# draw graph
nx.draw(G, pos=layout, ax=ax, with_labels=True)
# draw labels using the same, pre-computed graph layout
nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=edge_to_label, ax=ax)
plt.show()
Upvotes: 2