J'utilise Python pour simuler un processus qui a lieu sur des graphiques dirigés. Je voudrais produire une animation de ce processus.
Le problème que j'ai rencontré est que la plupart Python bibliothèques de visualisation graphique combinent des paires d'arêtes dirigées dans un seul bord. Par exemple, NetworkX ne dessine que deux bords lorsque Affichage du graphique suivant, alors que je souhaiterais afficher chacun des quatre bords séparément:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.MultiDiGraph()
G.add_edges_from([
(1, 2),
(2, 3),
(3, 2),
(2, 1),
])
plt.figure(figsize=(8,8))
nx.draw(G)
Je voudrais afficher quelque chose comme ça, avec chaque bord parallèle dessiné séparément:
La question arêtes réciproques dans IGraph in r semble traiter du même problème, mais la solution existe pour la bibliothèque R IGraph, et non le Python un.
Existe-t-il un moyen facile de produire ce style d'intrigue à l'aide d'un fichier existant Python Bibliothèque de visualisation graphique? Ce serait un bonus s'il pouvait supporter des multigrans.
Je suis ouvert aux solutions qui invoquent un programme externe pour produire les images. J'aimerais générer une série de cadres d'animation. La solution doit donc être automatisée.
Les outils graphviz semblent afficher des bords distincts.
Par exemple, donner ceci:
digraph G {
A -> B;
A -> B;
A -> B;
B -> C;
B -> A;
C -> B;
}
à dot
produit:
La langue d'entrée de GRAPHVIZ est assez simple afin que vous puissiez la générer seul, bien que la recherche de "python graphviz" présente quelques bibliothèques comprenant un graphviz
module sur PYPI .
Voici python qui génère le graphe ci-dessus à l'aide du module graphviz
:
from graphviz import Digraph
dot = Digraph()
dot.node('A', 'A')
dot.node('B', 'B')
dot.node('C', 'C')
dot.edges(['AB', 'AB', 'AB', 'BC', 'BA', 'CB'])
print(dot.source)
dot.render(file_name, view=True)
Utilisation de NetworkX, une solution de contournement éventuelle qui évite le fichier E/S et utilise le point par pydot pour la mise en page.
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from io import BytesIO
g = nx.dodecahedral_graph()
d = nx.drawing.nx_pydot.to_pydot(g) # d is a pydot graph object, dot options can be easily set
# attributes get converted from networkx,
# use set methods to control dot attributes after creation
png_str = d.create_png()
sio = BytesIO() # file-like string, appropriate for imread below
sio.write(png_str)
sio.seek(0)
img = mpimg.imread(sio)
imgplot = plt.imshow(img)
pour pourquoi seek(0)
est nécessaire, voir Comment créer une image à partir d'une chaîne en python
Si, dans la console Ipython (QT), il s'agit alors d'imprimer en ligne et une approche plus directe est la suivante:
import networkx as nx
from IPython.display import Image
g = nx.dodecahedral_graph()
d = nx.drawing.nx_pydot.to_pydot(g)
png_str = d.create_png()
Image(data=png_str)
Peut-être que je suis un peu tardif mais j'ai trouvé une autre solution à votre problème, alors je l'affiche afin que cela puisse être utile si quelqu'un a le même problème. Cela ajoute l'argument ConnectionStyle argument à NX.DRAW:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.MultiDiGraph()
G.add_edges_from([
(1, 2),
(2, 3),
(3, 2),
(2, 1),
])
plt.figure(figsize=(8,8))
nx.draw(G, connectionstyle='arc3, rad = 0.1',)
Ici vous voyez le résultat: