From 0be87658edfb090d5bb90cd99f78322c53689c29 Mon Sep 17 00:00:00 2001 From: "ryan.danehy@pnnl.gov" Date: Tue, 25 Feb 2025 15:36:11 -0800 Subject: [PATCH 1/3] add widget --- tutorials/widget/Demo 1 - HNXWidget.ipynb | 850 ++++++++++++++++++++++ tutorials/widget/README.md | 31 + 2 files changed, 881 insertions(+) create mode 100755 tutorials/widget/Demo 1 - HNXWidget.ipynb create mode 100644 tutorials/widget/README.md diff --git a/tutorials/widget/Demo 1 - HNXWidget.ipynb b/tutorials/widget/Demo 1 - HNXWidget.ipynb new file mode 100755 index 00000000..dfbed6c6 --- /dev/null +++ b/tutorials/widget/Demo 1 - HNXWidget.ipynb @@ -0,0 +1,850 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install hypernetx ## uncomment to run in Colab\n", + "# !pip install hnxwidget" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# HyperNetX Widgets\n", + "\n", + "Unlike the tutorials, this is an interactive demo to get you acquainted with the constructor options and how to use the widget. **Hover over the nodes and edges each time you run the widget to see how properties enhance the visual information.**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:14.006519Z", + "start_time": "2024-05-16T22:23:11.953762Z" + } + }, + "outputs": [], + "source": [ + "import hypernetx as hnx\n", + "from hypernetx.utils.toys.lesmis import LesMis\n", + "from hnxwidget import HypernetxWidget\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:14.281368Z", + "start_time": "2024-05-16T22:23:14.007410Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/miniconda3/envs/hnx2/lib/python3.10/site-packages/pandas/core/dtypes/cast.py:1641: DeprecationWarning: np.find_common_type is deprecated. Please use `np.result_type` or `np.promote_types`.\n", + "See https://numpy.org/devdocs/release/1.25.0-notes.html and the docs for more information. (Deprecated NumPy 1.25)\n", + " return np.find_common_type(types, [])\n" + ] + }, + { + "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", + " \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", + "
FullNameDescription
Symbol
AZAnzelmadaughter of TH and TM
BABahorel`Friends of the ABC' cutup
BBBabettooth-pulling bandit of Paris
BJBrujonnotorious criminal
BLBlachevilleParisian student from Montauban
.........
TSToussaintservant of JV at Rue Plumet
VIMadame Victurniensnoop in M-- sur M--
XAChild 1son of TH sold to MN
XBChild 2son of TH sold to MN
ZEZephinelover of FA
\n", + "

80 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " FullName Description\n", + "Symbol \n", + "AZ Anzelma daughter of TH and TM\n", + "BA Bahorel `Friends of the ABC' cutup\n", + "BB Babet tooth-pulling bandit of Paris\n", + "BJ Brujon notorious criminal\n", + "BL Blacheville Parisian student from Montauban\n", + "... ... ...\n", + "TS Toussaint servant of JV at Rue Plumet\n", + "VI Madame Victurnien snoop in M-- sur M--\n", + "XA Child 1 son of TH sold to MN\n", + "XB Child 2 son of TH sold to MN\n", + "ZE Zephine lover of FA\n", + "\n", + "[80 rows x 2 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scenes = {\n", + " 0: ('FN', 'TH'),\n", + " 1: ('TH', 'JV'),\n", + " 2: ('BM', 'FN', 'JA'),\n", + " 3: ('JV', 'JU', 'CH', 'BM'),\n", + " 4: ('JU', 'CH', 'BR', 'CN', 'CC', 'JV', 'BM'),\n", + " 5: ('TH', 'GP'),\n", + " 6: ('GP', 'MP'),\n", + " 7: ('MA', 'GP'),\n", + "}\n", + "H = hnx.Hypergraph(scenes)\n", + "dnames = LesMis().dnames\n", + "dnames" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## I. LesMis Hypergraph in the Hypernetx-Widget - Default Behavior\n", + "The widget allows you to interactively move, color, select, and hide objects in the hypergraph. Click on the question mark in the Navigation menu for a description of interactive features." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:15.130555Z", + "start_time": "2024-05-16T22:23:15.104677Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/miniconda3/envs/hnx2/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:438: DeprecationWarning: The `ipykernel.comm.Comm` class has been deprecated. Please use the `comm` module instead.For creating comms, use the function `from comm import create_comm`.\n", + " self.comm = Comm(**args)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "93965671121b4f67aaeea3c2616913b9", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HypernetxWidget(component='HypernetxWidget', props={'nodes': [{'uid': 'TH'}, {'uid': 'MP'}, {'uid': 'FN'}, {'u…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "## Default behavior\n", + "example1 = HypernetxWidget(H)\n", + "example1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## II. Preset attributes \n", + "Some of the visualization attributes of the hypergraph may be set using similar parameters as the hnx.draw function" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:16.132733Z", + "start_time": "2024-05-16T22:23:16.120716Z" + } + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6c4f2b96019d4ac0be5146d8f00e346f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HypernetxWidget(component='HypernetxWidget', props={'nodes': [{'uid': 'TH'}, {'uid': 'MP'}, {'uid': 'FN'}, {'u…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "node_colors = {k:'r' if k in ['JV','TH','FN'] else 'b' for k in H.nodes}\n", + "example2 = HypernetxWidget(\n", + " H,\n", + " nodes_kwargs={'color':node_colors},\n", + " edges_kwargs={'edgecolors':'g'}\n", + ")\n", + "example2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## III. Attributes of visualization:\n", + "The `get_state()` method returns the attributes available from a widget for reuse.\n", + "\n", + "**Note:** if you \"Run All\" this notebook, the following cells may produce an exception. Acquiring the widget state in python requires some time for the widget to initialize and render. Run the cells below individually for best results." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:17.245676Z", + "start_time": "2024-05-16T22:23:17.232292Z" + }, + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'_dom_classes': (),\n", + " '_model_module': 'hnxwidget',\n", + " '_model_module_version': '^0.1.0',\n", + " '_model_name': 'ExampleModel',\n", + " '_view_count': None,\n", + " '_view_module': 'hnxwidget',\n", + " '_view_module_version': '^0.1.0',\n", + " '_view_name': 'ExampleView',\n", + " 'component': 'HypernetxWidget',\n", + " 'edge_stroke': {},\n", + " 'hidden_edges': {},\n", + " 'hidden_nodes': {},\n", + " 'layout': 'IPY_MODEL_bc96ccb610dc44d2ba6798d9f8f91771',\n", + " 'node_fill': {},\n", + " 'pos': {},\n", + " 'props': {'nodes': [{'uid': 'TH'},\n", + " {'uid': 'MP'},\n", + " {'uid': 'FN'},\n", + " {'uid': 'CN'},\n", + " {'uid': 'MA'},\n", + " {'uid': 'BM'},\n", + " {'uid': 'BR'},\n", + " {'uid': 'CC'},\n", + " {'uid': 'JU'},\n", + " {'uid': 'JV'},\n", + " {'uid': 'GP'},\n", + " {'uid': 'CH'},\n", + " {'uid': 'JA'}],\n", + " 'edges': [{'uid': '0', 'elements': ['FN', 'TH']},\n", + " {'uid': '1', 'elements': ['TH', 'JV']},\n", + " {'uid': '2', 'elements': ['BM', 'FN', 'JA']},\n", + " {'uid': '3', 'elements': ['JV', 'JU', 'CH', 'BM']},\n", + " {'uid': '4', 'elements': ['JU', 'CH', 'BR', 'CN', 'CC', 'JV', 'BM']},\n", + " {'uid': '5', 'elements': ['TH', 'GP']},\n", + " {'uid': '6', 'elements': ['GP', 'MP']},\n", + " {'uid': '7', 'elements': ['MA', 'GP']}],\n", + " 'nodeFill': {'TH': '#ff0000ff',\n", + " 'MP': '#0000ffff',\n", + " 'FN': '#ff0000ff',\n", + " 'CN': '#0000ffff',\n", + " 'MA': '#0000ffff',\n", + " 'BM': '#0000ffff',\n", + " 'BR': '#0000ffff',\n", + " 'CC': '#0000ffff',\n", + " 'JU': '#0000ffff',\n", + " 'JV': '#ff0000ff',\n", + " 'GP': '#0000ffff',\n", + " 'CH': '#0000ffff',\n", + " 'JA': '#0000ffff'},\n", + " 'edgeStroke': {0: '#008000ff',\n", + " 1: '#008000ff',\n", + " 2: '#008000ff',\n", + " 3: '#008000ff',\n", + " 4: '#008000ff',\n", + " 5: '#008000ff',\n", + " 6: '#008000ff',\n", + " 7: '#008000ff'},\n", + " 'edgeStrokeWidth': {0: 2, 1: 2, 2: 2, 3: 2, 4: 2, 5: 2, 6: 2, 7: 2},\n", + " 'edgeLabelColor': {0: '#008000ff',\n", + " 1: '#008000ff',\n", + " 2: '#008000ff',\n", + " 3: '#008000ff',\n", + " 4: '#008000ff',\n", + " 5: '#008000ff',\n", + " 6: '#008000ff',\n", + " 7: '#008000ff'}},\n", + " 'removed_edges': {},\n", + " 'removed_nodes': {},\n", + " 'selected_edges': {},\n", + " 'selected_nodes': {}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "example2.get_state()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## IV. Reuse attributes\n", + "Once an attribute of a widget visualization has been set it may be reused in another visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:18.370346Z", + "start_time": "2024-05-16T22:23:18.359473Z" + } + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7599ffb13290423491a500ef2bf49043", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HypernetxWidget(component='HypernetxWidget', props={'nodes': [{'uid': 'TH'}, {'uid': 'MP'}, {'uid': 'FN'}, {'u…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "## \n", + "example3 = HypernetxWidget(\n", + " H,\n", + " nodes_kwargs={'color': example2.props[\"nodeFill\"]}\n", + ")\n", + "\n", + "example3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## V. Setting Labels and Callouts\n", + "We can also adjust specific labels and add call outs as node or edge data." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:19.486436Z", + "start_time": "2024-05-16T22:23:19.468323Z" + }, + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9809de9d953d49b28ac84b68319a2aef", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HypernetxWidget(component='HypernetxWidget', props={'nodes': [{'uid': 'TH'}, {'uid': 'MP'}, {'uid': 'FN'}, {'u…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "example4 = HypernetxWidget(\n", + " H,\n", + " collapse_nodes=True,\n", + " node_data=dnames,\n", + " node_labels={'JV': 'Valjean'},\n", + " edge_labels={0: 'scene 0'},\n", + " nodes_kwargs={'color':'pink'},\n", + ")\n", + "\n", + "example4" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using Hypergraph's metadata" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:20.554709Z", + "start_time": "2024-05-16T22:23:20.528041Z" + } + }, + "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", + " \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", + " \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", + " \n", + "
weightFullNameDescriptionmisc_properties
uid
FN1Fantinelover of FT{}
TH1Th\\'enardiersergeant of Waterloo and keeper of a chophouse{}
JV1Jean Valjeanthief of bread{}
BM1Monsieur Bamataboisidler of M-- sur M--{}
JA1Javertpolice officer of M-- sur M--{}
JU1Judge of Douaijudge at the court trying CH{}
CH1Champmathieuaccused thief mistaken for JV{}
BR1Brevetconvict in the galleys with JV{}
CN1Chenildieuconvict in the galleys with JV{}
CC1Cochepailleconvict in the galleys with JV{}
GP1George Pontmercyfather of MA and son-in-law of GI{}
MP1Madame Pontmercyyounger daughter of GI{}
MA1Mariusgrandson of GI{}
\n", + "
" + ], + "text/plain": [ + " weight FullName \\\n", + "uid \n", + "FN 1 Fantine \n", + "TH 1 Th\\'enardier \n", + "JV 1 Jean Valjean \n", + "BM 1 Monsieur Bamatabois \n", + "JA 1 Javert \n", + "JU 1 Judge of Douai \n", + "CH 1 Champmathieu \n", + "BR 1 Brevet \n", + "CN 1 Chenildieu \n", + "CC 1 Cochepaille \n", + "GP 1 George Pontmercy \n", + "MP 1 Madame Pontmercy \n", + "MA 1 Marius \n", + "\n", + " Description misc_properties \n", + "uid \n", + "FN lover of FT {} \n", + "TH sergeant of Waterloo and keeper of a chophouse {} \n", + "JV thief of bread {} \n", + "BM idler of M-- sur M-- {} \n", + "JA police officer of M-- sur M-- {} \n", + "JU judge at the court trying CH {} \n", + "CH accused thief mistaken for JV {} \n", + "BR convict in the galleys with JV {} \n", + "CN convict in the galleys with JV {} \n", + "CC convict in the galleys with JV {} \n", + "GP father of MA and son-in-law of GI {} \n", + "MP younger daughter of GI {} \n", + "MA grandson of GI {} " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_properties = dnames.reset_index()\n", + "H2 = hnx.Hypergraph(H.dataframe, node_properties=node_properties)\n", + "\n", + "H2.nodes.dataframe" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:21.109029Z", + "start_time": "2024-05-16T22:23:21.086440Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " weight FullName \\\n", + "uid \n", + "FN 1 Fantine \n", + "TH 1 Th\\'enardier \n", + "JV 1 Jean Valjean \n", + "BM 1 Monsieur Bamatabois \n", + "JA 1 Javert \n", + "JU 1 Judge of Douai \n", + "CH 1 Champmathieu \n", + "BR 1 Brevet \n", + "CN 1 Chenildieu \n", + "CC 1 Cochepaille \n", + "GP 1 George Pontmercy \n", + "MP 1 Madame Pontmercy \n", + "MA 1 Marius \n", + "\n", + " Description degree misc_properties \n", + "uid \n", + "FN lover of FT 2 {} \n", + "TH sergeant of Waterloo and keeper of a chophouse 3 {} \n", + "JV thief of bread 3 {} \n", + "BM idler of M-- sur M-- 3 {} \n", + "JA police officer of M-- sur M-- 1 {} \n", + "JU judge at the court trying CH 2 {} \n", + "CH accused thief mistaken for JV 2 {} \n", + "BR convict in the galleys with JV 1 {} \n", + "CN convict in the galleys with JV 1 {} \n", + "CC convict in the galleys with JV 1 {} \n", + "GP father of MA and son-in-law of GI 3 {} \n", + "MP younger daughter of GI 1 {} \n", + "MA grandson of GI 1 {} \n", + "\n", + " weight size misc_properties\n", + "uid \n", + "0 1 2 {}\n", + "1 1 2 {}\n", + "2 1 3 {}\n", + "3 1 4 {}\n", + "4 1 7 {}\n", + "5 1 2 {}\n", + "6 1 2 {}\n", + "7 1 2 {}\n" + ] + } + ], + "source": [ + "## to add an additional property column to nodes and edges, first set a default value, then change the \n", + "## value for individual objects:\n", + "\n", + "H2.nodes.set_defaults({'degree':0})\n", + "for nd in H2.nodes:\n", + " H2.nodes[nd].degree = H2.degree(nd)\n", + " \n", + "H2.edges.set_defaults({'size':0})\n", + "for ed in H2.edges:\n", + " H2.edges[ed].size = H2.size(ed)\n", + " \n", + "print(H2.nodes.dataframe)\n", + "print()\n", + "print(H2.edges.dataframe)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-16T22:23:21.748473Z", + "start_time": "2024-05-16T22:23:21.723634Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/miniconda3/envs/hnx2/lib/python3.10/site-packages/pandas/core/dtypes/cast.py:1641: DeprecationWarning: np.find_common_type is deprecated. Please use `np.result_type` or `np.promote_types`.\n", + "See https://numpy.org/devdocs/release/1.25.0-notes.html and the docs for more information. (Deprecated NumPy 1.25)\n", + " return np.find_common_type(types, [])\n", + "/opt/miniconda3/envs/hnx2/lib/python3.10/site-packages/pandas/core/dtypes/cast.py:1641: DeprecationWarning: np.find_common_type is deprecated. Please use `np.result_type` or `np.promote_types`.\n", + "See https://numpy.org/devdocs/release/1.25.0-notes.html and the docs for more information. (Deprecated NumPy 1.25)\n", + " return np.find_common_type(types, [])\n", + "/opt/miniconda3/envs/hnx2/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:438: DeprecationWarning: The `ipykernel.comm.Comm` class has been deprecated. Please use the `comm` module instead.For creating comms, use the function `from comm import create_comm`.\n", + " self.comm = Comm(**args)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "14d3751aad0d4bf48f97e2fd955ef64b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HypernetxWidget(component='HypernetxWidget', props={'nodes': [{'uid': 'TH'}, {'uid': 'MP'}, {'uid': 'FN'}, {'u…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "### All of the data in the property dataframes may be used in the widget except for the misc_properties\n", + "### Hover over nodes and edges to see the data associated with the object\n", + "\n", + "node_colors = {nd: plt.cm.Set1(H2.nodes[nd].degree) for nd in H2.nodes}\n", + "edge_colors = {ed: plt.cm.Set1(H2.edges[ed].size) for ed in H2.edges}\n", + "\n", + "example5 = HypernetxWidget(\n", + " H2,\n", + " collapse_nodes=True,\n", + " node_data=H2.nodes.dataframe[['weight', 'FullName', 'Description', 'degree']],\n", + " edge_data=H2.edges.dataframe[['weight','size']],\n", + " node_labels={'JV': 'Valjean'},\n", + " edge_labels={0: 'scene 0'},\n", + " nodes_kwargs={'color':node_colors},\n", + " edges_kwargs={'edgecolors':edge_colors}\n", + ")\n", + "example5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.10.14" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/widget/README.md b/tutorials/widget/README.md new file mode 100644 index 00000000..2364a4f1 --- /dev/null +++ b/tutorials/widget/README.md @@ -0,0 +1,31 @@ +# Overview + +These tutorials demonstrate how to use [hnxwidget](https://pypi.org/project/hnxwidget/), an interactive visualization tool +of HyperNetX. + +# How to run the tutorials on Jupyter Notebook + +Create a virtual environment: + +`make venv` + + +Activate the environment: + +`source venv-hnx/bin/activate` + + +Navigate to the root of this repository. Install the required dependencies in order to run the Jupyter Notebooks: + +`make tutorials-deps` + +Once the dependencies have been installed, run the notebooks: + +`make tutorials` + +This command will open up the notebooks on a browser at the following URL: http://localhost:8888/tree + +Below is a screenshot of what to expect to see on the browser. Click a folder and open the desired +tutorial on your browser: + +![](../images/jupyter_notebook_screenshot.png) From 400f6f60d658d4fceba1c207285771e1e4fe3ed9 Mon Sep 17 00:00:00 2001 From: "ryan.danehy@pnnl.gov" Date: Tue, 25 Feb 2025 15:36:46 -0800 Subject: [PATCH 2/3] fix pre-commit --- hypernetx/drawing/util.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hypernetx/drawing/util.py b/hypernetx/drawing/util.py index 773d35ae..ddd5b8b3 100644 --- a/hypernetx/drawing/util.py +++ b/hypernetx/drawing/util.py @@ -194,6 +194,7 @@ def get_set_layering(H, collapse=True): return levels + def layout_with_radius(B, node_and_edge_radius=1, **kwargs): """ Convenience function allowing the user to specify ideal radii for nodes and edges in the drawing @@ -217,17 +218,16 @@ def layout_with_radius(B, node_and_edge_radius=1, **kwargs): dict mapping of node and edge positions to R^2 """ - + # get radii encodings and convert to dictionary radius_dict = dict(zip(B, inflate(B, node_and_edge_radius))) - + # edges weights are the sum of the radii of the edge endpoints for u, v, d in B.edges(data=True): - d['weight'] = radius_dict.get(u, 0) + radius_dict.get(v, 0) - + d["weight"] = radius_dict.get(u, 0) + radius_dict.get(v, 0) + # compute all pairs shortest path (APSP) dist = dict(nx.all_pairs_dijkstra_path_length(B)) # compute and return layout using above APSP; pass through arguments return nx.kamada_kawai_layout(B, dist=dist, **kwargs) - From 7e915833cb189db49f86ef4654ce19f2331f0216 Mon Sep 17 00:00:00 2001 From: "ryan.danehy@pnnl.gov" Date: Tue, 25 Feb 2025 15:53:45 -0800 Subject: [PATCH 3/3] =?UTF-8?q?bump:=20version=202.3.13=20=E2=86=92=202.4.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cz.toml | 2 +- docs/source/conf.py | 2 +- hypernetx/__init__.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.cz.toml b/.cz.toml index fb7ab019..90143cff 100644 --- a/.cz.toml +++ b/.cz.toml @@ -1,6 +1,6 @@ [tool.commitizen] name = "cz_conventional_commits" -version = "2.3.13" +version = "2.4.0" version_provider = "poetry" version_files = [ "pyproject.toml", diff --git a/docs/source/conf.py b/docs/source/conf.py index 3ba66e7a..636a9614 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ import os -__version__ = "2.3.13" +__version__ = "2.4.0" # If extensions (or modules to document with autodoc) are in another directory, diff --git a/hypernetx/__init__.py b/hypernetx/__init__.py index 06e7ac33..4e5ce9c9 100644 --- a/hypernetx/__init__.py +++ b/hypernetx/__init__.py @@ -11,4 +11,4 @@ from hypernetx.utils import * from hypernetx.utils.toys import * -__version__ = "2.3.13" +__version__ = "2.4.0" diff --git a/pyproject.toml b/pyproject.toml index 3c390e75..2d47e335 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hypernetx" -version = "2.3.13" +version = "2.4.0" description = "HyperNetX is a Python library for the creation and study of hypergraphs." authors = ["Brenda Praggastis ", "Dustin Arendt ", "Sinan Aksoy ", "Emilie Purvine ",