Reputation: 23
I want to make a circular network graph with nodes linked by an arc I just started using networkx
I found the correct ways of doing arcs for my edges but some of them have an inverted curve ...
here is the full code
import random
from math import cos, sin
import matplotlib
import networkx as nx
from matplotlib import pyplot as plt
from pyvis.network import Network
import scipy as sp
def get_coordinates_in_circle(n, scale):
return_list = []
for i in range(n):
theta = float(i) / n * 2 * 3.141592654
y = cos(theta)
x = sin(theta)
return_list.append((x * scale, y * scale))
# print(return_list)
return return_list
def draw_number(length):
"""determines a random index number for selection."""
from_index = random.randint(0, length)
to_index = random.randint(0, length)
return from_index, to_index
def netw(NodesN):
G = nx.Graph()
node_list = []
fixed_positions = {} # dict with two of the positions set
for i in range(1, NodesN + 1):
node_list.append(i)
CirclePos = get_coordinates_in_circle(NodesN, 1)
# jump by 1
from_list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
to_list1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
# jump by 2
from_list2 = [1,3,5,7,9]
to_list2 = [3,5,7,9,1]
# jump by 3
from_list3 = [1,4,7,10,3 ]
to_list3 = [4,7,10,3,6]
from_list = from_list1
to_list = to_list1
for i in range(len(node_list)):
G.add_node(node_list[i])
fixed_positions[i+1] = CirclePos[i]
for j in range(len(from_list)):
G.add_edges_from([(from_list[j], to_list[j])])
fixed_nodes = fixed_positions.keys()
pos = nx.spring_layout(G, pos=fixed_positions, fixed=fixed_nodes)
# pos = nx.kamada_kawai_layout(G, pos=fixed_positions)
nx.draw_networkx_nodes(G,pos)
nx.draw_networkx_labels(G,pos)
nx.draw_networkx_edges(G,pos,arrows=True,connectionstyle=f"arc3,rad=.5")
# nx.draw_networkx(G,pos)
plt.show()
netw(10)
it gives me the correct thing except for the 10->1 edge and if I change the "jump by" list the problem change place and make the "inverted" arc when an edge goes from a big number to a small number
I understood part of my problem with this to replace my coordinates in the "get_coordinates_in_circle" func
it just gives me a line instead of a circle (not what I want just an aid to understant my problem)
return_list = [(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9),]
my question is: is ther a way to make it thinks its a closed loop?
draw_circular does not do that
Upvotes: 0
Views: 292
Reputation: 4772
The inconsistency in the arc direction comes from the fact that you're using a Graph
instead of a DiGraph
. If we change the first line of the netw
function definition to G = nx.Graph()
, we end up with the following:
Also, if you want to invert the curvature of the edges, you can use a negative number for rad in the connectionstyle specification. For instance, using connectionstyle=f"arc3,rad=-.5"
yields the following result:
By the way, here's a refactored version of your code.
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
def netw(NodesN, jump = 1):
node_list = list(range(1,NodesN + 1))
from_list = node_list[::jump]
to_list = from_list[1:] + from_list[:1]
#
# I suspect you're actually trying to do this with the "jump by" number:
#
# from_list = node_list
# to_list = from_list[jump:] + from_list[:jump]
G = nx.DiGraph()
G.add_nodes_from(node_list)
G.add_edges_from(zip(from_list, to_list))
pos = nx.circular_layout(G)
# If you really want the nodes to go clockwise starting from the top, here's a quick approach.
# Just uncomment the block below
#
# c,s = pos[node_list[0]]
# R_mat = np.array([[-s,c],[c,s]])
# for k,v in pos.items():
# pos[k] = R_mat @ v
nx.draw_networkx(G, pos = pos, connectionstyle=f"arc3,rad=.5")
plt.show()
netw(10, jump = 1)
Upvotes: 1