{ "cells": [ { "cell_type": "markdown", "id": "cc191d89", "metadata": {}, "source": [ "# Basic use\n", "\n", "This Jupyter notebook gives an overview of the Python package [gravis](https://pypi.org/project/gravis). The .ipynb file can be found [here](https://github.com/robert-haas/gravis/tree/master/examples)." ] }, { "cell_type": "code", "execution_count": null, "id": "51a0be7d", "metadata": { "scrolled": false }, "outputs": [], "source": [ "import gravis as gv" ] }, { "cell_type": "markdown", "id": "b4762356", "metadata": {}, "source": [ "## Create a graph" ] }, { "cell_type": "markdown", "id": "6cfb386b", "metadata": {}, "source": [ "### 1) String or dictionary in gJGF\n", "\n", "This package uses a custom format called [gravis JSON graph format (gJGF)](../../rst/format_specification.html). The following example encodes a simple but well-known graph ([en](https://en.wikipedia.org/wiki/Eulerian_path), [de](https://de.wikipedia.org/wiki/Haus_vom_Nikolaus)) as dictionary in gJGF." ] }, { "cell_type": "code", "execution_count": null, "id": "00de2c8a", "metadata": {}, "outputs": [], "source": [ "graph1 = {\n", " 'graph':{\n", " 'directed': True,\n", " 'metadata': {\n", " 'arrow_size': 5,\n", " 'background_color': 'black',\n", " 'edge_size': 3,\n", " 'edge_label_size': 14,\n", " 'edge_label_color': 'white',\n", " 'node_size': 15,\n", " 'node_color': 'white',\n", " },\n", " 'nodes': {\n", " 1: {'metadata': {'shape': 'rectangle', 'y': 200}},\n", " 2: {},\n", " 3: {},\n", " 4: {'metadata': {'shape': 'rectangle', 'y': 200}},\n", " 5: {'metadata': {'shape': 'hexagon', 'y': 0}},\n", " },\n", " 'edges': [\n", " {'source': 1, 'target': 2, 'metadata': {'color': '#d73027', 'de': 'Das', 'en': 'This'}},\n", " {'source': 2, 'target': 3, 'metadata': {'color': '#f46d43', 'de': 'ist', 'en': 'is'}},\n", " {'source': 3, 'target': 1, 'metadata': {'color': '#fdae61', 'de': 'das', 'en': 'the'}},\n", " {'source': 1, 'target': 4, 'metadata': {'color': '#fee08b', 'de': 'Haus', 'en': 'house'}},\n", " {'source': 4, 'target': 3, 'metadata': {'color': '#d9ef8b', 'de': 'vom', 'en': 'of'}},\n", " {'source': 3, 'target': 5, 'metadata': {'color': '#a6d96a', 'de': 'Ni-.', 'en': 'San-'}},\n", " {'source': 5, 'target': 2, 'metadata': {'color': '#66bd63', 'de': 'ko-', 'en': 'ta'}},\n", " {'source': 2, 'target': 4, 'metadata': {'color': '#1a9850', 'de': 'laus.', 'en': 'Claus.'}},\n", " ],\n", " }\n", "}" ] }, { "cell_type": "markdown", "id": "e0f70e69", "metadata": {}, "source": [ "### 2) Graph object from external library\n", "\n", "This package provides support for recognizing graph objects from external libraries. It also allows to add graph annotations, which are mapped to visual elements and their appearance.\n", "\n", "The following example shows how to create a graph object with [NetworkX](https://networkx.org) and add node sizes and colors coming from [centrality calculation](https://networkx.org/documentation/stable/reference/algorithms/centrality.html) and [community detection](https://networkx.org/documentation/stable/reference/algorithms/community.html)." ] }, { "cell_type": "code", "execution_count": null, "id": "28f78c1e", "metadata": {}, "outputs": [], "source": [ "import networkx as nx\n", "\n", "graph2 = nx.les_miserables_graph()\n", "\n", "# Centrality calculation\n", "centrality = nx.algorithms.degree_centrality(graph2)\n", "\n", "# Community detection\n", "communities = nx.algorithms.community.greedy_modularity_communities(graph2)\n", "\n", "# Assignment of node sizes\n", "nx.set_node_attributes(graph2, centrality, 'size')\n", "\n", "# Assignment of node colors\n", "colors = ['red', 'blue', 'green', 'orange', 'pink']\n", "for community, color in zip(communities, colors):\n", " for node in community:\n", " graph2.nodes[node]['color'] = color" ] }, { "cell_type": "markdown", "id": "1141b026", "metadata": {}, "source": [ "The following example shows how to create a graph object with [igraph](https://igraph.org) and add node sizes and edge sizes coming from [node betweenness](https://igraph.org/python/api/latest/igraph._igraph.GraphBase.html#betweenness) and [edge betweenness](https://igraph.org/python/api/latest/igraph._igraph.GraphBase.html#edge_betweenness) calculation." ] }, { "cell_type": "code", "execution_count": null, "id": "0907f2b4", "metadata": {}, "outputs": [], "source": [ "import igraph as ig\n", "\n", "graph3 = ig.Graph.Lattice(dim=[5, 5, 2], circular=False)\n", "\n", "# Betweenness calculation\n", "node_betweenness = graph3.betweenness()\n", "edge_betweenness = graph3.edge_betweenness()\n", "\n", "# Assignment of node and edge sizes\n", "graph3.vs['size'] = [val / 5.0 for val in node_betweenness]\n", "graph3.es['size'] = edge_betweenness" ] }, { "cell_type": "markdown", "id": "78c33b6e", "metadata": {}, "source": [ "## Plot a graph\n", "\n", "A graph visualization can be embedded inside an output cell of a Jupyter notebook." ] }, { "cell_type": "code", "execution_count": null, "id": "1642ebf9", "metadata": { "scrolled": false }, "outputs": [], "source": [ "gv.vis(graph1, show_node_label=False, show_edge_label=True, edge_label_data_source='en')" ] }, { "cell_type": "code", "execution_count": null, "id": "6ec3e616", "metadata": {}, "outputs": [], "source": [ "gv.d3(graph2, use_node_size_normalization=True, node_size_normalization_max=30,\n", " use_edge_size_normalization=True, edge_size_data_source='weight', edge_curvature=0.3)" ] }, { "cell_type": "code", "execution_count": null, "id": "cbf4e1d9", "metadata": {}, "outputs": [], "source": [ "gv.three(graph3, use_edge_size_normalization=True)" ] }, { "cell_type": "markdown", "id": "de563de6", "metadata": {}, "source": [ "A graph visualization can also be displayed in a new browser window or tab." ] }, { "cell_type": "code", "execution_count": null, "id": "bdf1d54b", "metadata": {}, "outputs": [], "source": [ "fig = gv.vis(graph1, show_node_label=False, show_edge_label=True, edge_label_data_source='en')\n", "fig.display()" ] }, { "cell_type": "markdown", "id": "f04f7ab4", "metadata": {}, "source": [ "## Export a graph" ] }, { "cell_type": "markdown", "id": "6bbec8bb", "metadata": {}, "source": [ "### 1) As HTML file\n", "\n", "A graph visualization can be exported as standalone HTML file." ] }, { "cell_type": "code", "execution_count": null, "id": "2dae8127", "metadata": {}, "outputs": [], "source": [ "fig = gv.d3(graph2, use_node_size_normalization=True, node_size_normalization_max=30,\n", " use_edge_size_normalization=True, edge_size_data_source='weight', edge_curvature=0.3,\n", " zoom_factor=0.6)\n", "fig.export_html('graph2.html')" ] }, { "cell_type": "markdown", "id": "5d620f1a", "metadata": {}, "source": [ "### 2) As PNG, JPG or SVG file with static plot\n", "\n", "A graph visualization can be exported as static image in JPG, PNG or SVG format. Behind the scences, this is achieved by creating a HTML visualization, opening it in a headless browser with [Selenium](https://selenium-python.readthedocs.io/) and capturing a picture with the same JPG, PNG or SVG button that a user can click when viewing a HTML visualization. As such it takes a few seconds and requires some optional dependencies to be installed (Selenium, webbrowser and webdriver)." ] }, { "cell_type": "code", "execution_count": null, "id": "fed9fdde", "metadata": {}, "outputs": [], "source": [ "fig.export_jpg('graph2.jpg')" ] }, { "cell_type": "code", "execution_count": null, "id": "9c0dca48", "metadata": {}, "outputs": [], "source": [ "fig.export_png('graph2.png')" ] }, { "cell_type": "code", "execution_count": null, "id": "928f518e", "metadata": {}, "outputs": [], "source": [ "fig.export_svg('graph2.svg')" ] }, { "cell_type": "markdown", "id": "b508a13a", "metadata": {}, "source": [ "A Jupyter notebook can also display images in JPG, PNG or SVG format directly in output cells." ] }, { "cell_type": "code", "execution_count": null, "id": "08606d8d", "metadata": {}, "outputs": [], "source": [ "import IPython\n", "\n", "svg_text = fig.to_svg()\n", "IPython.display.SVG(svg_text)" ] }, { "cell_type": "code", "execution_count": null, "id": "a80cf9d6", "metadata": {}, "outputs": [], "source": [ "jpg_data = fig.to_jpg()\n", "IPython.display.Image(jpg_data)" ] }, { "cell_type": "code", "execution_count": null, "id": "1f00dfc8", "metadata": {}, "outputs": [], "source": [ "png_data = fig.to_png()\n", "IPython.display.Image(png_data)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.7.12" } }, "nbformat": 4, "nbformat_minor": 5 }