Tree grafisch darstellen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Hallo miteinander,

für ein kleines Projekt sollte ich einen Tree in python grafisch darstellen.
Konkreter: Ich erhalte von anderen Klassen / Skripten zum einen Objekte (Häuser), und eine Zahl, die entweder positiv oder negativ ist. Ist die Zahl positiv, so wird mehr Strom benötigt, ist die Zahl negativ, wird ein Überschuss produziert (z.B. dank Solarpanels usw.).

Mein Vorhaben ist nun, alle Objekte als Punkte darzustellen, diese klug zu verbinden (kann man das irgendwie randomly machen?), sie zu beschriften, und je nach dem, ob sie Strom brauchen / überproduzieren, die Punkte rötlicher / grüner darzustellen.
Wenn es geht, würde ich den Stromfluss auch gleich auf den Verbindungen darstellen...das stelle ich mir aber relativ kompliziert vor.

Was meint ihr zu dem Vorhaben? Wie würdet ihr das machen?
Und: Habt ihr einen Vorschlag, wie man Trees am besten / schönsten / für mein Vorhaben am günstigsten darstellen kann?

Danke für alle Tipps! :)
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@MarcelF6:
Für die Ausgabe wirst Du vllt. hier fündig: http://networkx.github.io/index.html
BlackJack

Neben networkx ist GraphViz noch ein Klassiker um Graphen zu visualisieren. Es gibt diverse Python-Module die das benutzen beziehungsweise Quelltext dafür erstellen können. Man kann sich da auch relativ leicht selber etwas basteln.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Danke für die Tipps!

Ich habe noch eine konzeptionelle Frage: Wenn ich eine Liste habe mit einer unbekannten Anzahl an Einträgen:
liste = ["hausA", "hausB", "hausC", "hausD"]
Wie kann ich am einfachsten die Punkte erstellen und sie gleich miteinander verbinden?

Hätte ich eine fixe Anzahl, sähe das so aus:

Code: Alles auswählen

a="node_1"
b="node_2"
c="node_3"
G.do(a,b)
G.do(b,c)
G.do(a,c)
Vielen Dank für jeden Tipp!
BlackJack

@MarcelF6: Was ist denn hier `G`? Für welche Bibliothek hast Du Dich denn hier entschieden? Das wäre schon irgendwie wichtig zu wissen welchen Datentyp Du verwendest der eine `do()`-Methode hat.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Hallo,

G ist der Graph und "do()" ist einfach eine beliebige Methode.
Mir gehts mehr darum, eine Möglichkeit zu finden, alle Elemente der Liste miteinander zu verlinken, ohne dass man im Vornherein weiss, dass es 3, 4 oder mehr Elemente sind.

Danke für die Tipps!
BlackJack

@MarcelF6: Ähm, wie wär's wenn Du Dir zum Beispiel mal `networkx` anschaust und die tatsächlichen `Graph`-Objekte dort und welche konkreten Methoden die haben‽ Es macht sehr wenig Sinn hier über Fantasieobjekte zu sprechen. Dann ist die Antwort nämlich:

Code: Alles auswählen

nodes = ['node_1', 'node_2', 'node_3']
G.do_what_i_want(nodes)
So, und jetzt ab zur Networkx-Dokumentation und den tatsächlichen Namen dieser Methode ermitteln. Die gibt's nämlich.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ich wollte nur abstrahieren, da ich dachte, es gebe evtl. eine allgemeine Lösung.
Die Methode, welche ich verwende, heisst "add_edge".
Das Problem aber bleibt: Wie kann ich aus einer Liste mit nodes alle miteinander verbinden (und die nodes beschriften)?
BlackJack

@MarcelF6: Wenn Du `add_egde()` Verwendest, dann verwendest Du die falsche Methode. Es gibt bereits eine die genau das mit der Liste machst was Du haben möchtest.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Du meinst "add_nodes()" ?
BlackJack

@MarcelF6: Nein, meine ich nicht. Willst Du jetzt echt raten und jedes mal hier nachfragen?
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ah sorry, ich meinte natürlich "read_edgelist()".
Und nein, ein Rate- / Nachfragespiel sollte es hier nicht werden!
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ich habe noch eine andere Frage:
Ist es möglich, nodes entsprechend der Höhe einer Zahl grüner / rötlicher darzustellen?
Also konkret verwende ich folgendes Format: [("node1", -13), ("node2", 33), ("node3", -2)]
Das heisst also, dass "node1" ganz rot, "node2" ganz grün und "node3" etwas rötlicher dargestellt wird?
Ganz nach dem Motto: "Je grösser (und positiver) die Zahl, desto grüner ; je kleiner (und negativer) die Zahl, desto rötlicher soll der node dargestellt werden."
BlackJack

@MarcelF6: Das geht mit dem `node_color`-Argument zusammen mit den `cmap`, `vmin`, und `vmax`-Argumenten der Zeichenfunktionen.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Hallo BlackJack,
danke für deinen Hinweis!

Also, folgendes verstehe ich:

Code: Alles auswählen

nx.draw(G,pos,node_color=range(24),node_size=800,cmap=plt.cm.Blues)
Damit werden 24 Nodes unterschieden - in Blautönen.
Ich möchte bei meinem Vorhaben ja eigentlich switchen zwischen rötlich und grünlich.
Das heisst, vmin wäre ganz klar mein kleinster Wert und müsste mit rot assoziiert werden.
vmax wäre bei mir der Maximalwert, = grün.
Wie benutze ich aber cmap, damit ich die Werte für rot und grün definieren kann und damit networkx die nodes entsprechend grünlich / rötlich malt?

Danke für die wertvolle Hilfe!
BlackJack

@MarcelF6: Für `cmap` musst Du eine Farbabbildung nehmen die von Rot nach Grün geht und für `node_colors` die Werte der einzelnen Knoten. Und halt `vmin` und `vmax` daraus berechnen und setzen.
Antworten