अजगर में नेटवर्कएक्स का उपयोग करके निर्देशित ग्राफ़ कैसे बनाएं?


101

मेरे पास एक स्क्रिप्ट से आने वाले कुछ नोड्स हैं जिन्हें मैं एक ग्राफ पर मैप करना चाहता हूं। नीचे, मैं ए से डी तक जाने के लिए एरो का उपयोग करना चाहता हूं और शायद किनारे को भी (लाल या कुछ) रंग में रंगना है।

यह मूल रूप से, ए से डी तक के मार्ग की तरह है जब अन्य सभी नोड्स मौजूद हैं। आप शहरों के रूप में प्रत्येक नोड की कल्पना कर सकते हैं और ए से डी तक की यात्रा के लिए दिशा-निर्देशों की आवश्यकता है (तीर प्रमुखों के साथ)।

नीचे दिया गया यह कोड ग्राफ बनाता है

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)
plt.show()

लेकिन मैं ऐसा कुछ चाहता हूं जैसे छवि में दिखाया गया हो।यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

पहली छवि के सिर और दूसरी छवि पर लाल रंग के किनारों को तीर दें।

जवाबों:


86

केवल लाल किनारों के लिए तीर के साथ पूरी तरह से fleshed उदाहरण:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

# Specify the edges you want here
red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red'
                for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

# Need to create a layout when doing
# separate calls to draw nodes and edges
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), 
                       node_color = values, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

लाल किनारे


1
यह पागल है कि हमारे दो अपडेटेड चित्र कितने अलग हैं। किनारे के रंगों का पता लगाने के लिए +1!
mdml

आपका किनारा (C, E) लाल क्यों नहीं है, हालाँकि यह आपके कोड के अनुसार लाल होना चाहिए?
ब्रेन तूफ़ान

क्या यह तीर केवल ब्याज के किनारों पर होना संभव नहीं है? उदाहरण के लिए (ए, सी) और (सी, ई)
मस्तिष्क तूफान

@ user1988876: आह, क्षमा करें, (C, E)लाल नहीं है क्योंकि मैंने किनारों को red_edgesतब उठाया था जब मैं अभी भी आपके अप्रत्यक्ष ग्राफ के साथ काम कर रहा था, बस किनारों से बेतरतीब ढंग से उठाकर लौटा था G.edges()। यह होना चाहिए red_edges = [('A', 'C'), ('E', 'C')]
मैरिज

@ user1988876: अलग-अलग कॉल के साथ केवल कुछ किनारों पर तीर होना संभव है draw_networkx_edges()। मैंने कोड को साफ कर दिया है और डायग्राफ के मुद्दों को ठीक कर दिया है।
मारियस

47

मैंने केवल इसे पूर्णता के लिए रखा है। मैंने मार्स और mdml से बहुत कुछ सीखा है। यहाँ किनारे वजन हैं। तीर के बारे में क्षमा करें। ऐसा लगता है कि मैं केवल एक ही कह रहा हूं कि यह मदद नहीं कर सकता। मैं इसे ipython नोटबुक के साथ प्रस्तुत नहीं कर सकता था, मुझे सीधे अजगर से जाना था, जो कि जल्द ही अपने एज वेट प्राप्त करने में समस्या थी।

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pylab

G = nx.DiGraph()

G.add_edges_from([('A', 'B'),('C','D'),('G','D')], weight=1)
G.add_edges_from([('D','A'),('D','E'),('B','D'),('D','E')], weight=2)
G.add_edges_from([('B','C'),('E','F')], weight=3)
G.add_edges_from([('C','F')], weight=4)


val_map = {'A': 1.0,
                   'D': 0.5714285714285714,
                              'H': 0.0}

values = [val_map.get(node, 0.45) for node in G.nodes()]
edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])
red_edges = [('C','D'),('D','A')]
edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G,pos, node_color = values, node_size=1500,edge_color=edge_colors,edge_cmap=plt.cm.Reds)
pylab.show()

यहां छवि विवरण दर्ज करें


9
मैंने इसे चलाया और नोड लेबल नहीं मिला। आप इन जोड़ने की जरूरत है: node_labels = {node:node for node in G.nodes()}; nx.draw_networkx_labels(G, pos, labels=node_labels)
मेडऑफअयर

और क्या होगा यदि आपके पास पहले से ही एक अप्रत्यक्ष ग्राफ है और इसकी एक निर्देशित प्रति फिर से निकालना चाहते हैं? क्या G.add_edges_from()प्रारंभ और समापन बिंदु को मैन्युअल रूप से दर्ज किए बिना लाइन सेट करने का कोई तरीका है ? शायद एक से किनारों को जोड़ने dict?
फाकॉफी

इस खंड में कोड की पहली पंक्ति (आयात लाइनों के अलावा) यह निर्धारित करती है कि यह किस प्रकार का ग्राफ है और यह किस तरह के किनारों को स्वीकार करता है। आप एक डिग (अधिक जानकारी) से एक ग्राफ़ (कम जानकारी) पर जा सकते हैं लेकिन आप एक ग्राफ़ (कम जानकारी) से किसी डिग्राफ (अधिक जानकारी) तक बिना सूचना या उस गुम सूचना के निर्माण के लिए नहीं जा सकते। मैं आपके प्रश्न को एक और स्टैक ओवरफ्लो प्रश्न में एक उदाहरण के साथ रखने का सुझाव दूंगा।
Back2Basics

1
क्या किनारों पर वास्तविक तीर प्राप्त करना संभव है? मैं सिर्फ मोटा अंत पसंद नहीं है।
विकुनिया

1
Matplotlib में अरकहेड को खींचना मुश्किल है और वर्तमान में NetworkX में समर्थित नहीं है। खींचने के अनुरोध स्वीकार किए जाते हैं।
Back2Basics

33

नियमित nx.draw के बजाय आप उपयोग करना चाह सकते हैं:

nx.draw_networkx(G[, pos, arrows, with_labels])

उदाहरण के लिए:

nx.draw_networkx(G, arrows=True, **options)

आप विकल्प चुन सकते हैं कि ** चर इस तरह से:

options = {
    'node_color': 'blue',
    'node_size': 100,
    'width': 3,
    'arrowstyle': '-|>',
    'arrowsize': 12,
}

कुछ कार्य भी समर्थन करते हैं directed=True parameter इस मामले में यह स्थिति डिफ़ॉल्ट है:

G = nx.DiGraph(directed=True)

संजाल संदर्भ यहाँ पाया जाता है

तीर छवि के साथ ग्राफ


21

आपको एक ग्राफ के बजाय एक निर्देशित ग्राफ का उपयोग करने की आवश्यकता है , अर्थात

G = nx.DiGraph()

फिर, उन एज रंगों की एक सूची बनाएं, जिन्हें आप उपयोग करना चाहते हैं और उन्हें पास करना चाहते हैं nx.draw(जैसा कि @ मारी द्वारा दिखाया गया है)।

यह सब एक साथ रखकर, मुझे नीचे की छवि मिलती है। अभी भी काफी अन्य चित्र जो आप दिखाते हैं (मुझे नहीं पता कि आपके किनारे का वजन कहां से आ रहा है), लेकिन बहुत करीब! यदि आप चाहते हैं कि आपका आउटपुट ग्राफ़ कैसा दिखे (जैसे तीर की तरह दिखने वाले तीर के निशान ), तो मैं अधिक नियंत्रण चाहता हूं, मैं Networkv को ग्राफविज़ के साथ देखूंगा

यहां छवि विवरण दर्ज करें


आह, मैं समझ नहीं पा रहा था कि तीर काम क्यों नहीं कर रहे थे क्योंकि मैं प्रलेखन में उनके लिए तर्क देख सकता था।
मारियस

9
import networkx as nx
import matplotlib.pyplot as plt

g = nx.DiGraph()
g.add_nodes_from([1,2,3,4,5])
g.add_edge(1,2)
g.add_edge(4,2)
g.add_edge(3,5)
g.add_edge(2,3)
g.add_edge(5,4)

nx.draw(g,with_labels=True)
plt.draw()
plt.show()

यह सिर्फ सरल है कि नेटवर्कएक्स का उपयोग करके अजगर 3.x द्वारा निर्देशित ग्राफ कैसे खींचना है। बस सरल प्रतिनिधित्व और संशोधित किया जा सकता है और रंगीन आदि यहाँ उत्पन्न ग्राफ देखें ।

नोट: यह सिर्फ एक सरल प्रतिनिधित्व है। भारित किनारों की तरह जोड़ा जा सकता है

g.add_edges_from([(1,2),(2,5)], weight=2)

और इसलिए फिर से प्लॉट किया गया।


1
import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_node("D")
G.add_node("E")
G.add_node("F")
G.add_node("G")
G.add_edge("A","B")
G.add_edge("B","C")
G.add_edge("C","E")
G.add_edge("C","F")
G.add_edge("D","E")
G.add_edge("F","G")

print(G.nodes())
print(G.edges())

pos = nx.spring_layout(G)

nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edge_color='r', arrows = True)

plt.show()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.