1

I am generating a network topology diagram through the data in a csv file where s0..s2 and c1..c3 are nodes of the diagram.

network.csv:

source,port,destination

s1,1,c3

s2,1,c1

s0,1,c2

s1,2,s2

s2,2,s0

I need to make all the source to be blue and destinations to be green. How can I do it without overriding the source nodes?

Sakshi
  • 17
  • 1
  • 6

1 Answers1

5

Following is a working solution:

import csv
import networkx as nx
from matplotlib import pyplot as plt

with open('../resources/network.csv') as csvfile:
    reader = csv.DictReader(csvfile)
    edges = {(row['source'], row['destination']) for row in reader }
print(edges) # {('s1', 'c3'), ('s1', 's2'), ('s0', 'c2'), ('s2', 's0'), ('s2', 'c1')}

G = nx.DiGraph()
source_nodes = set([edge[0] for edge in edges])
G.add_edges_from(edges)
for n in G.nodes():
    G.nodes[n]['color'] = 'b' if n in source_nodes else 'g'

pos = nx.spring_layout(G)
colors = [node[1]['color'] for node in G.nodes(data=True)]
nx.draw_networkx(G, pos, with_labels=True, node_color=colors)
plt.show()

We first read the csv to an edge list, which is later used for the construction of G. For well defining the colors we set each source node with blue and the rest of the nodes as green (i.e., all destination nodes that also not source nodes).

We also use nx.draw_networkx to get a more compact implementation for drawing the graph.

The result should be something like:

enter image description here

zohar.kom
  • 1,765
  • 3
  • 12
  • 28
  • Thank You so much for the help. But sometimes I am getting one source node as green(s2). I have a program where everytime I run the main program(diff python file) I have new connections in the csv. So sometimes when I am running this code I am getting one source node green – Sakshi Jan 29 '19 at 09:12
  • Happy to help :) It's difficult to say why it happens without the actual code and data. Probably the edges / source_nodes are not what you think they are. Try printing them and reproduce such a scenario. Worth saying that the csv part is completely irrelevant to the drawing part, and my guess is that the problem is with reading the csv. – zohar.kom Jan 29 '19 at 10:12
  • Now I have one more node in destination i.e. M0, can you tell me how can I give it a different color than other two nodes please? – Sakshi Jan 31 '19 at 00:56
  • How can I add the edge weight from the CSV from port no. ? example: S11, S21, etc on their edges? – Sakshi Jan 31 '19 at 04:17
  • That's another question, which I'd be happy to answer. Why changing the original question if you accepted an answer? The idea of SO is answering a question once, also for **others**. Now the answer has nothing to do with the question, as it answers the original question. – zohar.kom Jan 31 '19 at 08:17
  • 1
    I am sorry I thought if a generate a new question it might not be noticed by you. – Sakshi Jan 31 '19 at 08:33
  • It's ok, and don't worry SO has a strong community and someone will probably answer your question pretty quickly. For the first question - you control the colors with the line `G.nodes[n]['color'] = 'b' if n in source_nodes else 'g'`. Just change the logic of assigning colors to nodes. – zohar.kom Jan 31 '19 at 09:00
  • For the second question about edge weights: 1. You should read the CSV file with: `edges = [(row['source'], row['destination'], {'w': row['port']}) for row in reader]` 2. You'll need to draw the edge labels with: `nx.draw_networkx_edge_labels(G, pos, edge_labels={(e[0], e[1]): e[2]['w'] for e in G.edges(data=True)})` before running `plt.show()` – zohar.kom Jan 31 '19 at 09:01
  • I am getting this error for the edge weight improvement....unhashable type: 'dict' – Sakshi Jan 31 '19 at 09:26
  • And I don't want only the port no. to be printed as weights but with the corresponding source id, like: s11, s21, s01, etc – Sakshi Jan 31 '19 at 09:28
  • For solving the "unhashable type: 'dict'" error - note that it's `[(row['source'], row['destination'], {'w': row['port']}) for row in reader]` and **NOT** `{(row['source'], row['destination'], {'w': row['port']}) for row in reader}` (**look at the outmost parentheses type**) – zohar.kom Jan 31 '19 at 09:32
  • And for the second part - I'm sure you can take it from here, just concatenate the strings as you wish when creating 'edge_labels'. – zohar.kom Jan 31 '19 at 09:33
  • can you check this one https://stackoverflow.com/questions/54458259/call-dictionary-from-one-function-to-another – Sakshi Jan 31 '19 at 10:20