0

i have stared nodes positions with networkx but matplotlib render it at wrong place. What is very important is to get the same picture each time i launch the script : so, nodes coordinates respect is fundamental.

Also, the view is too compact, forcing me too manually zoom inside, and appears in figure2 in place of figure1. finally, matplotlib works on little float scale [-1,1] where i prefer screen dimension x [0,1280] and y [0,704].

i have tried many source code but it still doesnt do the job properly

import matplotlib.pyplot as plt
import networkx as nx

zero_zero = 'zero_zero'
zero_one = 'zero_one'
one_zero = 'one_zero'
one_one = 'one_one'

foo_1 = 'foo_1'
foo_2 = 'foo_2'
foo_3 = 'foo_3'
bar_1 = 'bar_1'
bar_2 = 'bar_2'
bar_3 = 'bar_3'

stuff_1 = 'stuff_1'
stuff_2 = 'stuff_2'
stuff_3 = 'stuff_3'
waow = 'waow'


fig = plt.figure(figsize=(100,100))

fig, ax = plt.subplots()
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5 , 1.5)
G = nx.Graph()

starpos={zero_zero:(0,0), zero_one:(0,1), one_zero:(1,0), one_one:(1,1), foo_1:(1,0),foo_2:(0.1,0.1),foo_3:(0.2,0.3),bar_1:(0.3,0.2),bar_2:(0.76,.80),bar_3:(0,0.2),stuff_1:(0.8,0.6),stuff_2:(0.3,0.9),stuff_3:(0.7,0.7),waow:(0.4,0.6)}    

for k,v in starpos.items():
    G.add_node(k,pos=v)


G.nodes(data=True)


G.add_edge(foo_1, foo_2)

G.add_edge(foo_3, bar_3)
G.add_edge(bar_1, foo_3)
G.add_edge(bar_1, bar_2)
G.add_edge(bar_3, bar_2)


G.add_edge(stuff_1, stuff_3)
G.add_edge(waow, bar_3)
G.add_edge(bar_2, stuff_3)


G.add_edge(zero_zero, zero_one)
G.add_edge(zero_one, one_zero)
G.add_edge(one_zero, one_one)
G.add_edge(one_one, zero_zero)

pos = nx.spring_layout(G)


nx.draw(G, pos, font_size=16, with_labels=False)
for p in pos:  # raise text positions
    pos[p][1] += 0.07
nx.draw_networkx_labels(G, pos)

plt.show()

networkx matplotlib picture

laticoda
  • 100
  • 14

1 Answers1

0

Let's first deal with a misconception: even though you've assigned an attribute 'pos' to each node in the graph, the drawing commands don't use that at all.

When you do:

nx.draw(G, pos)

the argument pos is a dictionary whose keys are the nodes of G and whose values are the positions you want them to be in. In your case, you've defined pos using pos=nx.spring_layout(G). In this command, each node is initially given a random position, and then it treats the nodes as masses which are connected by springs and tries to find where the nodes would move to. So every time it will find a different arrangement, and - this is important - it doesn't care at all about the node attributes you've defined.

In your case, you've already defined the dictionary starpos, which I believe has the desired position of each node. So there's no need to assign an attribute when you create the nodes [since networkx doesn't use the attributes to assign positions]. Then when you draw it, use the dictionary you've already created rather than using spring_layout to create a new one. Try

nx.draw(G, starpos, font_size=16, with_labels=False)
Joel
  • 22,598
  • 6
  • 69
  • 93
  • Yes Joel ! How to have it just on Figure one (i have one extra useless blank figure) with the legend uppon each node ? i get this traceback: starpos[p][1] += 0.07 TypeError: 'tuple' object does not support item assignment – laticoda Nov 07 '19 at 19:18
  • So that error is because if you have a tuple, say for example `(1,2)`, it is [*immutable*](https://stackoverflow.com/questions/1538663/why-are-python-strings-and-tuples-are-made-immutable) - Python does not let you change a tuple. One option is to have a new dict `labelpos` for labels: `labelpos = {p, (x,y+0.07) for p, (x,y) in starpos.items()}`. Another option is to use lists instead of tuples for the position, so use `[1,2]`, which will allow you to do the steps you use. – Joel Nov 07 '19 at 22:27
  • For the extra figure: take a look at the two places where you define `fig`. Think about what you *want* to happen with the first `fig`, and then check your code for whether you tell it to do that or not. What's happening is that your first `fig` is becoming your extra empty plot. – Joel Nov 07 '19 at 22:36