{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Beispiele\n", "\n", "`Graph`- und `Digraph`-Objekte haben eine `_repr_svg_()`-Methode, sodass sie direkt in einem Jupyter-Notebook gerendert und dargestellt werden können." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Einfaches Beispiel" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import graphviz" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "hello-pythonistas\n", "\n", "\n", "\n", "Hello\n", "\n", "Hello\n", "\n", "\n", "\n", "Pythonistas!\n", "\n", "Pythonistas!\n", "\n", "\n", "\n", "Hello->Pythonistas!\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dot = graphviz.Digraph(\"hello-pythonistas\", comment=\"Hello world example\")\n", "\n", "dot.edge(\"Hello\", \"Pythonistas!\")\n", "\n", "dot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ihr könnt euch auch den Quelltext ausgeben lassen mit:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "// Hello world example\n", "digraph \"hello-pythonistas\" {\n", "\tHello -> \"Pythonistas!\"\n", "}\n", "\n" ] } ], "source": [ "print(dot.source)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Auch die Ausgabe des Kommentars oder anderer Elemente des Quelltexts sind möglich, z.B. mit:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello world example\n" ] } ], "source": [ "print(dot.comment)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ihr könnt auch Daten aus einem pandas DataFrame verwenden, z.B.:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
actionview
0single useJupyter
1teamworkJupyterHub
2convertnbconvert
3Java, R, Julia etc.kernels
4extendextensions
\n", "
" ], "text/plain": [ " action view\n", "0 single use Jupyter\n", "1 teamwork JupyterHub\n", "2 convert nbconvert\n", "3 Java, R, Julia etc. kernels\n", "4 extend extensions" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "\n", "j = {\n", " \"action\": [\n", " \"single use\",\n", " \"teamwork\",\n", " \"convert\",\n", " \"Java, R, Julia etc.\",\n", " \"extend\",\n", " ],\n", " \"view\": [\"Jupyter\", \"JupyterHub\", \"nbconvert\", \"kernels\", \"extensions\"],\n", "}\n", "\n", "df = pd.DataFrame(j)\n", "\n", "df" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "jupyter_moons\n", "\n", "\n", "\n", "What do you want to do?\n", "\n", "What do you want to do?\n", "\n", "\n", "\n", "Jupyter\n", "\n", "Jupyter\n", "\n", "\n", "\n", "What do you want to do?--Jupyter\n", "\n", "single use\n", "\n", "\n", "\n", "JupyterHub\n", "\n", "JupyterHub\n", "\n", "\n", "\n", "What do you want to do?--JupyterHub\n", "\n", "teamwork\n", "\n", "\n", "\n", "nbconvert\n", "\n", "nbconvert\n", "\n", "\n", "\n", "What do you want to do?--nbconvert\n", "\n", "convert\n", "\n", "\n", "\n", "kernels\n", "\n", "kernels\n", "\n", "\n", "\n", "What do you want to do?--kernels\n", "\n", "Java, R, Julia etc.\n", "\n", "\n", "\n", "extensions\n", "\n", "extensions\n", "\n", "\n", "\n", "What do you want to do?--extensions\n", "\n", "extend\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "jm = graphviz.Graph(\"jupyter_moons\", comment=\"Jupyter moons\")\n", "\n", "jm.node(\"What do you want to do?\")\n", "\n", "for index, row in df.iterrows():\n", " jm.edge(\n", " \"What do you want to do?\", str(row[\"view\"]), label=(str(row[\"action\"]))\n", " )\n", "\n", "jm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Styling\n", "\n", "Ihr könnt `graph_attr`-, `node_attr`- und `edge_attr`-Argumente der `Graph`- und `Digraph`-Konstuktoren verwenden, um die [Standardattribute von Graphviz](https://www.graphviz.org/doc/info/attrs.html) für eure Graphen, Knoten und Kanten zu ändern, z.B.:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "hello-pythonistas\n", "\n", "\n", "\n", "Hello\n", "Hello\n", "\n", "\n", "\n", "Pythonistas!\n", "Pythonistas!\n", "\n", "\n", "\n", "Hello->Pythonistas!\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dot = graphviz.Digraph(\n", " \"hello-pythonistas\",\n", " comment=\"Hello world example\",\n", " node_attr={\"shape\": \"plaintext\"},\n", ")\n", "\n", "dot.edge(\"Hello\", \"Pythonistas!\")\n", "\n", "dot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Die `graph_attr`-, `node_attr`- und `edge_attr`-Argumente können auch auf Instanzen angewendet werden:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "hello-pythonistas\n", "\n", "\n", "\n", "Hello\n", "Hello\n", "\n", "\n", "\n", "Pythonistas!\n", "Pythonistas!\n", "\n", "\n", "\n", "Hello->Pythonistas!\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dot.graph_attr[\"rankdir\"] = \"LR\"\n", "\n", "dot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Um `att_stmt`-Attributanweisungen direkt hinzuzufügen, ruft die `attr()`-Methode der `Graph`- oder `Digraph`-Instanz mit dem gewünschten Ziel als erstes Argument und den Attributen als Schlüsselwort-Argument auf.\n", "\n", "
\n", "\n", "**Hinweis:**\n", "\n", "Attribut-Anweisungen wirken sich auf alle späteren Graphen, Knoten oder Kanten innerhalb desselben (Sub-)Graphen aus.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Engines\n", "\n", "Neben Dot können auch verschiedene andere [Layout Engines](https://graphviz.org/docs/layouts/) verwendet werden." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "python_visualisation_landscape\n", "\n", "\n", "\n", "Matplotlib\n", "\n", "Matplotlib\n", "\n", "\n", "\n", "pandas\n", "\n", "pandas\n", "\n", "\n", "\n", "Matplotlib--pandas\n", "\n", "\n", "\n", "\n", "Geoplot\n", "\n", "Geoplot\n", "\n", "\n", "\n", "Matplotlib--Geoplot\n", "\n", "\n", "\n", "\n", "descartes\n", "\n", "descartes\n", "\n", "\n", "\n", "Matplotlib--descartes\n", "\n", "\n", "\n", "\n", "seaborn\n", "\n", "seaborn\n", "\n", "\n", "\n", "Matplotlib--seaborn\n", "\n", "\n", "\n", "\n", "ggpy\n", "\n", "ggpy\n", "\n", "\n", "\n", "Matplotlib--ggpy\n", "\n", "\n", "\n", "\n", "plotnine\n", "\n", "plotnine\n", "\n", "\n", "\n", "Matplotlib--plotnine\n", "\n", "\n", "\n", "\n", "scikit_plot\n", "\n", "scikit_plot\n", "\n", "\n", "\n", "Matplotlib--scikit_plot\n", "\n", "\n", "\n", "\n", "GeoPandas\n", "\n", "GeoPandas\n", "\n", "\n", "\n", "pandas--GeoPandas\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pvl = graphviz.Graph(\"python_visualisation_landscape\", engine=\"neato\")\n", "\n", "pvl.edge(\"Matplotlib\", \"pandas\")\n", "pvl.edge(\"pandas\", \"GeoPandas\")\n", "pvl.edge(\"Matplotlib\", \"Geoplot\")\n", "pvl.edge(\"Matplotlib\", \"descartes\")\n", "pvl.edge(\"Matplotlib\", \"seaborn\")\n", "pvl.edge(\"Matplotlib\", \"ggpy\")\n", "pvl.edge(\"Matplotlib\", \"plotnine\")\n", "pvl.edge(\"Matplotlib\", \"scikit_plot\")\n", "\n", "pvl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ihr könnt auch das `engine`-Attribut einer bestehenden Instanz ändern:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "python_visualisation_landscape\n", "\n", "\n", "\n", "Matplotlib\n", "\n", "Matplotlib\n", "\n", "\n", "\n", "pandas\n", "\n", "pandas\n", "\n", "\n", "\n", "Matplotlib--pandas\n", "\n", "\n", "\n", "\n", "Geoplot\n", "\n", "Geoplot\n", "\n", "\n", "\n", "Matplotlib--Geoplot\n", "\n", "\n", "\n", "\n", "descartes\n", "\n", "descartes\n", "\n", "\n", "\n", "Matplotlib--descartes\n", "\n", "\n", "\n", "\n", "seaborn\n", "\n", "seaborn\n", "\n", "\n", "\n", "Matplotlib--seaborn\n", "\n", "\n", "\n", "\n", "ggpy\n", "\n", "ggpy\n", "\n", "\n", "\n", "Matplotlib--ggpy\n", "\n", "\n", "\n", "\n", "plotnine\n", "\n", "plotnine\n", "\n", "\n", "\n", "Matplotlib--plotnine\n", "\n", "\n", "\n", "\n", "scikit_plot\n", "\n", "scikit_plot\n", "\n", "\n", "\n", "Matplotlib--scikit_plot\n", "\n", "\n", "\n", "\n", "GeoPandas\n", "\n", "GeoPandas\n", "\n", "\n", "\n", "pandas--GeoPandas\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pvl.engine = \"circo\"\n", "\n", "pvl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eine vollständige Übersicht über die Engines erhaltet ihr mit:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "circo\n", "dot\n", "fdp\n", "neato\n", "osage\n", "patchwork\n", "sfdp\n", "twopi\n" ] } ], "source": [ "for engine in sorted(graphviz.ENGINES):\n", " print(engine)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dateien schreiben und lesen" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'python_visualisation_landscape.gv'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pvl.save()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "python_visualisation_landscape\n", "\n", "\n", "\n", "Matplotlib\n", "\n", "Matplotlib\n", "\n", "\n", "\n", "pandas\n", "\n", "pandas\n", "\n", "\n", "\n", "Matplotlib--pandas\n", "\n", "\n", "\n", "\n", "Geoplot\n", "\n", "Geoplot\n", "\n", "\n", "\n", "Matplotlib--Geoplot\n", "\n", "\n", "\n", "\n", "descartes\n", "\n", "descartes\n", "\n", "\n", "\n", "Matplotlib--descartes\n", "\n", "\n", "\n", "\n", "seaborn\n", "\n", "seaborn\n", "\n", "\n", "\n", "Matplotlib--seaborn\n", "\n", "\n", "\n", "\n", "ggpy\n", "\n", "ggpy\n", "\n", "\n", "\n", "Matplotlib--ggpy\n", "\n", "\n", "\n", "\n", "plotnine\n", "\n", "plotnine\n", "\n", "\n", "\n", "Matplotlib--plotnine\n", "\n", "\n", "\n", "\n", "scikit_plot\n", "\n", "scikit_plot\n", "\n", "\n", "\n", "Matplotlib--scikit_plot\n", "\n", "\n", "\n", "\n", "GeoPandas\n", "\n", "GeoPandas\n", "\n", "\n", "\n", "pandas--GeoPandas\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "graphviz.Source.from_file(\"python_visualisation_landscape.gv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dot-Dateien konvertieren" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eine Dot-Datei kann in ein anderes Format, z.B. PDF, PNG, SVG etc., umgewandelt werden mit `render`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'python_visualisation_landscape.gv.svg'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from graphviz import render\n", "\n", "\n", "render(\"dot\", \"svg\", \"python_visualisation_landscape.gv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " \n", "**Siehe auch:**\n", "\n", "* [graphviz manual](https://graphviz.readthedocs.io/en/stable/manual.html#jupyter-notebooks)\n", "* [examples/graphviz-notebook](https://nbviewer.org/github/xflr6/graphviz/blob/master/examples/graphviz-notebook.ipynb)\n", "* [examples/graphviz-engines](https://nbviewer.org/github/xflr6/graphviz/blob/master/examples/graphviz-engines.ipynb)\n", "* [examples/graphviz-escapes.ipynb](https://nbviewer.org/github/xflr6/graphviz/blob/master/examples/graphviz-escapes.ipynb)\n", "* [Graphviz Online](https://dreampuf.github.io/GraphvizOnline/)\n", "
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.11 Kernel", "language": "python", "name": "python311" }, "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.11.4" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 2 }