Center graph Pertersen in jupyter


I would like to know how I can make the graph go straight and not tilted as it is. I'm doing it with the IDE Jupyter and Python 3.6.

This is the code:

import networkx

gP = { 1: [2,5,6], 2: [3,1,7], 3: [4,2,8], 4: [5,3,9], 5: [1,4,10],6: [1,8,9], 
            7:[2,9,10], 8: [3,10,6], 9: [4,6,7], 10: [5,7,8] }

for k in gP:
gP[-1] = list(range(1,11))
gP[-2] = list(range(1,11))

rH = [8, 3, 4, 5, 10, 7, 2, 1, 6, 9];
g = networkx.Graph()
for k, vs in gP.items():
   for v in vs:
      if v in [-1, -2] or k in [-1, -2]:
      if abs(rH.index(k) - rH.index(v)) == 1:
          g.add_edge(k,v, color='red', width=1.5)
          g.add_edge(k,v, color='black', width=0.5)

posicion = networkx.circular_layout(g)
edges = g.edges()
colors = [g[u][v]['color'] for u,v in edges]
width = [g[u][v]['width'] for u,v in edges]
networkx.draw_shell(g, nlist=[range(6,11), range(1,6)], edge_color=colors, width=width, with_labels = True)

Thank you very much.

asked by chuches 07.06.2018 в 15:27

1 answer


In the code you have shown there is a line that says:

posicion = networkx.circular_layout(g)

This line is used to calculate a disposition of the nodes (the coordinates x,y in which each of them should be drawn), so that they are organized in a circle.

Actually this line is superfluous, because you do not do anything later with the positions that you have calculated, since in fact you paint the graph following another arrangement, called "shell". When you call the function draw_shell() , this function internally calls networkx.shell_layout() to calculate where each node would go (in this case disposing them in several circular layers), and also paints the result.

We can separate these two operations explicitly: first calculate where the nodes would go, according to a "layered" provision ( shell ):

posicion = networkx.shell_layout(g, nlist=[range(6,11), range(1,6)])

and then paint it in those positions (note that I now use draw() instead of draw_shell() :

networkx.draw(g, pos=posicion, edge_color=colors, width=width, with_labels = True)

The result at the moment is the same as it would be with your code:

If there was any way to ask networkx.shell_layout() to rotate the positions of the nodes, before asking networkx.draw() to draw it, we would have what you are looking for. Unfortunately, the functions that calculate the arrangement of the nodes do not support any parameter that allows the result to be rotated.

But doing it in two stages allows us to rotate it "by hand", so to speak, because the variable posiciones is a dictionary whose keys are the names of the nodes (numbers in this case) and whose values are the coordinates x,y (in the form of array numpy) where each one should be painted.

We can therefore manipulate the positions of the nodes as we please. The following function uses matrix algebra and numpy to rotate all the points of the graph with respect to the origin, a given angle (clockwise, counterclockwise if the angle is negative):

import numpy as np

def rotate_pos(pos, angle):
  theta = np.radians(angle)
  c, s = np.cos(theta), np.sin(theta)
  R = np.array(((c,-s), (s, c)))
  for k,v in pos.items():
  return newpos

So, to rotate your graph to the left an angle of 360/20 (which is the amount needed in this case for the base of the pentagon to go horizontal, instead of one of its sides going vertical), the code would be:

networkx.draw(g, pos=rotate_pos(posicion, -360/20),
              edge_color=colors, width=width, with_labels=True)

answered by 07.06.2018 / 16:57