diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/Graph.png b/documentations/seminararbeiten/Verflechtungsanalyse/Graph.png
new file mode 100644
index 0000000..fb7f0ae
Binary files /dev/null and b/documentations/seminararbeiten/Verflechtungsanalyse/Graph.png differ
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/companies.csv b/documentations/seminararbeiten/Verflechtungsanalyse/companies.csv
new file mode 100644
index 0000000..0097ec9
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/companies.csv
@@ -0,0 +1,12 @@
+id;label;type;branche
+1;Porsche Automobil Holding;Company;Automobilhersteller
+2;Volkswagen AG;Company;Automobilhersteller
+3;Volkswagen;Company;Automobilhersteller
+4;Audi;Company;Automobilhersteller
+5;Seat;Company;Automobilhersteller
+6;Skoda Auto;Company;Automobilhersteller
+7;Porsche AG;Company;Automobilhersteller
+8;Lamborghini;Company;Automobilhersteller
+9;Bentley;Company;Automobilhersteller
+10;Forvia;Company;Automobilzulieferer
+11;Hella;Company;Automobilzulieferer
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/betweeness_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/betweeness_networkx.html
new file mode 100644
index 0000000..f4ac680
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/betweeness_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/closeness_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/closeness_networkx.html
new file mode 100644
index 0000000..d177118
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/closeness_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/degree_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/degree_networkx.html
new file mode 100644
index 0000000..57aade6
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/degree_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/edges_path_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/edges_path_networkx.html
new file mode 100644
index 0000000..9e68207
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/edges_path_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/eigenvector_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/eigenvector_networkx.html
new file mode 100644
index 0000000..8da2b79
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/eigenvector_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/metrics/pagerank_networkx.html b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/pagerank_networkx.html
new file mode 100644
index 0000000..507039f
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/metrics/pagerank_networkx.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/mockup_verflechtungsanalyse_with_networkx.ipynb b/documentations/seminararbeiten/Verflechtungsanalyse/mockup_verflechtungsanalyse_with_networkx.ipynb
new file mode 100644
index 0000000..7d07996
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/mockup_verflechtungsanalyse_with_networkx.ipynb
@@ -0,0 +1,654 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Networkx und Pyvis - Minimal Working Example"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Referenzen: \n",
+ "- [Networkx Dokumentation](https://networkx.org/documentation/stable/)\n",
+ "- [Pyvis Dokumentation](https://pyvis.readthedocs.io/en/latest/index.html)\n",
+ "- [Introduction to Python for Humanists](https://python-textbook.pythonhumanities.com/06_sna/06_01_05_networkx_pyvis.html)\n",
+ "\n",
+ "\n",
+ "Networkx ist eine Python Bibliothek zur Erstellung und Analyse von Netzwerken. Pyvis ist eine Python Bibliothek zur interaktiven Visualisierung von Netzwerkgraphen. Beide können mit `pip` installiert werden. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: networkx in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (3.0)\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "[notice] A new release of pip is available: 23.1.1 -> 23.1.2\n",
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: pyvis in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (0.3.2)\n",
+ "Requirement already satisfied: ipython>=5.3.0 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pyvis) (8.4.0)\n",
+ "Requirement already satisfied: jinja2>=2.9.6 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pyvis) (3.1.2)\n",
+ "Requirement already satisfied: jsonpickle>=1.4.1 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pyvis) (3.0.1)\n",
+ "Requirement already satisfied: networkx>=1.11 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pyvis) (3.0)\n",
+ "Requirement already satisfied: backcall in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.2.0)\n",
+ "Requirement already satisfied: decorator in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (5.1.1)\n",
+ "Requirement already satisfied: jedi>=0.16 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.18.1)\n",
+ "Requirement already satisfied: matplotlib-inline in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.1.3)\n",
+ "Requirement already satisfied: pickleshare in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.7.5)\n",
+ "Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (3.0.30)\n",
+ "Requirement already satisfied: pygments>=2.4.0 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (2.12.0)\n",
+ "Requirement already satisfied: setuptools>=18.5 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (58.1.0)\n",
+ "Requirement already satisfied: stack-data in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.3.0)\n",
+ "Requirement already satisfied: traitlets>=5 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (5.7.1)\n",
+ "Requirement already satisfied: colorama in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from ipython>=5.3.0->pyvis) (0.4.5)\n",
+ "Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from jinja2>=2.9.6->pyvis) (2.1.1)\n",
+ "Requirement already satisfied: parso<0.9.0,>=0.8.0 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from jedi>=0.16->ipython>=5.3.0->pyvis) (0.8.3)\n",
+ "Requirement already satisfied: wcwidth in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=5.3.0->pyvis) (0.2.5)\n",
+ "Requirement already satisfied: executing in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from stack-data->ipython>=5.3.0->pyvis) (0.8.3)\n",
+ "Requirement already satisfied: asttokens in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from stack-data->ipython>=5.3.0->pyvis) (2.0.5)\n",
+ "Requirement already satisfied: pure-eval in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from stack-data->ipython>=5.3.0->pyvis) (0.2.2)\n",
+ "Requirement already satisfied: six in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from asttokens->stack-data->ipython>=5.3.0->pyvis) (1.16.0)\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "[notice] A new release of pip is available: 23.1.1 -> 23.1.2\n",
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
+ ]
+ }
+ ],
+ "source": [
+ "# install networkx and pyvis using pip\n",
+ "!pip install networkx\n",
+ "!pip install pyvis"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Panda Dataframe mit Beispieldaten\n",
+ "\n",
+ "Um ein Netzwerk aufbauen zu können, brauchen wir Daten für die Knoten (nodes) und Kanten (edges). Die Daten speichern wir jeweils in einem Panda Dataframe. Pandas kann ebenfalls mit `pip` installiert werden. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: pandas in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (1.4.3)\n",
+ "Requirement already satisfied: python-dateutil>=2.8.1 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pandas) (2.8.2)\n",
+ "Requirement already satisfied: pytz>=2020.1 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pandas) (2022.1)\n",
+ "Requirement already satisfied: numpy>=1.18.5 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from pandas) (1.23.0)\n",
+ "Requirement already satisfied: six>=1.5 in c:\\users\\tim\\appdata\\local\\programs\\python\\python39\\lib\\site-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "[notice] A new release of pip is available: 23.1.1 -> 23.1.2\n",
+ "[notice] To update, run: python.exe -m pip install --upgrade pip\n"
+ ]
+ }
+ ],
+ "source": [
+ "# install pandas using pip\n",
+ "!pip install pandas"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Die Knoten unseres Netzwerks sollen die Unternehmen und Personen darstellen. Eine `id` ermöglicht die eindeutige Identifizierung eines Knoten und hilft Duplikate zu vermeiden. Um Unternehmen von Personen differenzieren zu können, wurde zusätzlich die Information `type` aufgenommen. Sie dient in unserem Beispiel dazu, die Form des Knoten zu bestimmen. Durch `label` bekommt der Knoten eine für den User verständliche Bezeichnung. Weitere Informationen, wie zum Beispiel `branche`, können später für das Mouse Over oder die Größe oder Farbe der Knoten verwendet werden. \n",
+ "\n",
+ "Um in einem späteren Schritt die Attribute der Knoten an das Netzwerk zu übergeben, generieren wir zusätzlich eine Spalte `shape`, eine Spalte `color` und eine Spalte `title`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " id label type branche shape \\\n",
+ "0 1 Porsche Automobil Holding Company Automobilhersteller dot \n",
+ "1 2 Volkswagen AG Company Automobilhersteller dot \n",
+ "2 3 Volkswagen Company Automobilhersteller dot \n",
+ "3 4 Audi Company Automobilhersteller dot \n",
+ "4 5 Seat Company Automobilhersteller dot \n",
+ "\n",
+ " color title \n",
+ "0 #729b79ff Porsche Automobil Holding\\nAutomobilhersteller \n",
+ "1 #729b79ff Volkswagen AG\\nAutomobilhersteller \n",
+ "2 #729b79ff Volkswagen\\nAutomobilhersteller \n",
+ "3 #729b79ff Audi\\nAutomobilhersteller \n",
+ "4 #729b79ff Seat\\nAutomobilhersteller \n"
+ ]
+ }
+ ],
+ "source": [
+ "# import pandas\n",
+ "import pandas as pd\n",
+ "\n",
+ "# create dataframe based on the sample data\n",
+ "df_nodes = pd.read_csv('companies.csv', sep = ';')\n",
+ "\n",
+ "# define shape based on the type\n",
+ "node_shape = {'Company': 'dot', 'Person': 'triangle'}\n",
+ "df_nodes['shape'] = df_nodes['type'].map(node_shape)\n",
+ "\n",
+ "# define color based on branche\n",
+ "node_color = {'Automobilhersteller': ' #729b79ff', 'Automobilzulieferer': '#475b63ff', 'Branche 3': '#f3e8eeff', 'Branche 4': '#bacdb0ff', 'Branche 5': '#2e2c2fff'}\n",
+ "df_nodes['color'] = df_nodes['branche'].map(node_color)\n",
+ "\n",
+ "# add information column that can be used for the mouse over in the graph\n",
+ "df_nodes = df_nodes.fillna('')\n",
+ "df_nodes['title'] = df_nodes['label'] + '\\n' + df_nodes['branche']\n",
+ "\n",
+ "# show first five entries of the dataframe\n",
+ "print(df_nodes.head())"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Die Kanten visualisieren die Beziehungen zwischen den Unternehmen und Personen. Um in Pyvis eine Kante darzustellen braucht es minimal die Information zwischen welchen beiden Knoten eine Kante dargestellt werden soll. In den Beispieldaten entspricht dies `from` und `to`. Es wird jeweils auf die eindeutige `id` der jeweiligen Knoten referenziert. `label` bezeichnet hier die Art der Beziehung, z.B. AR = Aufsichtsrat. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " from to label\n",
+ "0 2 1 part_of\n",
+ "1 3 1 part_of\n",
+ "2 4 1 part_of\n",
+ "3 5 1 part_of\n",
+ "4 6 1 part_of\n"
+ ]
+ }
+ ],
+ "source": [
+ "# create dataframe based on the sample data\n",
+ "df_edges = pd.read_csv('relations.csv', sep = ';')\n",
+ "\n",
+ "# show first five entries of the dataframe\n",
+ "print(df_edges.head())"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Erstellung eines Netzwerks mit networkx\n",
+ "\n",
+ "Zur Erstellung des Netzwerks nutzen wir `networkx`, da diese Bibliothek bessere Analysemöglichkeiten hat als `pyvis`. Das mit `networkx` erstellte Netzwerk können wir später an `pyvis` zur interaktiven Visualisierung übergeben werden. \n",
+ "\n",
+ "Wir erstellen die Knoten und Kanten auf Basis unsere beiden Dataframes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 60,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1gAAANYCAYAAADZn0yoAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAB7LklEQVR4nO3deZyP9f7/8ednhtlknUF2iZKyZC/JVp1UfOtEjPpWZJsoa6LldEj1tVXI0nYsdSwRhXROcigVEWVJixGJkaOxDbMZc/3+uMb8pJmYmc/n876uz/W4327nRsNc19MpM5/n5/V+vy+fZVmWAAAAAABFFmY6AAAAAACECgoWAAAAAPgJBQsAAAAA/ISCBQAAAAB+QsECAAAAAD+hYAEAAACAn1CwAAB/cOjQIfXo0UO1atVSkyZNdN1112np0qV+u37NmjX122+/Ffrzf/jhB7Vt21aNGjXSVVddpb59+0qSZs+erYEDB/orJgAABVbMdAAAgLNYlqU777xTDzzwgObNmydJ+vnnn7Vs2bI//N6srCwVKxb8byWPPvqohgwZov/5n/+RJG3fvj3oGQAAyAsTLADA7/znP/9RRESE+vfvn/uxGjVq6JFHHpFkT4k6d+6s9u3bq0OHDjp58qQ6dOigxo0bq379+nr//fclSXv37lXdunV177336qqrrlKXLl2Umpqae82pU6fmfs73339foIwHDx5U1apVc/+5fv36uT9PSkrSrbfeqjp16mjEiBG5H09ISFDTpk119dVX65lnnsn9eM2aNTVixAjVr19fzZs3V2JioiTp8OHDuvvuu9WsWTM1a9ZMn3/+uSTpk08+UaNGjdSoUSNde+21SklJKVB2AEBoo2ABAH7n22+/VePGjf/092zZskWLFy/WJ598oqioKC1dulRbtmzRmjVrNGzYMFmWJcleyvfwww/ru+++U6lSpTR9+vTca8TFxWnLli1KSEjQxIkTC5RxyJAhat++vTp27KiXXnpJx44dy/21b775RgsXLtT27du1cOFC/fLLL5Kk5557Tl999ZW2bdumTz75RNu2bcv9nNKlS2v79u0aOHCgBg8eLEkaNGiQhgwZok2bNundd99V7969JUkTJ07UtGnT9M0332jdunWKjo4uUHYAQGijYAEA/tSAAQPUsGFDNWvWLPdjN998s8qVKyfJXlL4xBNPqEGD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L3X55ZebjgPDmGABAAAAhZSdna2HHnpITz/9NOUKkihYAAAAQKG98sorsixLjzzyiOkocAiWCAIAAACFsHv3brVo0UJffPGFrrjiCtNx4BBMsAAAAIACys7OVu/evTVy5EjKFX6HggUAAAAU0Kuvvqq0tDQNGTLEdBQ4DEsEAQAAgAL4+eef1aRJE3366aeqV6+e6ThwGCZYAAAAwEWyLEu9e/fWsGHDKFfIEwULAAAAuEhvvPGGjh49qscee8x0FDgUSwQBAACAi/DLL7+ocePGWrNmja655hrTceBQTLAAAACAC7AsS3379tWjjz5KucKfomABAAAAFzBnzhz9+uuvGjlypOkocDiWCAIAAAB/IikpSY0aNdJHH32kRo0amY4Dh6NgAQAAAPmwLEv/8z//o0aNGmnMmDGm48AFipkOAAAAADjVvHnztGfPHi1evNh0FLgEEywAAAAgD7/++qsaNmyoDz74QE2bNjUdBy5BwQIAAADOY1mW7r77bl155ZV64YUXTMeBi7BEEAAAADjPO++8o++//17z5s0zHQUuwwQLAAAAOMfhw4dVv359vf/++2rRooXpOHAZChYAAABwjm7duql69eqaMGGC6ShwIZYIAgAAADmWLFmib775RrNnzzYdBS7FBAsAAACQlJycrPr162vRokVq1aqV6ThwKQoWAAAAIOm+++5TXFycXn75ZdNR4GIsEQQAAIDnLV++XBs2bNDWrVtNR4HLMcECAACApx09elT169fX22+/rbZt25qOA5ejYAEAAMDTevbsqZiYGE2bNs10FIQAlggCAADAsz788EOtXbtW27dvNx0FIYIJFgAAADzp+PHjuuaaazR79mx16NDBdByECAoWAAAAPKlPnz4KCwvTq6++ajoKQghLBAEAAOA5q1at0kcffcTSQPhdmOkAAAAAQDClpKSoT58+eu2111SqVCnTcRBiWCIIAAAAT3n44YeVnp6uf/zjH6ajIASxRBAAAACesWbNGi1btkw7duwwHQUhiiWCAAAA8IRTp06pd+/emjlzpsqUKWM6DkIUSwQBAADgCYMGDdKRI0f01ltvmY6CEMYSQQAAAIS8devWadGiRSwNRMCxRBAAAAAhLTU1Vb169dL06dNVrlw503EQ4lgiCAAAgJA2bNgwJSUlaf78+aajwANYIggAAICQtX79es2bN48HCiNoWCIIAACAkJSenq5evXppypQpiouLMx0HHsESQQAAAISkkSNHKjExUYsXLzYdBR7CEkEAAACEnE2bNmnWrFnatm2b6SjwGJYIAgAAIKRkZGSoZ8+eeumll1SxYkXTceAxFCwAAACElLFjx+ryyy9XfHy86SjwIPZgAQAAIGRs2bJFt956q7Zu3apKlSqZjgMPYoIFAACAkJCZmamePXtqwoQJlCsYQ8ECAABASHjhhRdUtWpV3X///aajwMNYIggAAADX27Ztmzp06KCvv/5aVatWNR0HHsYECwAAAK52+vRp9ezZU//3f/9HuYJxFCwAAAC42oQJExQXF6devXqZjgKwRBAAAADu9e2336pt27bavHmzqlevbjoOwAQLAAAA7pSVlaVevXrp2WefpVzBMShYAAAAcKWXXnpJJUqUUN++fU1HAXKxRBAAAACu88MPP6hVq1bauHGjatWqZToOkIsJFgAAAFzlzJkz6tWrl5555hnKFRyHggUAAABXmTJlisLDwzVgwADTUYA/YIkgAAAAXCMxMVEtW7bUhg0bVLt2bdNxgD9gggUAAABXyM7O1kMPPaQnn3yScgXHomABAADAFaZPn67Tp0/r0UcfNR0FyBdLBAEAAOB4e/bsUbNmzfTZZ5+pbt26puMA+WKCBQAAAEezLEu9e/fWiBEjKFdwPAoWAAAAHO21115TSkqKhg4dajoKcEEsEQQAAIBj7du3T02aNNHatWt19dVXm44DXBATLAAAADiSZVnq06ePBg8eTLmCa1CwAAAA4Ej/+Mc/9Ntvv2nEiBGmowAXjSWCAAAAcJz9+/fr2muv1erVq9WgQQPTcYCLxgQLAAAAjmJZlvr166eBAwdSruA6xUwHAAAAAM711ltvaf/+/Vq6dKnpKECBsUQQAAAAjnHw4EE1bNhQ//rXv9S4cWPTcYACo2ABAADAESzL0l133aVrrrlGY8eONR0HKBSWCAIAAMARFixYoMTERC1cuNB0FKDQmGABAADAuEOHDqlBgwZasWKFmjVrZjoOUGgULAAAABjXtWtX1apVS+PGjTMdBSgSlggCAADAqEWLFmn79u166623TEcBiowJFgAAAIw5fPiwGjRooCVLlui6664zHQcoMgoWAAAAjImPj1flypU1adIk01EAv2CJIAAAAIx47733tHnzZr355pumowB+wwQL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DrlwLZ+k1yWVljRTUmoA7xUjqZ/scsXSMgCAt23YsEErVqzQzp07TUcB4EBMsFzNJ2mSpPmy90RF+vXqlhWp48fD9PHHvXPuQ7kCAHhbVlaW+vfvr4kTJ6pMmTKm4wBwIApWSOgsKVHSHbKnTUX91xomKUY+XycdPLhO8fHztH379qKGBADA9aZNm6bY2FjFx8ebjgLAoShYIaOcpMWS1krqIvtBwNEFvEZ0zud1ybnOItWte71efPFFdenSRSkpKf6LC+M4ph0ACiYpKUnPPvuspk2bxmmsAPLls3iVFaKSZR/nvlzSVklpssuTJSlbdrf2SUqXXawayj4d8EFJsX+4Wt++fXXixAnNnz+fbyoh4MCBA2revLkOHDhgOgoAuEb37t11+eWX67nnnjMdBYCDUbA846CkbZJSJGXI3q9VUlIDSZUu+NlpaWm6/vrr1adPHz388MOBDIogoGABQMGsWrVKffv21bfffquYGFPPogTgBpwi6BmVdDFFKj/R0dFatGiRrr/+ejVv3lxNmzb1XzQAABwsPT1dAwYM0NSpUylXAC6IPVi4aLVr19b06dPVtWtXHT161HQcAACCYsKECbr66qt1xx13mI4CwAVYIogCGzRokPbu3av33nuP/VguxRJBALg4u3fvVosWLbRlyxZVr17ddBwALsAECwU2YcIE/frrr5o0aZLpKAAABIxlWRo4cKBGjBhBuQJw0diDhQKLiIjQO++8o+bNm6tly5a64YYbTEdCITC8BoA/t2TJEu3bt0+DBw82HQWAizDBQqHUqFFD//jHPxQfH6/Dhw+bjoMCYmknAPy5lJQUDR48WDNmzFBERITpOABchIKFQrv99tt133336b777tOZM2dMxwEAwG9Gjx6t9u3b68YbbzQdBYDLULBQJM8++6zS09N56CIAIGRs375dc+fO1YQJE0xHAeBCFCwUSbFixbRgwQLNnDlTq1evNh0HAIAiyc7OVkJCgsaMGaMKFSqYjgPAhShYKLJKlSrp7bff1n333aekpCTTcQAAKLQ5c+YoMzNTffr0MR0FgEtRsOAX7du318MPP6zu3bsrKyvLdBwAAAosOTlZI0eO1IwZMxQeHm46DgCXomDBb5588knFxMToqaeeMh0FF4Fj2gHg90aNGqV77rlHTZo0MR0FgIvxHCz4TVhYmN566y01btxYN9xw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AZo6daqio6NNxwGAC2KChZBSq1Ytvf766+rWrZuSk5NNxwEAFNH48eNVv3593X777aajAMBF4TlYCEnDhw/Xd999p+XLlyssjPcRzpecnKwrrriCEgrA0RITE9WyZUtt2bJF1atXNx0HAC4KrzwRkl544QUdO3ZM48aNMx0FAFAIlmVp4MCBevzxxylXAFyFPVgIScWLF9fChQvVtGlTXX/99WrTpo3pSACAAliyZIn279+vwYMHm44CAAXCBAshq2rVqpozZ4569OihX3/91XQcAMBFSklJ0eDBgzVjxgwVL17cdBwAKBAKFkLaX/7yFz300EPq0aOHzpw5YzqOo7D9EoBTjR49Wh06dFDr1q1NRwGAAuOQC4S8M2fO6JZbblGrVq00ZswY03Ec4ciRI6pdu7aOHDliOgoA/M62bdt000036dtvv1X58uVNxwGAAmOChZAXHh6uefPm6c0339S///1v03EAAPnIzs5WQkKCnn32WcoVANeiYMETKlasqHnz5umBBx7QL7/8YjoOACAPs2fPVlZWlvr06WM6CgAUGgULntGmTRsNHjxY3bt31+nTp03HAQCcIzk5WaNGjdLMmTN5fiEAV+MrGDxlxIgRKlOmjEaNGmU6CgDgHCNHjlT37t117bXXmo4CAEXCc7DgKWFhYZo7d66aNGmiG264QXfeeafpSADgeevXr9fKlSu1c+dO01EAoMiYYMFzYmNjtXDhQvXt21c//fST6TjGcIAoACfIyspSQkKCJk2apNKlS5uOAwBFRsGCJ7Vo0UJPPvmkunbtqvT0dNNxgs7n85mOAACSpFdeeUVxcXHq1q2b6SgA4Bc8BwueZVmWunbtqgoVKmj69Omm4wTV0aNHVatWLR09etR0FAAeduDAATVs2FCff/65rrzyStNxAMAvmGDBs3w+n958802tWrVK8+fPNx0HADxn6NChSkhIoFwBCCkccgFPK126tBYtWqSbb75Z1157rerWrWs6EgB4wkcffaRNmzZp9uzZpqMAgF8xwYLnNWrUSM8//7y6dOmi1NRU03EAIOSlp6drwIABeuWVVxQdHW06DgD4FQULkNS7d281btxYDz/8MKfrAUCAjR8/XvXr19dtt91mOgoA+B0FC5C9H2vGjBnatGmTZs2aZTpOUFAkAZiQmJioKVOmaPLkyaajAEBAsAcLyFGiRAktXrxYN954o5o0aaKGDRuajhQwHNMOwATLsjRw4EA9/vjjqlatmuk4ABAQTLCAc1x11VV66aWX1LVrV504ccJ0HAAIKe+++67279+vwYMHm44CAAHDc7CAPPTr109Hjx7VwoULQ3Lac+zYMdWsWVPHjh0zHQWAR6SkpKhevXqaN2+eWrdubToOAAQMEywgD5MnT9auXbs0bdo001EAICT8/e9/10033US5AhDy2IMF5CEqKkqLFy/Wddddp+bNm6t58+amIwGAa23btk1vvfWWvv32W9NRACDgmGAB+bj88ss1c+ZM3XPPPTpy5IjpOADgStnZ2UpISNDYsWNVvnx503EAIOAoWMCf+Otf/6q77rpLDzzwgLKzs03H8Su2XwIIhtmzZ+vMmTPq3bu36SgAEBQULOACxo0bp99++00TJ040HcVvQvHgDgDOk5ycrCeeeEIzZsxQWBgvOQB4A6cIAhdh3759at68uRYtWhQSG7SPHz+u6tWr6/jx46ajAAhhffr0UUxMDA8VBuApHHIBXITq1atr1qxZio+P15YtW1ShQgXTkQDA0davX6+VK1dq586dpqMAQFAxrwcuUseOHfXAAw/o3nvv1ZkzZ0zHAQDHysrKUkJCgiZNmqTSpUubjgMAQUXBAgpg9OjRysrK0rPPPms6CgA41iuvvKK4uDh169bNdBQACDr2YAEFdPDgQTVp0kRz5szRzTffbDpOobAHC0CgHDhwQA0bNtQXX3yhK664wnQcAAg6JlhAAVWqVEn//Oc/df/99+vAgQOm4xQa760ACIShQ4cqISGBcgXAsyhYQCG0a9dOAwcOVPfu3XX69GnTcQqMY9oBBMJHH32kTZs26YknnjAdBQCMoWABhTRq1ChdcsklevLJJ01HAQDj0tPTNWDAAL3yyiuKjo42HQcAjKFgAYUUFhamt956SwsWLNCyZctMxwEAo8aNG6cGDRrotttuMx0FAIzikAugiNavX68777xTX375pWrWrGk6zkU5ceKEqlatqhMnTpiOAiAEJCYmqmXLlvr6669VrVo103EAwCgKFuAHL730kubNm6fPPvtMkZGRpuNcEAULQN6SJG2TlCIpU1KEpJKSGkqqlOdnWJaljh076qabbtLw4cODFRQAHIuCBfiBZVm6++67VaVKFU2dOtV0nAuiYAGwJUuaJWm5pK2SMiRFSsqW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VK5cOQoWQkpKSkq+z4rKysrK95jzcuXKmY4eAEck1ZbZo9HLStqd86N/HDhwQB9//HHuksJSpUrlTrfatWun0qVL++1eAFBYFCzABbZv36727dtr7dq1uvrqq4t8PQoW3Co1NVWJiYl5ntCXkpKi2rVr53lCX/ny5S/ymPNQskxSvMwsFYyRtED2BCswsrOztX379tzp1vr169WgQYPcwtW8efMAHygCAHmjYAEuMXv2bI0fP14bN24s8qZvChacLCMjQz/99FOeJeq3337TZZddlmeJqly5sgdL1IUMk/SqpFNBvGcJSf0kTQriPe2va5999llu4dq7d6/atWuXu5zw8ssv578PAEFBwQJcpFevXsrIyNDbb79dpBcKFCyYlpWVpb179+Z5uERSUpKqV6+e5+ES1apV45CDArEk9ZE9TQpGySohe2r2miSzZebQoUO5ywk/+ugjRUZG5k632rdvH6JLQwE4AQULcJHU1FS1bNlSAwYMUL9+/Qp9HQoWgiE7O1u//PJLniXq559/VqVKlfIsUTVr1lTx4sVNxw8hlqThkmYqsMsFYyT1l/2wY2dNiizL0s6dO3OnW5999pmuuuqq3MLVsmVLRUREmI4JIERQsACX+eGHH3TDDTfo3//+txo3blyoa1Cw4C+WZengwYN5lqjdu3crNjY2z8MlatWqpaioKNPxPWaZpAdllyx/ni4YKbtczVEg91z5U0ZGhr744ovcwrVr1y7deOONucsJr7zySpYTAig0ChbgQgsXLtQTTzyhzZs3q0yZMgX+/LS0NJUtW1bp6en+D4eQY1mWfvvtt3yPOS9RokS+x5yXKFHCdHz8zhFJfSV9KCldRXsYcZikKEm3yd7n5d4ld7/99ptWr16dW7gsy8qdbt10002Ki4szHRGAi1CwAJcaOHCgkpKS9O677xb4ndb09HSVKVOGgoXfOXbs2B9K1Nmfh4WF5XvMOUdju9Em2Uv5lsleznfx0+yMjHBFRhaX1Fn20sOLe4iwW1iWpR9//DG3bH3yySeqXbt27nSrVatWioyMNB0TgINRsACXysjI0A033KAePXpoyJAhF/lZSZK2KTMzWX37PqjZs+dJKimpoaRKAcsK5zh58uQfJlBnS1R6enqeBeqKK65QbGys6egIiGRJsyUtl7RVdtGKkr1vK1v2lMone9oVrfT0KzV27DY9/XSiIiMrm4kcZKdPn9aGDRtyC9e3336rG264IbdwXX311SwnBPA7FCzAxfbs2aMWLVro/fff13XXXZfH70iWNEv//8VThqRIWVa2Tp5MUcmSJWW/gLI/bhetTpJ6SuIFtVulpaVp9+7dee6LOnbsmC6//PLflaizP69YsSIvFD3voKRtklL0/78ulJTUQGffhLnxxhs1fPhwde7c2VRIo44ePar//Oc/uacTpqen6+abb85dTnjppZeajgjAMAoW4HLLli3TwIEDtWXLlnP2CWyU/Qyagi//kaJlv3vdWfYzdJr7My78JDMzU3v27MmzRB06dEiXXXZZnif0ValSRWFhYabjw8VmzJihTz/9VPPnzzcdxRF2796dO91as2aNqlevnrt/q3Xr1oqOjjYdEUCQUbCAEDBixAht375dH3zwlsLC+su/G9g7yn6mjXs3sLvVmTNn9PPPP+dZovbv36+qVavmuS+qevXqKlasmOn4CFGHDx9W7dq1deDAgSI/9DzUZGVladOmTbmFa+vWrWrZsmXucsIGDRrwBgfgARQsIAScPn1aTz/dUM88s0fR0Za8fgSzm2RnZ+vAgQN5ntC3Z88eVaxYMc8Sddlll/HcHhjTsWNH/e///q969OhhOoqjHT9+XGvXrs0tXMeOHctdTnjzzTerSpUqpiM6gL032F6WmikpQuwNhttRsADXsx8imp09Q2FhgXyulXMfIup0lmXp0KFDeZaoxMRElSlTJs8Sdfnll7O8CI701ltv6Z133tHy5ctNR3GVvXv3atWqVVq1apVWr16tSy+9NHe61aZNG4881iDvvcH2igtL9vcX9gbD3ShYgKtZkvpIWiDpVBDuV0JSd0mvi5L1R8nJyXkec56YmKjIyMg8T+irXbt2zmEjgHukpKSoatWq2rNnj8qVY/lwYZw5c0ZbtmzJnW599dVXatasWW7huvbaaxUeHm46ph+xNxjeQcECXG2Y7Ad8BqNcnVVCUj/Z3yi95/jx4/kec56dnZ1niapTp47Kli1rOjrgV127dtUtt9yiPn36mI4SEk6ePKlPPvkkt3D997//VYcOHXKXE9aoUcN0xEIKxMOt2RsMZ6NgAa61TFK8pFQD946RPTULzT1Zp06dUmJiYp6HS5w6dUq1a9fO85jzuLg4jjmHZyxZskRTp07VmjVrTEcJSfv3789dTrhq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9NVXX2n48OGmoygqKkrFixfXyZMnTUcB4HGXXHKJbr31Vi1evNh0FAAoFAoWYEBWVpYGDRqkiRMnKjo62nQcSSwTBOAcPXr0YJkgANeiYAEGvPbaaypXrpzuvvtu01FycdAFAKe49dZbtWPHDu3fv990FAAoMAoWEGRHjhzR3//+d02ePNlR+52YYAFwisjISN15551auHCh6SgAUGAULCDInnnmGd19991q2LCh6Si/Q8EC4CScJgjArYqZDgB4yY4dO7Rw4ULt3LnTdJQ/YIkgACdp166dDhw4oB9//FFXXHGF6TgAcNGYYAFBYlmWBg8erKefftqRRw8zwQLgJOHh4brnnnuYYgFwHQoWECTvv/++Dh48qP79+5uOkicmWACc5uwyQR7ZCcBNKFhAEKSnp2vo0KGaPHmyihcvbjpOnphgAXCaFi1aKDMzU998843pKABw0ShYQBC89NJLatCggW666SbTUfJFwQLgND6fT927d9e8efNMRwGAi0bBAgLswIEDmjhxoiZNmmQ6yp9iiSAAJ+rRo4cWLFig7Oxs01EA4KJQsIAAGzVqlPr27avLL7/cdJQ/xQQLgBNdc801KlOmjD7//HPTUQDgonBMOxBAGzZs0OrVq/X999+bjnJBTLAAONXZwy5at25tOgoAXJDP4mgeICCys7PVsmVLDRw4UPfff7/pOBdkWZaio6N19OhRRUdHm44DALl++ukntWjRQklJSY49KAgAzmKJIBAgc+fOVVhYmO677z7TUS6Kz+djmSAAR6pVq5Zq166tjz/+2HQUALggChYQACdOnNATTzyhyZMnKyzMPX/NWCYIwKnOLhMEAKdzzys/wEWee+453XLLLWrRooXpKAXCBAuAU91zzz1avny50tLSTEcBgD9FwQL8bNeuXXrzzTf1wgsvmI5SYEywADjVpZdeqiZNmmjFihWmowDAn6JgAX42bNgwPfbYY6pUqZLpKAXGBAuAk/Xo0YNlggAcj4IF+NG///1v7dy5U4MHDzYdpVAoWACc7K9//atWr16t48ePm44CAPmiYAF+cvr0aQ0ePFgvvviiIiMjTccpFJYIAnCyMmXKqF27dlq6dKnpKACQLwoW4CfTpk1TtWrV1KlTJ9NRCo0JFgCni4+P17x580zHAIB8UbAAPzh8+LCee+45vfzyy/L5fKbjFBoTLABO16lTJ23cuFGHDh0yHQUA8kTBAvzgqaee0r333qt69eqZjlIkTLAAOF1MTIzuuOMOLVq0yHQUAMgTBQsoom+++UbvvfeennnmGdNRioyCBcANeOgwACfzWZZlmQ4BuJVlWWrTpo3uvfde9evXz3ScIjt+/LiqVaumEydOmI4CAPnKzMxU5cqV9dVXX6lmzZqm4wDA7zDBAopg0aJFOnHihHr37m06il+UKlVKaWlpyszMNB0FAPIVERGhLl26aMGCBaajAMAfULCAQkpNTdVjjz2myZMnKzw83HQcv/D5fCwTBOAKLBME4FQULKCQJkyYoBYtWqhNmzamo/gVBQuAG7Ru3VrJycn69ttvTUcBgN+hYAGFsG/fPk2ZMkUTJkwwHcXvKFgA3CAsLEzdunVjigXAcShYQCGMGDFCAwcOVI0aNUxH8TuehQXALXr06KH58+eL87oAOAkFCyigTz/9VF988YUef/xx01ECggkWALdo3LixwsPDtWnTJtNRACAXBQsogDNnzmjQoEEaP368YmJiTMcJiNjYWCZYAFzB5/Nx2AUAx6FgAQXw5ptv6pJLLlG3bt1MRwmYuLg4JlgAXCM+Pl4LFy7UmTNnTEcBAEkULOCiHTt2TH/72980ZcoU+Xw+03EChiWCANykbt26uvTSS/XJJ5+YjgIAkihYwEUbPXq0OnfurGuvvdZ0lIDikAsAbsMyQQBOUsx0AMANvvvuO7399tueeN4KEywAbtOtWzdde+21euWVVxQZGWk6DgCPY4IFXIBlWRo8eLCeeOIJVahQwXScgOOQCwBuU716ddWrV0///ve/TUcBAAoWcCErVqzQvn37NHDgQNNRgoJDLgC40dlnYgGAaT6Lp/MB+crIyNA111yjqVOn6tZbbzUdJyjOnDmjyMhIpaenq1gxVhEDcIfDhw+rTp06OnDggEqUKGE6DgAPY4IF/InJkyerbt26nilXkhQeHq4yZcro6NGjpqMAwEUrX768rrvuOi1btsx0FAAeR8EC8vHrr79q/PjxevHFF01HCToOugDgRpwmCMAJKFhAPkaNGqVevXqpTp06pqMEHQddAHCjO++8U5988omOHDliOgoAD6NgAXnYtGmT/v3vf+upp54yHcUIDroA4EalSpXSLbfconfffdd0FAAeRsECzpOdna1HH31Uzz33nEqVKmU6jhEsEQTgViwT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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# import networkx\n",
+ "import networkx as nx\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "fig = plt.figure(figsize=(12,12))\n",
+ "ax = plt.subplot(111)\n",
+ "ax.set_title('Graph - Shapes', fontsize=10)\n",
+ "\n",
+ "# initiate graph\n",
+ "graph = nx.MultiGraph()\n",
+ "\n",
+ "# create edges from dataframe\n",
+ "graph = nx.from_pandas_edgelist(df_edges, source = 'from', target = 'to', edge_attr= 'label')\n",
+ "\n",
+ "# update node attributes from dataframe\n",
+ "nodes_attr = df_nodes.set_index('id').to_dict(orient = 'index')\n",
+ "nx.set_node_attributes(graph, nodes_attr)\n",
+ "\n",
+ "\n",
+ "pos = nx.spring_layout(graph)\n",
+ "nx.draw(graph, pos, node_size=1500, node_color='yellow', font_size=8, font_weight='bold')\n",
+ "\n",
+ "plt.tight_layout()\n",
+ "plt.show()\n",
+ "plt.savefig(\"Graph.png\", format=\"PNG\")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Visualisierung des Netzwerks mit pyvis\n",
+ "\n",
+ "Für die Visualisierung importieren wir `Network` von `pyvis.network` und initialisiern das `pyvis` Netzwerk. Mit der Methode `from_nx` können wir das `networkx` Netzwerk übergeben. \n",
+ "\n",
+ "Die Größe der Knoten bestimmen wir je nach Auswahl entweder aufgrund der Anzahl der Verbindungen zu anderen Knoten oder anhand der Eigenvektor-Zentralität. Knoten mit vielen Verbindungen bzw. höherer Zentralität werden größer dargestellt."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# visualize using pyvis\n",
+ "from pyvis.network import Network\n",
+ "\n",
+ "def create_centrality_graph(df, measure_type, save_path):\n",
+ " # initiate network\n",
+ " net = Network(directed=False, neighborhood_highlight=True, bgcolor = \"white\", font_color=\"black\")\n",
+ "\n",
+ " # pass networkx graph to pyvis\n",
+ " net.from_nx(graph)\n",
+ "\n",
+ " # set edge options \n",
+ " net.inherit_edge_colors(False)\n",
+ " net.set_edge_smooth('dynamic')\n",
+ "\n",
+ " adj_list = net.get_adj_list()\n",
+ "\n",
+ " measure_vector = {}\n",
+ "\n",
+ " if measure_type == \"eigenvector\":\n",
+ " measure_vector = nx.eigenvector_centrality(graph)\n",
+ " df[\"eigenvector\"] = measure_vector.values()\n",
+ " if measure_type == \"degree\":\n",
+ " measure_vector = nx.degree_centrality(graph)\n",
+ " df[\"degree\"] = measure_vector.values()\n",
+ " if measure_type == \"betweeness\":\n",
+ " measure_vector = nx.betweenness_centrality(graph)\n",
+ " df[\"betweeness\"] = measure_vector.values()\n",
+ " if measure_type == \"closeness\":\n",
+ " measure_vector = nx.closeness_centrality(graph)\n",
+ " df[\"closeness\"] = measure_vector.values()\n",
+ " if measure_type == \"pagerank\":\n",
+ " measure_vector = nx.pagerank(graph)\n",
+ " df[\"pagerank\"] = measure_vector.values()\n",
+ " if measure_type == \"average_degree\":\n",
+ " measure_vector = nx.average_degree_connectivity(graph)\n",
+ " # df[\"average_degree\"] = measure_vector.values()\n",
+ " print(measure_vector.values())\n",
+ " \n",
+ "\n",
+ " # calculate and update size of the nodes depending on their number of edges\n",
+ " for node_id, neighbors in adj_list.items():\n",
+ " \n",
+ " # df[\"edges\"] = measure_vector.values()\n",
+ " \n",
+ " if measure_type == \"edges\":\n",
+ " size = 10 #len(neighbors)*5 \n",
+ " else:\n",
+ " size = measure_vector[node_id]*50 \n",
+ " next((node.update({'size': size}) for node in net.nodes if node['id'] == node_id), None)\n",
+ "\n",
+ " # set the node distance and spring lenght using repulsion\n",
+ " net.repulsion(node_distance=150, spring_length=50)\n",
+ "\n",
+ " # activate physics buttons to further explore the available solvers:\n",
+ " # barnesHut, forceAtlas2Based, repulsion, hierarchicalRepulsion\n",
+ " net.show_buttons(filter_=['physics'])\n",
+ "\n",
+ " # save graph as HTML\n",
+ " net.save_graph(save_path)\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Alle zusammen ausführen und ein DataFram erstellen mit allen Nodes je nach Kennzahl aufgeteilt."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " eigenvector | \n",
+ " degree | \n",
+ " betweeness | \n",
+ " closeness | \n",
+ " pagerank | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.241703 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.416667 | \n",
+ " 0.053313 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 0.633039 | \n",
+ " 0.6 | \n",
+ " 0.777778 | \n",
+ " 0.666667 | \n",
+ " 0.280074 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 0.241703 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.416667 | \n",
+ " 0.053313 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 0.449459 | \n",
+ " 0.4 | \n",
+ " 0.644444 | \n",
+ " 0.625000 | \n",
+ " 0.187550 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 0.241703 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.416667 | \n",
+ " 0.053313 | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " 0.241703 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.416667 | \n",
+ " 0.053313 | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " 0.241703 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.416667 | \n",
+ " 0.053313 | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " 0.171611 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.400000 | \n",
+ " 0.053491 | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " 0.171611 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.400000 | \n",
+ " 0.053491 | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " 0.076707 | \n",
+ " 0.1 | \n",
+ " 0.000000 | \n",
+ " 0.312500 | \n",
+ " 0.056939 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " 0.200900 | \n",
+ " 0.2 | \n",
+ " 0.200000 | \n",
+ " 0.434783 | \n",
+ " 0.101890 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " eigenvector degree betweeness closeness pagerank\n",
+ "0 0.241703 0.1 0.000000 0.416667 0.053313\n",
+ "1 0.633039 0.6 0.777778 0.666667 0.280074\n",
+ "2 0.241703 0.1 0.000000 0.416667 0.053313\n",
+ "3 0.449459 0.4 0.644444 0.625000 0.187550\n",
+ "4 0.241703 0.1 0.000000 0.416667 0.053313\n",
+ "5 0.241703 0.1 0.000000 0.416667 0.053313\n",
+ "6 0.241703 0.1 0.000000 0.416667 0.053313\n",
+ "7 0.171611 0.1 0.000000 0.400000 0.053491\n",
+ "8 0.171611 0.1 0.000000 0.400000 0.053491\n",
+ "9 0.076707 0.1 0.000000 0.312500 0.056939\n",
+ "10 0.200900 0.2 0.200000 0.434783 0.101890"
+ ]
+ },
+ "execution_count": 88,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "centrality_comparison_df = pd.DataFrame()\n",
+ "\n",
+ "eigenvector_path = \"./metrics/eigenvector_networkx.html\"\n",
+ "degree_path = \"./metrics/degree_networkx.html\"\n",
+ "betweeness_path = \"./metrics/betweeness_networkx.html\"\n",
+ "closeness_path = \"./metrics/closeness_networkx.html\"\n",
+ "pagerank_path = \"./metrics/pagerank_networkx.html\"\n",
+ "average_degree_path = \"./metrics/average_degree_path_networkx.html\"\n",
+ "edges_path = \"./metrics/edges_path_networkx.html\"\n",
+ "\n",
+ "create_centrality_graph(centrality_comparison_df, \"eigenvector\", eigenvector_path)\n",
+ "create_centrality_graph(centrality_comparison_df, \"degree\", degree_path)\n",
+ "create_centrality_graph(centrality_comparison_df, \"betweeness\", betweeness_path)\n",
+ "create_centrality_graph(centrality_comparison_df, \"closeness\", closeness_path)\n",
+ "create_centrality_graph(centrality_comparison_df, \"pagerank\", pagerank_path)\n",
+ "# create_centrality_graph(centrality_comparison_df, \"average_degree\", average_degree_path)\n",
+ "create_centrality_graph(centrality_comparison_df, \"edges\", edges_path)\n",
+ "\n",
+ "centrality_comparison_df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 95,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0.18181818181818182\n",
+ "4\n",
+ "2.327272727272727\n",
+ "Graph with 11 nodes and 10 edges\n",
+ "0.0\n",
+ "{1: 5.0, 6: 1.5, 4: 2.5, 2: 2.5}\n",
+ "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}\n",
+ "[]\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(nx.density(graph))\n",
+ "print(nx.diameter(graph))\n",
+ "print(nx.average_shortest_path_length(graph))\n",
+ "print(nx.k_core(graph))\n",
+ "print(nx.average_clustering(graph))\n",
+ "print(nx.average_degree_connectivity(graph))\n",
+ "# print(nx.community.modularity(graph, [{ 1, 2}]))\n",
+ "print(max(nx.connected_components(graph)))\n",
+ "s = [graph.subgraph(c).copy() for c in nx.connected_components(graph)]\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 96,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AssertionError",
+ "evalue": "",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32mc:\\Users\\Tim\\Documents\\Master\\Semester 4\\Projektgruppe\\aki_prj23_transparenzregister\\documentations\\seminararbeiten\\Verflechtungsanalyse\\mockup_verflechtungsanalyse_with_networkx.ipynb Cell 17\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m net \u001b[39m=\u001b[39m Network(directed\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m, neighborhood_highlight\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, bgcolor \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mwhite\u001b[39m\u001b[39m\"\u001b[39m, font_color\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mblack\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 3\u001b[0m \u001b[39m# pass networkx graph to pyvis\u001b[39;00m\n\u001b[1;32m----> 4\u001b[0m net\u001b[39m.\u001b[39;49mfrom_nx(s)\n\u001b[0;32m 6\u001b[0m \u001b[39m# set edge options \u001b[39;00m\n\u001b[0;32m 7\u001b[0m net\u001b[39m.\u001b[39minherit_edge_colors(\u001b[39mFalse\u001b[39;00m)\n",
+ "File \u001b[1;32mc:\\Users\\Tim\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\pyvis\\network.py:689\u001b[0m, in \u001b[0;36mNetwork.from_nx\u001b[1;34m(self, nx_graph, node_size_transf, edge_weight_transf, default_node_size, default_edge_weight, show_edge_weights, edge_scaling)\u001b[0m\n\u001b[0;32m 660\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mfrom_nx\u001b[39m(\u001b[39mself\u001b[39m, nx_graph, node_size_transf\u001b[39m=\u001b[39m(\u001b[39mlambda\u001b[39;00m x: x), edge_weight_transf\u001b[39m=\u001b[39m(\u001b[39mlambda\u001b[39;00m x: x),\n\u001b[0;32m 661\u001b[0m default_node_size \u001b[39m=\u001b[39m\u001b[39m10\u001b[39m, default_edge_weight\u001b[39m=\u001b[39m\u001b[39m1\u001b[39m, show_edge_weights\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, edge_scaling\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m):\n\u001b[0;32m 662\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[0;32m 663\u001b[0m \u001b[39m This method takes an exisitng Networkx graph and translates\u001b[39;00m\n\u001b[0;32m 664\u001b[0m \u001b[39m it to a PyVis graph format that can be accepted by the VisJs\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 687\u001b[0m \u001b[39m >>> nt.show(\"nx.html\")\u001b[39;00m\n\u001b[0;32m 688\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 689\u001b[0m \u001b[39massert\u001b[39;00m(\u001b[39misinstance\u001b[39m(nx_graph, nx\u001b[39m.\u001b[39mGraph))\n\u001b[0;32m 690\u001b[0m edges\u001b[39m=\u001b[39mnx_graph\u001b[39m.\u001b[39medges(data \u001b[39m=\u001b[39m \u001b[39mTrue\u001b[39;00m)\n\u001b[0;32m 691\u001b[0m nodes\u001b[39m=\u001b[39mnx_graph\u001b[39m.\u001b[39mnodes(data \u001b[39m=\u001b[39m \u001b[39mTrue\u001b[39;00m)\n",
+ "\u001b[1;31mAssertionError\u001b[0m: "
+ ]
+ }
+ ],
+ "source": [
+ "net = Network(directed=False, neighborhood_highlight=True, bgcolor = \"white\", font_color=\"black\")\n",
+ "\n",
+ "# pass networkx graph to pyvis\n",
+ "net.from_nx(s)\n",
+ "\n",
+ "# set edge options \n",
+ "net.inherit_edge_colors(False)\n",
+ "net.set_edge_smooth('dynamic')\n",
+ "\n",
+ "adj_list = net.get_adj_list()\n",
+ "\n",
+ "# calculate and update size of the nodes depending on their number of edges\n",
+ "for node_id, neighbors in adj_list.items():\n",
+ " \n",
+ " # df[\"edges\"] = measure_vector.values()\n",
+ " \n",
+ " \n",
+ " size = 10 #len(neighbors)*5 \n",
+ " \n",
+ " next((node.update({'size': size}) for node in net.nodes if node['id'] == node_id), None)\n",
+ "\n",
+ "# set the node distance and spring lenght using repulsion\n",
+ "net.repulsion(node_distance=150, spring_length=50)\n",
+ "\n",
+ "# activate physics buttons to further explore the available solvers:\n",
+ "# barnesHut, forceAtlas2Based, repulsion, hierarchicalRepulsion\n",
+ "net.show_buttons(filter_=['physics'])\n",
+ "\n",
+ "# save graph as HTML\n",
+ "net.save_graph(\"./metrics/connected_components_networkx.html\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.10.1 64-bit",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.13"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/documentations/seminararbeiten/Verflechtungsanalyse/relations.csv b/documentations/seminararbeiten/Verflechtungsanalyse/relations.csv
new file mode 100644
index 0000000..bd436e4
--- /dev/null
+++ b/documentations/seminararbeiten/Verflechtungsanalyse/relations.csv
@@ -0,0 +1,11 @@
+from;to;label
+2;1;part_of
+3;1;part_of
+4;1;part_of
+5;1;part_of
+6;1;part_of
+7;1;part_of
+8;4;part_of
+9;4;part_of
+11;10;part_of
+10;4;supplierer
\ No newline at end of file
|