Saya ingin menggunakan networkx untuk mempelajari arsitektur proyek yang cukup besar tetapi pengujian yang saya lakukan sejauh ini tidak begitu baik, berikut adalah contoh minimal dari semua penelitian saya:

import matplotlib.pyplot as plt
import networkx as nx
from networkx.readwrite import node_link_graph

G = node_link_graph({'directed': True, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 'build'}, {'id': 'root'}, {'id': 'utils'}, {'id': 'codegen'}, {'id': 'codegen.templates'}, {'id': 'nodes.shapes'}, {'id': 'codegen.c_types'}, {'id': 'nodes'}, {'id': 'containers'}, {'id': 'distutils'}, {'id': 'wheel'}, {'id': 'tools.testing'}, {'id': 'finalizations'}, {'id': 'importing'}, {'id': 'plugins'}, {'id': 'freezer'}, {'id': 'tree'}, {'id': 'specs'}, {'id': 'optimizations'}, {'id': 'plugins.standard'}, {'id': 'tools.general.dll_report'}, {'id': 'tools.specialize'}, {'id': 'tools.testing.compare_with_cpython'}, {'id': 'tools.testing.find_sxs_modules'}, {'id': 'tools.testing.measure_construct_performance'}, {'id': 'tools.testing.run_root_tests'}, {'id': 'tools'}], 'links': [{'source': 'build', 'target': 'root'}, {'source': 'build', 'target': 'utils'}, {'source': 'root', 'target': 'root'}, {'source': 'root', 'target': 'containers'}, {'source': 'root', 'target': 'utils'}, {'source': 'root', 'target': 'finalizations'}, {'source': 'root', 'target': 'freezer'}, {'source': 'root', 'target': 'plugins'}, {'source': 'root', 'target': 'nodes.shapes'}, {'source': 'utils', 'target': 'root'}, {'source': 'utils', 'target': 'utils'}, {'source': 'codegen', 'target': 'codegen'}, {'source': 'codegen', 'target': 'codegen.templates'}, {'source': 'codegen', 'target': 'root'}, {'source': 'codegen', 'target': 'codegen.c_types'}, {'source': 'codegen', 'target': 'utils'}, {'source': 'codegen', 'target': 'nodes.shapes'}, {'source': 'codegen', 'target': 'nodes'}, {'source': 'codegen', 'target': 'containers'}, {'source': 'codegen.templates', 'target': 'root'}, {'source': 'nodes.shapes', 'target': 'codegen.c_types'}, {'source': 'nodes.shapes', 'target': 'codegen'}, {'source': 'nodes.shapes', 'target': 'root'}, {'source': 'nodes.shapes', 'target': 'nodes.shapes'}, {'source': 'codegen.c_types', 'target': 'codegen.templates'}, {'source': 'codegen.c_types', 'target': 'codegen.c_types'}, {'source': 'codegen.c_types', 'target': 'codegen'}, {'source': 'nodes', 'target': 'containers'}, {'source': 'nodes', 'target': 'utils'}, {'source': 'nodes', 'target': 'nodes.shapes'}, {'source': 'nodes', 'target': 'importing'}, {'source': 'nodes', 'target': 'root'}, {'source': 'nodes', 'target': 'optimizations'}, {'source': 'nodes', 'target': 'tree'}, {'source': 'nodes', 'target': 'nodes'}, {'source': 'nodes', 'target': 'specs'}, {'source': 'containers', 'target': 'root'}, {'source': 'distutils', 'target': 'wheel'}, {'source': 'distutils', 'target': 'tools.testing'}, {'source': 'tools.testing', 'target': 'root'}, {'source': 'tools.testing', 'target': 'utils'}, {'source': 'tools.testing', 'target': 'tools.testing'}, {'source': 'finalizations', 'target': 'finalizations'}, {'source': 'finalizations', 'target': 'root'}, {'source': 'finalizations', 'target': 'importing'}, {'source': 'finalizations', 'target': 'plugins'}, {
                    'source': 'importing', 'target': 'containers'}, {'source': 'importing', 'target': 'plugins'}, {'source': 'importing', 'target': 'root'}, {'source': 'importing', 'target': 'utils'}, {'source': 'importing', 'target': 'importing'}, {'source': 'importing', 'target': 'tree'}, {'source': 'plugins', 'target': 'root'}, {'source': 'plugins', 'target': 'containers'}, {'source': 'plugins', 'target': 'utils'}, {'source': 'plugins', 'target': 'plugins'}, {'source': 'freezer', 'target': 'codegen'}, {'source': 'freezer', 'target': 'codegen.templates'}, {'source': 'freezer', 'target': 'root'}, {'source': 'freezer', 'target': 'utils'}, {'source': 'freezer', 'target': 'containers'}, {'source': 'freezer', 'target': 'importing'}, {'source': 'freezer', 'target': 'nodes'}, {'source': 'freezer', 'target': 'plugins'}, {'source': 'freezer', 'target': 'tree'}, {'source': 'freezer', 'target': 'freezer'}, {'source': 'tree', 'target': 'root'}, {'source': 'tree', 'target': 'plugins'}, {'source': 'tree', 'target': 'utils'}, {'source': 'tree', 'target': 'tree'}, {'source': 'tree', 'target': 'nodes'}, {'source': 'tree', 'target': 'optimizations'}, {'source': 'tree', 'target': 'freezer'}, {'source': 'tree', 'target': 'importing'}, {'source': 'tree', 'target': 'specs'}, {'source': 'specs', 'target': 'root'}, {'source': 'specs', 'target': 'specs'}, {'source': 'specs', 'target': 'utils'}, {'source': 'optimizations', 'target': 'root'}, {'source': 'optimizations', 'target': 'importing'}, {'source': 'optimizations', 'target': 'nodes'}, {'source': 'optimizations', 'target': 'nodes.shapes'}, {'source': 'optimizations', 'target': 'tree'}, {'source': 'optimizations', 'target': 'utils'}, {'source': 'optimizations', 'target': 'optimizations'}, {'source': 'optimizations', 'target': 'plugins'}, {'source': 'plugins.standard', 'target': 'root'}, {'source': 'plugins.standard', 'target': 'plugins'}, {'source': 'plugins.standard', 'target': 'containers'}, {'source': 'plugins.standard', 'target': 'utils'}, {'source': 'tools.general.dll_report', 'target': 'freezer'}, {'source': 'tools.general.dll_report', 'target': 'utils'}, {'source': 'tools.specialize', 'target': 'codegen'}, {'source': 'tools.specialize', 'target': 'root'}, {'source': 'tools.testing.compare_with_cpython', 'target': 'root'}, {'source': 'tools.testing.compare_with_cpython', 'target': 'tools.testing'}, {'source': 'tools.testing.compare_with_cpython', 'target': 'utils'}, {'source': 'tools.testing.find_sxs_modules', 'target': 'tools.testing'}, {'source': 'tools.testing.find_sxs_modules', 'target': 'root'}, {'source': 'tools.testing.find_sxs_modules', 'target': 'utils'}, {'source': 'tools.testing.measure_construct_performance', 'target': 'tools.testing'}, {'source': 'tools.testing.run_root_tests', 'target': 'tools'}, {'source': 'tools.testing.run_root_tests', 'target': 'tools.testing'}, {'source': 'tools.testing.run_root_tests', 'target': 'utils'}]})
nx.draw(G, with_labels=True)
plt.show()

Seperti yang Anda lihat, menggambar grafik dengan cara yang naif ini akan menghasilkan output yang sama sekali tidak berguna & tidak dapat dibaca seperti:

enter image description here

Masalahnya, setelah semua penelitian saya membaca tutorial/dokumen networkx, memeriksa beberapa referensi google, saya tidak dapat menemukan cara yang tepat untuk menyelesaikan tugas. Saya sudah menginstal graphviz tetapi saya gagal total mencoba membangun & menjalankan pygraphivz/pydot di windows, toh...

Pertanyaan: Bagaimana saya bisa menggambar grafik kompleks menggunakan networkx dalam semacam cara hierarkis & bersih di mana node tersebar secara seragam di antara mereka? Di bawah ini Anda dapat melihat jenis output yang ingin saya capai di sini:

enter image description here

Seperti yang Anda lihat, node tersebar, siklus ditampilkan dengan benar dan tingkat hierarki yang berbeda benar-benar jelas atas/bawah... Akan sangat bagus jika sesuatu seperti ini (atau serupa) dapat dicapai dengan networkx.

Sebenarnya, apa yang dijelaskan dalam kertas ini persis seperti jenis keluaran yang saya' d ingin mencapai di sini

Ns. Contoh gambar dipinjam dari situs< /a>

0
BPL 11 April 2020, 22:01

1 menjawab

Jawaban Terbaik

Berbagai drawfungsi networkx mengambil argumen pos, yang merupakan kamus yang memiliki nama simpul sebagai kunci, dan koordinat x,y sebagai nilai.

Anda dapat menghasilkan ini sendiri. Jika Anda mengetahui hierarki yang ingin Anda terapkan, Anda dapat menerjemahkan hierarki ke posisi y, lalu tambahkan saja posisi isian x saat Anda melanjutkan:

# exctracting nodes from dictionary into list:
nodes = [{'id': 'build'}, {'id': 'root'}, {'id': 'utils'}, {'id': 'codegen'}, {'id': 'codegen.templates'}, {'id': 'nodes.shapes'}, {'id': 'codegen.c_types'}, {'id': 'nodes'}, {'id': 'containers'}, {'id': 'distutils'}, {'id': 'wheel'}, {'id': 'tools.testing'}, {'id': 'finalizations'}, {'id': 'importing'}, {'id': 'plugins'}, {'id': 'freezer'}, {'id': 'tree'}, {'id': 'specs'}, {'id': 'optimizations'}, {'id': 'plugins.standard'}, {'id': 'tools.general.dll_report'}, {'id': 'tools.specialize'}, {'id': 'tools.testing.compare_with_cpython'}, {'id': 'tools.testing.find_sxs_modules'}, {'id': 'tools.testing.measure_construct_performance'}, {'id': 'tools.testing.run_root_tests'}, {'id': 'tools'}]

nodelist = []
for n in nodes:
    for k, v in n.items():
        nodelist.append(v)

# hierarchy here is arbitrarily defined based on the index of hte node in nodelist. 
# {hierarchy_level : number_of_nodes_at_that_level}
hierarchy = {
    0:4,
    1:10,
    2:5,
    3:5,
    4:3
}

coords = []
for y, v in hierarchy.items():
    coords += [[x, y] for x in list(range(v))]

# map node names to positions 
# this is based on index of node in nodelist.
# can and should be tailored to your actual hierarchy    
positions = {}
for n, c in zip(nodelist, coords):
    positions[n] = c

fig = plt.figure(figsize=(15,5))
nx.draw_networkx_nodes(G, pos=positions, node_size=50)
nx.draw_networkx_edges(G, pos=positions, alpha=0.2)

# generate y-offset for the labels, s.t. they don't lie on the nodes
label_positions = {k:[v0, v1-.25] for k, (v0,v1) in positions.items()}
nx.draw_networkx_labels(G, pos=label_positions, font_size=8)
plt.show()

enter image description here

Label simpul agak tumpang tindih, tetapi ini dapat disesuaikan dengan ukuran font, penyeimbangan tambahan melalui dimensi gambar

EDIT:

Putar label simpul untuk menghindari tumpang tindih teks:

text = nx.draw_networkx_labels(G, pos=label_positions, font_size=8)
for _, t in text.items():
    t.set_rotation(20)

enter image description here

1
warped 13 April 2020, 13:47