Zum Inhalt

Grundidee

dsstools baut auf dem Package für Netzwerkanalyse, NetworkX auf und erweitert es um Funktionen und Integrationen, die im Forschungsbereich des Lehrstuhls Digital Social Science relevant sind. Von daher sollten Grundkenntnisse sowohl in Python als auch in NetworkX vorhanden sein, bevor wir starten können.

Die Grundidee bei dsstools ist, dass immer auf Basis eines networkx.Graph-Objektes gearbeitet wird. Das bedeutet, dass alle Interaktionen mit dem Netzwerk rein auf Basis von dsstools stattfinden können, aber auch immer Funktionen von NetworkX angewandt werden können. Das hat das Ziel, das fortgeschrittene Personen auch komplexere Funktionen selbst schreiben können. Für absolute Beginner sind jedoch die von dsstools bereitgestellten Funktionen völlig ausreichend.

Einstieg in die Programmierung

Lege als Erstes eine Python Datei an und importiere dsstools. Zusätzlich importieren wir networkx, da wir ab und an auf Funktionen des Moduls zurückgreifen:

import dsstools
import networkx as nx

Das Package NetworkX wird im Import innerhalb python immer als networkx geschrieben und für gewöhnlich mit einem Alias nx versehen, um die Schreibweise abzukürzen.

Import eines Graphen

Zuerst muss ein Graph importiert werden. Dazu bietet NetworkX selbst einige unterschiedliche Formate an:

  • read_pajek für Pajek-Dateien
  • read_gexf für Graph Exchange XML Format
  • Ein Überblick über alle kompatiblen Formate ist hier zu finden.

Darüber hinaus stellt dsstools noch mehrere Integrationen bereit, wie Daten oder Netzwerke importiert werden können. Siehe für eine Auflistung hier.

Achtung

Wir empfehlen für den Anfang, die Daten als networkx.DiGraph zu importieren!

Bereinigung (optional)

Manchmal müssen Kanten, deren Ursprungs- und Endknoten identisch ist, aus dem Netzwerk entfernt werden. Das lässt sich mittels networkx erledigen:

graph.remove_edges_from(nx.selfloop_edges(graph))

In diesem Fall werden Selfloops entfernt, also Kanten, deren Start- und Endknoten der gleiche ist. Das kommt bisweilen bei gecrawlten Netzwerken vor.

Positionierung

Bevor wir eine Abbildung zeichnen können, müssen die Positionen der Knoten unseres Netzwerkes festgelegt werden. Dazu gibt es derzeit zwei Varianten: Standard (nutzt intern nx.spring_layout()) und Graphviz.

Erstere Variante ist automatisch mit der Installation von dsstols verfügbar. Zweitere Variante ist komplizierter zu installieren, liefert aber eine (subjektiv) bessere Positionierung.

Standard

Überblickshaft ein Beispiel, wie die sogenannte Layouter-Klasse verwendet wird, in welchem die Positionen festgelegt werden:

layouter = dsstools.Layouter()
layouter.update_positions("positions.json", graph, seed=12)

Zuerst wird ein Objekt layouter erstellt, welches mittels der Methode update_positions() den Pfad für eine Datei übergibt, in die alle Positionen geschrieben werden, den Graphen selbst und einen sogenannten Seed.

Der Seed (in diesem Fall 12) legt die Zufälligkeit der entstehenden Positionen fest und determiniert das Netzwerk. Falls du unterschiedliche Positionen probieren willst, kansnt du über den Seed iterieren (bspw. mithilfe einer Range und eines For-Loops). Die obige Zeilen lässt sich auch kürzer schreiben:

layout = dsstools.Layouter().update_positions("positions.json", graph, seed=12)

In der Variable layout findet sich in der Folge ein Dictionary, welches für das Zeichnen übergeben werden kann (siehe dazu unten).

Graphviz

Graphviz liefert schönere Ergebnisse in der Positionierung, ist allerdings etwas schwieriger zu installieren. Dazu muss Graphviz oder pygraphviz installiert sein. Hier wird die Installation von Graphviz erklärt. Zusätzlich kannst du auch die Python-Anbindung pygraphviz installieren (Erklärung hier, du benötigst aber dennoch Graphviz.)

Wenn du das geschafft hast, kannst du den graphviz Layouter auswählen und darüber deine Positionen festlegen lassen:

positions = dsstools.Layouter().select("graphviz").update_positions("positions.json", graph, seed=12)

Falls eine andere Layout-Engine verwendet werden soll (beispielweise bei großen Netzwerken), kann diese über den Parameter prog übergeben werden:

positions = (
    dsstools.Layouter()
    .select("graphviz")
    .update_positions("positions.json", graph, seed=12, prog="fdp")
)

Für eine Übersicht der verfügbaren Layout-Engines innerhalb von Graphviz siehe hier.

!!! Achtung Der Seed für Graphviz ist nicht deterministisch (auf unterschiedlichen Systemen kommen unterschiedliche Ergebnisse zustande). Deshalb funktioniert die Zwischenspeicherung der Positionen auf unterschiedlichen Rechnern immer über die Positionsdatei.

Ergänzung

Beide Varianten nutzen ein Argument für den Ort und Name der Positionsdateien, in den Beispielen immer "positions.json". Meine Empfehlung ist es, wenn du dich auf eine Positionierung festgelegt hast, diese Datei mit in eure Versionskontrolle aufzunehmen, um euer Setup auch Anderen im Team zur Verfügung stellen zu können oder eine Historie eurer Positionen zu haben. Somit sollte euer Pfad für die Positionsdatei innerhalb eures Repositories liegen.