2012-10-22 12 views
8

मैं अजगर में ग्राफ खींचने के लिए पाइडोट का उपयोग कर रहा हूं। मैं एक निर्णय पेड़ का प्रतिनिधित्व करना चाहते हैं, का कहना है की तरह कुछ (A1, A2, A3 गुण हैं और दो वर्गों 0 और 1 हैं:पायडॉट: क्या दो अलग-अलग नोड्स को उसी स्ट्रिंग के साथ प्लॉट करना संभव है?

 a1>3 
    / \ 
    a2>10 a3>-7 
/\ /\ 
    1 0 1 0 

हालांकि, pydot का उपयोग कर, केवल दो पत्ते बनाई गई हैं और पेड़ इस (संलग्न png) की तरह दिखता है:

 a1>3 
    / \ 
    a2>10 a3>-7 
     | X | 
     1  0 

अब, यह सरल मामले तर्क ठीक है में लेकिन बड़े पेड़ों में यह गंदा आंतरिक विभिन्न शाखाओं से संबंधित नोड्स एकीकृत है

सरल कोड मैं। एम का उपयोग कर रहा है:

import pydot 
graph = pydot.Dot(graph_type='graph') 
edge = pydot.Edge("a_1>3", "a_2>10") 
graph.add_edge(edge) 
edge = pydot.Edge("a_1>3", "a_3>-7") 
graph.add_edge(edge) 
edge = pydot.Edge("a_2>10", "1") 
graph.add_edge(edge) 
edge = pydot.Edge("a_2>10", "0") 
graph.add_edge(edge) 
edge = pydot.Edge("a_3>-7", "1") 
graph.add_edge(edge) 
edge = pydot.Edge("a_3>-7", "0") 
graph.add_edge(edge) 
graph.write_png('simpleTree.png') 

मैं भी अलग नोड वस्तुओं की तुलना किनारों बना सकते हैं और की तुलना में यह ग्राफ में जोड़ने के लिए बनाने की कोशिश की लेकिन ऐसा लगता है कि pydot बजाय एक नया बनाने के समान नाम के साथ नोड्स के लिए नोड पूल जाँच करता है।

कोई विचार? धन्यवाद!

the image created by the code above

उत्तर

13

आपका नोड्स हमेशा एक अद्वितीय नामों की जरूरत है, नहीं तो आप उन्हें विशिष्ट नाम नहीं कर सकते हैं उन दोनों के बीच किनारों संलग्न करने के लिए। हालांकि, आप प्रत्येक नोड को एक लेबल दे सकते हैं, जो कि प्रस्तुत किए जाने पर प्रदर्शित होता है।

तो तुम अद्वितीय आईडी के साथ नोड्स जोड़ने की आवश्यकता होगी:

edge = pydot.Edge("a_2>10", "literal_0_0") 
graph.add_edge(edge) 
edge = pydot.Edge("a_2>10", "literal_1_0") 
graph.add_edge(edge) 
edge = pydot.Edge("a_3>-7", "literal_0_1") 
graph.add_edge(edge) 
edge = pydot.Edge("a_3>-7", "literal_1_1") 
graph.add_edge(edge) 
एक साथ किनारों आप इस बनाता है परिभाषित के बाकी के साथ

:

graph = pydot.Dot(graph_type='graph') 
graph.add_node(pydot.Node('literal_0_0', label='0')) 
graph.add_node(pydot.Node('literal_0_1', label='0')) 
graph.add_node(pydot.Node('literal_1_0', label='1')) 
graph.add_node(pydot.Node('literal_1_1', label='1')) 

तो उन नोड्स जोड़ने ग्राफ किनारों जोड़ें:

graph with correct edges

1

"प्रामाणिक" जवाब उपयोग करने के लिए है मानक पुस्तकालय से uuid मॉड्यूल, networkxdoes here के रूप में।

यह id का उपयोग कर pydot के लिए नोड नाम हैं जो अपने मूल ग्राफ में नोड्स के अनुरूप है, बनाने के लिए की तुलना में बेहतर है, क्योंकि जब तुम, अपने pydot ग्राफ निर्माण कर रहे हैं तो अगर (सिद्धांत में) एक नोड वस्तु हट जाता है कि id जीता ' टी अनिवार्य रूप से अद्वितीय नहीं है। इसके विपरीत, UUID बनाए गए ऑब्जेक्ट्स मूल नोड्स के जीवनकाल के अद्वितीय, लगातार और स्वतंत्र हैं।

हालांकि ऐसा होने के लिए, pydot ग्राफ बनाते समय बहुत अजीब होना चाहिए, जो कि असंभव है। id का उपयोग करने का लाभ यह है कि आपको मूल नोड्स से UUID ऑब्जेक्ट्स तक मैपिंग बनाने और पास करने की आवश्यकता नहीं है (ताकि आप नोड्स जोड़ने के बाद लगातार किनारों का निर्माण कर सकें)।

एक दिलचस्प मामला नेस्टेड रेखांकन कर रहे हैं: दो अलग-अलग रेखांकन networkx में एक ही hashable वस्तु हो सकती है (जैसे कि a), तो id नोड पर किसी भी अधिक सीधे नहीं किया जा सकता। लेकिन उस स्थिति में, id का उपयोग अभी भी किया जा सकता है, (नोड, ग्राफ) जोड़ी के संयोजन के रूप में: str(id(node)) + str(id(graph))

संबंधित मुद्दे