When I use networkx.draw to draw the network, python2 and python3 use the same program, but python2 cannot draw correctly

Viewed 114

When I use networkx.draw to draw the network,using the same program with python2 and python3 , but python2 cannot draw correctly. Left is py3, right is py2.


 import scipy
 import numpy as np
 import networkx as nx
 import matplotlib.pyplot as plt
 
 N = [("n{}".format(i), 0) for i in range(1,7)] + \ 
     [("n{}".format(i), 1) for i in range(7,13)] + \ 
     [("n{}".format(i), 2) for i in range(13,19)]
 E = [("n1","n2"), ("n1","n3"), ("n1","n5"),
      ("n2","n4"),
      ("n3","n6"), ("n3","n9"),
      ("n4","n5"), ("n4","n6"), ("n4","n8"),
      ("n5","n14"),
      ("n7","n8"), ("n7","n9"), ("n7","n11"),
      ("n8","n10"), ("n8","n11"), ("n8", "n12"),
      ("n9","n10"), ("n9","n14"),
      ("n10","n12"),
      ("n11","n18"),
      ("n13","n15"), ("n13","n16"), ("n13","n18"),
      ("n14","n16"), ("n14","n18"),
      ("n15","n16"), ("n15","n18"),
      ("n17","n18")]

 G = nx.Graph()
 print(list(map(lambda x: x[0], N)))
 G.add_nodes_from(list(map(lambda x: x[0], N)))
 G.add_edges_from(E)
 ncolor = ['r']*6+['g']*6+['b']*6
 nsize = [700] * 6 + [700] * 6 + [700] * 6
 nx.draw(G, with_labels=True, font_weight='bold',
         node_color=list(ncolor), node_size=nsize)
 plt.savefig("graph.png")
 plt.show()

enter image description here

2 Answers

For pythons older than 3.6 dictionaries does not maintain insertion order. Hence you might end up with those colors being assigned to different nodes. Try enforcing a nodelist when drawing using nodelist:

G = nx.Graph()
G.add_nodes_from(list(map(lambda x: x[0], N)))
G.add_edges_from(E)
ncolor = ['r']*6+['g']*6+['b']*6
nsize = [700] * 6 + [700] * 6 + [700] * 6
nodelist = [n[0] for n in N] 
nx.draw(G, with_labels=True, font_weight='bold',
     node_color=list(ncolor), node_size=nsize,
     nodelist=nodelist)
plt.savefig("graph.png")
plt.show()

If the differences between the figures is only the color (and for sure the positioning), then you can try to replace

ncolor = ['r']*6+['g']*6+['b']*6

with the following:

color_dict = {"n{}".format(i): "r" for i in range(1, 7)}
color_dict.update({"n{}".format(i): "g" for i in range(7, 13)})
color_dict.update({"n{}".format(i): "b" for i in range(13, 19)})
ncolor = [color_dict[node] for node in G]

Background

If I remember correctly, dict in python 2 do not necessarily preserve the order of added elements. Hence, "n0" does not need to be the first element in G. In python 3, they started to preserve the ordering and consequently you color the desired nodes.

Related