Dessiner un graphique de clique avec
import networkx as nx
....
nx.draw(G, layout=nx.spring_layout(G))
produit l'image suivante:
De toute évidence, l'espacement entre les nœuds (par exemple, la longueur du bord) doit être augmenté. J'ai googlé ceci et trouvé cette suggestion ici:
Pour certains des algorithmes de disposition, il existe un paramètre
scale
qui pourrait aider. par exemple.import networkx as nx G = nx.path_graph(4) pos = nx.spring_layout(G) # default to scale=1 nx.draw(G, pos) pos = nx.spring_layout(G, scale=2) # double distance between all nodes nx.draw(G, pos)
Cependant, le paramètre scale
ne semble pas avoir d'effet.
Quelle est la bonne méthode pour obtenir un meilleur dessin?
D'accord, ma réponse est trop tard pour cette question. Mais la solution à ce problème réside dans la version NetworkX 1.8 qui n'est pas encore sortie, mais qui est disponible via git hub.
Procédez comme suit pour augmenter la distance entre les nœuds:
pos = nx.spring_layout(G,k=0.15,iterations=20)
# k controls the distance between the nodes and varies between 0 and 1
# iterations is the number of times simulated annealing is run
# default k =0.1 and iterations=50
Ajustez ces paramètres pour voir comment cela fonctionne. Mais malgré cela, il n'y a aucune garantie que tous les nœuds ne se chevauchent pas
La réponse réelle à votre question est que votre graphique d'origine n'est pas un seul, composant entièrement connecté . Il s'agit de trois graphiques distincts.
Ce qui se passe, c'est que les trois pièces s'envolent à l'infini, ce qui, lors de la mise à l'échelle, fait ressembler chaque composant à une petite goutte.
L'algorithme spring_layout
spécifie une force de répulsion entre tous les nœuds (anti-gravité), et une force d'attraction entre uniquement nœuds connectés (les "ressorts").
Ainsi, si le graphique n'est pas connecté, les pièces individuelles s'éloigneront de la force répulsive car il n'y a rien qui les relie. Il existe deux options: modifier la loi de force (modifier le code networkx) ou représenter graphiquement les composants séparément.
Voici comment ajouter une force qui attire tous les nœuds au centre du graphique. Ajoutez la dernière ligne de cet extrait de code à def _fruchterman_reingold
in layouts.py :
# displacement "force"
displacement = np.einsum('ijk,ij->ik',
delta,
(k * k / distance**2 - A * distance / k))
# ADD THIS LINE - prevent things from flying off into infinity if not connected
displacement = displacement - pos / ( k * np.sqrt(nnodes))
Cette seule ligne de code vous permet de créer des graphiques comme: plutôt que Cependant, la "meilleure" façon de résoudre ce problème est de représenter séparément les composants.
Vous pouvez parcourir les composants, les tracer dans des tracés séparés, avec les fonctions décrites ici .
Voir ce numéro de github pour plus de discussion.
J'ai utilisé le paramètre de distance optimale de la disposition Kamada Kawai et j'ai défini la distance entre les composants non connectés à la distance maximale dans le graphique. Il existe probablement une meilleure façon de connecter les dictionnaires, mais c'est assez simple:
df = pd.DataFrame(index=G.nodes(), columns=G.nodes())
for row, data in nx.shortest_path_length(G):
for col, dist in data.items():
df.loc[row,col] = dist
df = df.fillna(df.max().max())
layout = nx.kamada_kawai_layout(G, dist=df.to_dict())