{ "cells": [ { "cell_type": "markdown", "id": "a6b3d201", "metadata": {}, "source": [ "# gJGF\n", "\n", "This Jupyter notebook provides an example of using the Python package [gravis](https://pypi.org/project/gravis) and its custom format called [gravis JSON Graph Format (gJGF)](../../rst/format_specification.html). The .ipynb file can be found [here](https://github.com/robert-haas/gravis/tree/master/examples)." ] }, { "cell_type": "code", "execution_count": null, "id": "ac99a969", "metadata": {}, "outputs": [], "source": [ "import gravis as gv" ] }, { "cell_type": "markdown", "id": "f837fd5c", "metadata": {}, "source": [ "## Empty graph" ] }, { "cell_type": "code", "execution_count": null, "id": "28175f45", "metadata": {}, "outputs": [], "source": [ "graph1 = {\n", " 'graph': {}\n", "}\n", "\n", "gv.d3(graph1, graph_height=150)" ] }, { "cell_type": "markdown", "id": "ae172fa5", "metadata": {}, "source": [ "## Directed graph\n", "\n", "Reproduced from [Wikipedia: Directed graph](https://en.wikipedia.org/wiki/Directed_graph)" ] }, { "cell_type": "code", "execution_count": null, "id": "49824542", "metadata": {}, "outputs": [], "source": [ "graph2 = {\n", " 'graph': {\n", " 'label': 'Directed graph',\n", " 'nodes': {\n", " 'a': {},\n", " 'b': {},\n", " 'c': {},\n", " },\n", " 'edges': [\n", " {'source': 'a', 'target': 'b'},\n", " {'source': 'b', 'target': 'c'},\n", " {'source': 'c', 'target': 'a'},\n", " ],\n", " 'metadata': {\n", " 'node_color': '#007fff',\n", " 'node_border_size': 1.5,\n", " 'node_size': 16,\n", " }\n", " }\n", "}\n", "\n", "gv.d3(graph2, graph_height=150, show_node_label=False)" ] }, { "cell_type": "markdown", "id": "1f283f52", "metadata": {}, "source": [ "## Undirected graph\n", "\n", "Reproduced from [Wikipedia: Graph](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics))" ] }, { "cell_type": "code", "execution_count": null, "id": "c2485856", "metadata": {}, "outputs": [], "source": [ "graph3 = {\n", " 'graph': {\n", " 'label': 'Undirected graph',\n", " 'directed': False,\n", " 'nodes': {\n", " 1: {},\n", " 2: {},\n", " 3: {},\n", " 4: {},\n", " 5: {},\n", " 6: {},\n", " },\n", " 'edges': [\n", " {'source': 1, 'target': 2},\n", " {'source': 1, 'target': 5},\n", " {'source': 2, 'target': 5},\n", " {'source': 2, 'target': 3},\n", " {'source': 3, 'target': 4},\n", " {'source': 4, 'target': 5},\n", " {'source': 4, 'target': 6},\n", " ],\n", " 'metadata': {\n", " 'node_color': 'white',\n", " 'node_size': 30,\n", " 'node_border_size': 2,\n", " 'node_label_size': 20\n", " }\n", " }\n", "}\n", "\n", "gv.d3(graph3, graph_height=200)" ] }, { "cell_type": "markdown", "id": "fcc0a31e", "metadata": {}, "source": [ "## Multigraph\n", "\n", "A multigraph with multiedges in red and self-loops in blue, reproduced from [Wikipedia: Multigraph](https://en.wikipedia.org/wiki/Multigraph)" ] }, { "cell_type": "code", "execution_count": null, "id": "d0ee0c1e", "metadata": {}, "outputs": [], "source": [ "graph4 = {\n", " 'graph': {\n", " 'label': 'Multigraph',\n", " 'directed': False,\n", " 'nodes': {\n", " 1: {'metadata': {'hover': 'Node 1', 'x': 0, 'y': -60}},\n", " 2: {'metadata': {'hover': 'Node 2', 'x': 65, 'y': -20}},\n", " 3: {'metadata': {'hover': 'Node 3', 'x': 40, 'y': 60}},\n", " 4: {'metadata': {'hover': 'Node 4', 'x': -40, 'y': 60}},\n", " 5: {'metadata': {'hover': 'Node 5', 'x': -65, 'y': -20}},\n", " 6: {'metadata': {'hover': 'Node 6', 'x': 0, 'y': 5}},\n", " },\n", " 'edges': [\n", " {'source': 1, 'target': 2},\n", " {'source': 2, 'target': 3},\n", " {'source': 2, 'target': 2, 'metadata': {'color': 'blue'}},\n", " {'source': 3, 'target': 4},\n", " {'source': 3, 'target': 3, 'metadata': {'color': 'blue'}},\n", " {'source': 4, 'target': 5},\n", " {'source': 4, 'target': 4, 'metadata': {'color': 'blue'}},\n", " {'source': 5, 'target': 1, 'metadata': {'color': 'red'}},\n", " {'source': 5, 'target': 1, 'metadata': {'color': 'red'}},\n", " {'source': 1, 'target': 6, 'metadata': {'color': 'red'}},\n", " {'source': 1, 'target': 6, 'metadata': {'color': 'red'}},\n", " {'source': 6, 'target': 1, 'metadata': {'color': 'red'}},\n", " {'source': 2, 'target': 6},\n", " {'source': 3, 'target': 6, 'metadata': {'color': 'red'}},\n", " {'source': 6, 'target': 3, 'metadata': {'color': 'red'}},\n", " {'source': 4, 'target': 6, 'metadata': {'color': 'red'}},\n", " {'source': 6, 'target': 4, 'metadata': {'color': 'red'}},\n", " {'source': 5, 'target': 6},\n", " ],\n", " 'metadata': {'node_color': '#aaa', 'node_border_size': 1.2, 'edge_size': 1.2}\n", " }\n", "}\n", "\n", "gv.d3(graph4, graph_height=200, edge_curvature=0.3, show_node_label=False)" ] }, { "cell_type": "markdown", "id": "297a415f", "metadata": {}, "source": [ "## Annotated graph\n", "\n", "- Enzyme image [Protein ADH5 PDB 1m6h.png](https://commons.wikimedia.org/wiki/File:Protein_ADH5_PDB_1m6h.png) with [CC BY 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/) from [Wikipedia: Alcoholdehydrogenase](https://en.wikipedia.org/wiki/Alcohol_dehydrogenase)\n", "- Molecule images with [CC BY 4.0 license](https://creativecommons.org/licenses/by/4.0/) from [RHEA:25290](https://www.rhea-db.org/rhea/25290)\n", " \n", " - Bansal et al., Rhea, the reaction knowledgebase in 2022. Nucleic Acids Res. Epub:gkab1016 (2021). [PMID:34755880](https://pubmed.ncbi.nlm.nih.gov/34755880/), [DOI:10.1093/nar/gkab1016](https://doi.org/10.1093/nar/gkab1016)" ] }, { "cell_type": "code", "execution_count": null, "id": "36781563", "metadata": {}, "outputs": [], "source": [ "img_alcoholdehydrogenase = gv.convert.image_to_data_url(\n", " 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Protein_ADH5_PDB_1m6h.png/320px-Protein_ADH5_PDB_1m6h.png')\n", "img_ethanol = gv.convert.image_to_data_url(\n", " 'https://www.rhea-db.org/chebi/CHEBI:16236', 'svg')\n", "img_nad = gv.convert.image_to_data_url(\n", " 'https://www.rhea-db.org/chebi/CHEBI:57540', 'svg')\n", "img_acetaldehyde = gv.convert.image_to_data_url(\n", " 'https://www.rhea-db.org/chebi/CHEBI:15343', 'svg')\n", "img_proton = gv.convert.image_to_data_url(\n", " 'https://www.rhea-db.org/chebi/CHEBI:15378', 'svg')\n", "img_nadh = gv.convert.image_to_data_url(\n", " 'https://www.rhea-db.org/chebi/CHEBI:57945', 'svg')\n", "\n", "default_color = 'black'\n", "highlight_color = 'blue'\n", "highlight_size = 1.5\n", "background_color = '#f5f5f5'\n", "\n", "graph5 = {\n", " 'graph': {\n", " 'label': 'Annotated graph',\n", " 'directed': True,\n", " 'metadata': {\n", " 'arrow_color': 'black',\n", " 'arrow_size': 5,\n", " 'background_color': background_color,\n", " 'node_color': background_color,\n", " 'node_opacity': 0.8,\n", " 'node_size': 25,\n", " 'node_shape': 'hexagon',\n", " 'node_border_color': default_color,\n", " 'node_border_size': 0.8,\n", " 'node_label_color': default_color,\n", " 'node_label_size': 6,\n", " 'node_hover': 'Molecule: $label',\n", " 'node_click': '$hover',\n", " 'node_x': 0,\n", " 'node_y': 0,\n", " 'node_z': 0,\n", " 'edge_color': default_color,\n", " 'edge_opacity': 0.8,\n", " 'edge_size': 1,\n", " 'edge_label_color': 'black',\n", " 'edge_label_size': 5,\n", " 'edge_hover': '$label',\n", " 'edge_click': '$label',\n", " },\n", " 'nodes': {\n", " 1: {\n", " 'label': 'Alcohol dehydrogenase',\n", " 'metadata': {\n", " 'color': 'white',\n", " 'opacity': 1.0,\n", " 'size': 50,\n", " 'shape': 'circle',\n", " 'border_color': highlight_color,\n", " 'border_size': highlight_size,\n", " 'label_color': highlight_color,\n", " 'label_size': 7,\n", " 'hover': 'Enzyme: $label',\n", " 'click': '$hover',\n", " 'image': img_alcoholdehydrogenase,\n", " }\n", " },\n", " 2: {\n", " 'label': 'Ethanol',\n", " 'metadata': {\n", " 'size': 30,\n", " 'color': 'white',\n", " 'shape': 'rectangle',\n", " 'border_color': highlight_color,\n", " 'border_size': highlight_size,\n", " 'label_color': highlight_color,\n", " 'image': img_ethanol,\n", " 'x': -100,\n", " 'y': 50,\n", " }\n", " },\n", " 3: {\n", " 'label': 'NAD+',\n", " 'metadata': {\n", " 'image': img_nad,\n", " 'x': -100,\n", " 'y': 0,\n", " }\n", " },\n", " 4: {\n", " 'label': 'Acetaldehyde',\n", " 'metadata': {\n", " 'size': 30,\n", " 'color': 'white',\n", " 'shape': 'rectangle',\n", " 'border_color': highlight_color,\n", " 'border_size': highlight_size,\n", " 'label_color': highlight_color,\n", " 'image': img_acetaldehyde,\n", " 'x': 100,\n", " 'y': 50,\n", " }\n", " },\n", " 5: {\n", " 'label': 'NADH',\n", " 'metadata': {\n", " 'image': img_nadh,\n", " 'x': 100,\n", " 'y': 0,\n", " }\n", " },\n", " 6: {\n", " 'label': 'Proton',\n", " 'metadata': {\n", " 'image': img_proton,\n", " 'x': 100,\n", " 'y': -50,\n", " }\n", " },\n", " },\n", " 'edges': [\n", " {\n", " 'source': 2,\n", " 'target': 1,\n", " 'label': '1 mol',\n", " 'metadata': {\n", " 'color': highlight_color,\n", " 'opacity': 1.0,\n", " 'size': highlight_size,\n", " 'label_color': highlight_color,\n", " 'label_size': 6,\n", " },\n", " },\n", " {\n", " 'source': 3,\n", " 'target': 1,\n", " 'label': '1 mol',\n", " },\n", " {\n", " 'source': 1,\n", " 'target': 4,\n", " 'label': '1 mol',\n", " 'metadata': {\n", " 'color': highlight_color,\n", " 'size': highlight_size,\n", " 'label_color': highlight_color,\n", " 'label_size': 6,\n", " },\n", " },\n", " {\n", " 'source': 1,\n", " 'target': 5,\n", " 'label': '1 mol',\n", " },\n", " {\n", " 'source': 1,\n", " 'target': 6,\n", " 'label': '1 mol',\n", " },\n", " ],\n", " }\n", "}\n", "\n", "gv.d3(graph5, node_label_data_source='label', edge_label_data_source='label', show_edge_label=True, zoom_factor=2)" ] }, { "cell_type": "markdown", "id": "db13c5bd", "metadata": {}, "source": [ "## Multiple graphs\n", "\n", "gJGF can also be used to define multiple graphs in one dictionary (or JSON object). The visualization shows the first graph, while the other graphs can be selected in the menu on the right side in the category `Data selection`." ] }, { "cell_type": "code", "execution_count": null, "id": "d324ff1b", "metadata": {}, "outputs": [], "source": [ "graphs = {\n", " 'graphs': [\n", " {\n", " 'label': 'First graph',\n", " 'nodes': {\n", " 'a': {},\n", " 'b': {},\n", " },\n", " 'edges': [\n", " {'source': 'a', 'target': 'b'},\n", " ],\n", " },\n", " {\n", " 'label': 'Second graph',\n", " 'directed': False,\n", " 'nodes': {\n", " 1: {},\n", " 2: {},\n", " },\n", " 'edges': [\n", " {'source': 1, 'target': 2},\n", " ],\n", " },\n", " ]\n", "}\n", "\n", "gv.d3(graphs, graph_height=200)" ] }, { "cell_type": "code", "execution_count": null, "id": "c96544c6", "metadata": {}, "outputs": [], "source": [ "# reuse previous graphs: remove the \"graph\" key from each one, instead add a \"graphs\" key for the collection\n", "graphs = [graph2, graph3, graph4, graph5]\n", "gjgf = {'graphs': [g['graph'] for g in graphs]}\n", "\n", "gv.d3(gjgf, graph_height=200)" ] } ], "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 }