Skip to content

Instantly share code, notes, and snippets.

@jtrive84
Created December 21, 2023 22:32
Show Gist options
  • Select an option

  • Save jtrive84/7f800454d4c75c5e91827479ba33d8f0 to your computer and use it in GitHub Desktop.

Select an option

Save jtrive84/7f800454d4c75c5e91827479ba33d8f0 to your computer and use it in GitHub Desktop.
GraphBLAS demo
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "fb57f564-3640-458a-bf00-6c28e5666c84",
"metadata": {},
"source": [
"# GraphBLAS Demo\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eba5035a-819f-475b-8af3-d859c80fefc0",
"metadata": {},
"outputs": [],
"source": [
"!pip install networkx \n",
"!pip install python-graphblas[default] \n",
"!pip install graphblas-algorithms\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "58021cbf-5ba5-4eb8-a684-53f2dffda9f6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"type(G0): <class 'networkx.classes.graph.Graph'>\n",
"type(G1): <class 'graphblas_algorithms.classes.graph.Graph'>\n",
"\n",
"Number of nodes: 2,500\n",
"Number of edges: 155,707\n",
"\n"
]
}
],
"source": [
"import networkx as nx\n",
"import graphblas as gb\n",
"import graphblas_algorithms as ga\n",
"import matplotlib.pyplot as plt\n",
"\n",
"\n",
"# Create random graph in NetworkX.\n",
"G0 = nx.erdos_renyi_graph(2500, 0.05)\n",
"G1 = ga.Graph.from_networkx(G0)\n",
"\n",
"print(f\"\\ntype(G0): {type(G0)}\")\n",
"print(f\"type(G1): {type(G1)}\\n\")\n",
"print(f\"Number of nodes: {G0.number_of_nodes():,.0f}\")\n",
"print(f\"Number of edges: {G0.number_of_edges():,.0f}\\n\")\n"
]
},
{
"cell_type": "markdown",
"id": "2144009e-f7c7-4445-b25a-5f7130f04300",
"metadata": {},
"source": [
"\n",
"### degree_centrality comparison for NetworkX and GraphBLAS graphs."
]
},
{
"cell_type": "markdown",
"id": "8d26f7ab-e149-4452-b7ee-dc0889f41279",
"metadata": {},
"source": [
"#### 2,500 nodes"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "3370ad87-4a2d-4a80-8fac-dc3d06167fc0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"849 µs ± 128 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"109 µs ± 64.1 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"%timeit -n5 nx.degree_centrality(G0)\n",
"%timeit -n5 ga.degree_centrality(G1)\n"
]
},
{
"cell_type": "markdown",
"id": "eec6735c-d5e9-4f49-a3b5-52286f86b998",
"metadata": {},
"source": [
"<br>\n",
"\n",
"**Speed improvements scale with graph size, so larger graphs will see an even larger speed-up relative to NetworkX.**\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "74f56f1d-3031-4f0b-8672-ef8b4c07f73f",
"metadata": {},
"source": [
"\n",
"#### 5,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9a72ba41-da49-4b5f-a237-eb3a9b7e7779",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.8 ms ± 172 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"121 µs ± 39.3 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0a = nx.erdos_renyi_graph(5000, 0.05)\n",
"G1a = ga.Graph.from_networkx(G0a)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0a)\n",
"%timeit -n5 ga.degree_centrality(G1a)\n",
"\n",
"del G0a, G1a\n"
]
},
{
"cell_type": "markdown",
"id": "43de5a2a-59f2-4327-a272-fbcc6c7e2689",
"metadata": {},
"source": [
"<br>\n",
"\n",
"\n",
"#### 10,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b59422b0-2cbf-4f96-a7ee-d5715d25bd52",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.83 ms ± 404 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"141 µs ± 53.2 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0b = nx.erdos_renyi_graph(10000, 0.05)\n",
"G1b = ga.Graph.from_networkx(G0b)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0b)\n",
"%timeit -n5 ga.degree_centrality(G1b)\n",
"\n",
"del G0b, G1b\n"
]
},
{
"cell_type": "markdown",
"id": "71c79507-c2da-4f92-929c-6be4d5c1d13e",
"metadata": {},
"source": [
"<br>\n",
"\n",
"#### 15,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e6bc76e7-2035-4c4b-b59f-2b54295d627b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6.41 ms ± 765 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"166 µs ± 48.2 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0c = nx.erdos_renyi_graph(15000, 0.05)\n",
"G1c = ga.Graph.from_networkx(G0c)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0c)\n",
"%timeit -n5 ga.degree_centrality(G1c)\n",
"\n",
"del G0c, G1c\n"
]
},
{
"cell_type": "markdown",
"id": "7d6fdb7e-8222-4dfd-aaed-8365a6d3534e",
"metadata": {},
"source": [
"<br>\n",
"\n",
"#### 25,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "25c23b56-55ef-45aa-9387-f87c32fb0b71",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11.3 ms ± 1.43 ms per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"206 µs ± 56.2 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0d = nx.erdos_renyi_graph(25000, 0.05)\n",
"G1d = ga.Graph.from_networkx(G0d)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0d)\n",
"%timeit -n5 ga.degree_centrality(G1d)\n",
"\n",
"del G0d, G1d\n"
]
},
{
"cell_type": "markdown",
"id": "1aa942b0-ca95-4981-854a-b995906fc7ec",
"metadata": {},
"source": [
"\n",
"<br>\n",
"\n",
"\n",
"#### 35,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "55d39f2c-03da-4d4f-8567-6f76bcc907ea",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"24.4 ms ± 309 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"245 µs ± 62.6 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0e = nx.erdos_renyi_graph(35000, 0.05)\n",
"G1e = ga.Graph.from_networkx(G0e)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0e)\n",
"%timeit -n5 ga.degree_centrality(G1e)\n",
"\n",
"del G0e, G1e\n"
]
},
{
"cell_type": "markdown",
"id": "8aa39c01-4def-4c9d-a51d-19a0505cbffc",
"metadata": {},
"source": [
"<br>\n",
"\n",
"#### 50,000 nodes"
]
},
{
"cell_type": "code",
"execution_count": 99,
"id": "1c4e41aa-cb13-4cfb-9423-6df1b465a34f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"38.2 ms ± 460 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"322 µs ± 78.5 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"G0f = nx.erdos_renyi_graph(50000, 0.05)\n",
"G1f = ga.Graph.from_networkx(G0f)\n",
"\n",
"%timeit -n5 nx.degree_centrality(G0f)\n",
"%timeit -n5 ga.degree_centrality(G1f)\n",
"\n",
"del G0f, G1f\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "92f7a004-cd10-4dc6-91aa-4f396634ea68",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 800x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Comparison of NetworkX vs. GraphBLAS.\n",
"\n",
"xx = [2500, 5000, 10000, 15000, 25000, 35000, 50000]\n",
"y0 = [849e-6, 1.8e-3, 3.83e-3, 6.41e-3, 11.3e-3, 24.4e-3, 38.2e-3,] \n",
"y1 = [109e-6, 121e-6, 141e-6, 166e-6, 206e-6, 245e-6, 322e-6,]\n",
"\n",
"color0 = \"#1e5a6e\"\n",
"color1 = \"#E02C70\"\n",
"\n",
"fig, ax = plt.subplots(1, 1, figsize=(8., 5), tight_layout=True)\n",
"ax.set_title(\"Degree Centrality Comparison\", fontsize=10, loc=\"center\", weight=\"bold\") \n",
"ax.plot(xx, y0, color=color0, linewidth=2.5, linestyle=\"-\", label=\"NetworkX\")\n",
"ax.plot(xx, y1, color=color1, linewidth=2.5, linestyle=\"--\", label=\"GraphBLAS\")\n",
"ax.set_xlabel(\"N\", fontsize=10, weight=\"bold\")\n",
"ax.set_ylabel(\"secs.\", fontsize=10, weight=\"normal\")\n",
"ax.set_xticks(xx)\n",
"ax.set_xticklabels([f\"{ii:,.0f}\" for ii in xx])\n",
"ax.tick_params(axis=\"x\", which=\"major\", direction=\"in\", labelsize=9, rotation=45)\n",
"ax.tick_params(axis=\"y\", which=\"major\", direction=\"in\", labelsize=6)\n",
"ax.xaxis.set_ticks_position(\"none\")\n",
"ax.yaxis.set_ticks_position(\"none\")\n",
"ax.grid(True)\n",
"ax.legend(loc=\"upper left\", fancybox=True, framealpha=1, fontsize=\"medium\")\n",
"plt.show()\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "5e1b2800-5fe0-4a03-a50a-b927e74bf9b8",
"metadata": {},
"source": [
"\n",
"<br>\n",
"\n",
"### eigenvalue_centrality comparison for NetworkX and GraphBLAS graphs."
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "d3ed777a-7c80-4cee-a022-e0a6f876dfb5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"278 ms ± 1.68 ms per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"6.91 ms ± 518 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"%timeit -n5 nx.eigenvector_centrality(G0)\n",
"%timeit -n5 ga.eigenvector_centrality(G1)\n"
]
},
{
"cell_type": "markdown",
"id": "2e623fcb-dc20-43b0-95f5-ead88ec0d411",
"metadata": {},
"source": [
"<br>\n",
"\n",
"### average clustering coefficient comparison for NetworkX and GraphBLAS graphs.\n"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "544de594-0c7f-4751-940e-bab863f7807d",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4.44 s ± 2.1 ms per loop (mean ± std. dev. of 7 runs, 5 loops each)\n",
"45.5 ms ± 555 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)\n"
]
}
],
"source": [
"%timeit -n5 nx.average_clustering(G0)\n",
"%timeit -n5 ga.average_clustering(G1)\n"
]
},
{
"cell_type": "markdown",
"id": "f5b7e259-692e-4948-a335-80fb95ff078f",
"metadata": {},
"source": [
"<br>\n",
"\n",
"\n",
"**For objects that expose the `__networkx_plugin__` attribute, arbitrary graphs can be passed into \n",
"NetworkX functions, and the call will be dispatched to the appropriate subroutine.**\n",
"<br>\n",
"\n",
"**Notice that we can pass a GraphBLAS graph into a NetworkX function directly:**"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "bab34c65-67db-412a-9d1b-99579182d332",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"type(G1): <class 'graphblas_algorithms.classes.graph.Graph'>\n",
"G1.__networkx_plugin__: graphblas\n",
"\n"
]
}
],
"source": [
"print(f\"\\ntype(G1): {type(G1)}\")\n",
"print(f\"G1.__networkx_plugin__: {G1.__networkx_plugin__}\\n\")\n",
"\n",
"dc = nx.degree_centrality(G1)\n"
]
},
{
"cell_type": "markdown",
"id": "52250c71-9401-4d6b-98a0-93e13e2bc9fb",
"metadata": {},
"source": [
"**GraphBLAS graphs can be created independent of NetworkX. We can use the COOrdinate \n",
"sparse matrix representsation by specifying three arrays:**\n",
"\n",
"- **The row indicies of non-zero elements**\n",
"- **The column indicies of non-zero elements**\n",
"- **The values of non-zero elements**\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "79ab95a4-6c67-4baf-9195-7d03bbd04680",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"<class 'graphblas_algorithms.classes.graph.Graph'>\n"
]
}
],
"source": [
"# Creating GraphBLAS graphs directly.\n",
"\n",
"M = gb.Matrix.from_coo(\n",
" [0, 0, 1, 2, 2, 3, 4, 2],\n",
" [1, 3, 0, 0, 1, 2, 0, 4],\n",
" [4., 7., 9., 14., 3., 6., 11., 21.],\n",
" nrows=5, ncols=5, dtype='float32'\n",
" )\n",
"\n",
"G = ga.Graph(M)\n",
"\n",
"print(\"\\n\" + str(type(G)))\n"
]
},
{
"cell_type": "markdown",
"id": "e0dad9fb-9d1f-48eb-a6c6-22ed45a981dc",
"metadata": {},
"source": [
"<br>\n",
"\n",
"**Call `matrix`attribute to view matrix representation of graph:**"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "1f8d0320-0fb1-4edd-ac20-8d6f3f5ba528",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style>\n",
"table.gb-info-table {\n",
" border: 1px solid black;\n",
" max-width: 100%;\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 0px;\n",
"}\n",
"\n",
"td.gb-info-name-cell {\n",
" white-space: nowrap;\n",
"}\n",
"\n",
"details.gb-arg-details {\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 5px;\n",
" margin-left: 10px;\n",
"}\n",
"\n",
"summary.gb-arg-summary {\n",
" display: list-item;\n",
" outline: none;\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 0px;\n",
" margin-left: -10px;\n",
"}\n",
"\n",
"details.gb-expr-details {\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 5px;\n",
"}\n",
"\n",
"summary.gb-expr-summary {\n",
" display: list-item;\n",
" outline: none;\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 0px;\n",
"}\n",
"\n",
"blockquote.gb-expr-blockquote {\n",
" margin-top: 5px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 0px;\n",
" margin-left: 15px;\n",
"}\n",
"\n",
".gb-scalar {\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 5px;\n",
"}\n",
"\n",
"/* modify pandas dataframe */\n",
"table.dataframe {\n",
" margin-top: 0px;\n",
" margin-bottom: 0px;\n",
" padding-top: 0px;\n",
" padding-bottom: 0px;\n",
"}\n",
"\n",
"/* expression tooltips */\n",
".expr-tooltip .tooltip-circle {\n",
" background: #9a9cc6;\n",
" color: #fff;\n",
" border-radius: 50%;\n",
" width: 40px;\n",
" height: 40px;\n",
" padding-left: 4px;\n",
" padding-right: 4px;\n",
"}\n",
".expr-tooltip .tooltip-text {\n",
" visibility: hidden;\n",
" position: absolute;\n",
" width: 450px;\n",
" background: #eef;\n",
" border: 1px solid #99a;\n",
" text-align: left;\n",
" border-radius: 6px;\n",
" padding: 3px 3px 3px 8px;\n",
" margin-left: 6px;\n",
"}\n",
".expr-tooltip:hover .tooltip-text {\n",
" visibility: visible;\n",
"}\n",
".expr-tooltip code {\n",
" background-color: #f8ffed;\n",
"}\n",
"</style>\n",
"<details open class=\"gb-arg-details\"><summary class=\"gb-arg-summary\"><tt>M<sub>2</sub></tt><div>\n",
"<table class=\"gb-info-table\">\n",
" <tr>\n",
" <td rowspan=\"2\" class=\"gb-info-name-cell\"><pre>gb.Matrix</pre></td>\n",
" <td><pre>nvals</pre></td>\n",
" <td><pre>nrows</pre></td>\n",
" <td><pre>ncols</pre></td>\n",
" <td><pre>dtype</pre></td>\n",
" <td><pre>format</pre></td>\n",
" </tr>\n",
" <tr>\n",
" <td>8</td>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>FP32</td>\n",
" <td>bitmapr</td>\n",
" </tr>\n",
"</table>\n",
"</div>\n",
"</summary><div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td></td>\n",
" <td>4.0</td>\n",
" <td></td>\n",
" <td>7.0</td>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>9.0</td>\n",
" <td></td>\n",
" <td></td>\n",
" <td></td>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>14.0</td>\n",
" <td>3.0</td>\n",
" <td></td>\n",
" <td></td>\n",
" <td>21.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td></td>\n",
" <td></td>\n",
" <td>6.0</td>\n",
" <td></td>\n",
" <td></td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>11.0</td>\n",
" <td></td>\n",
" <td></td>\n",
" <td></td>\n",
" <td></td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div></details></div>"
],
"text/plain": [
"\"M_2\" nvals nrows ncols dtype format\n",
"gb.Matrix 8 5 5 FP32 bitmapr\n",
"----------------------------------------------\n",
" 0 1 2 3 4\n",
"0 4.0 7.0 \n",
"1 9.0 \n",
"2 14.0 3.0 21.0\n",
"3 6.0 \n",
"4 11.0 "
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"G.matrix"
]
},
{
"cell_type": "markdown",
"id": "a5f3cbd8-789f-4950-a25d-f37ae3057b37",
"metadata": {},
"source": [
"<br>\n",
"\n",
"**Show G in adjacency list representation:**"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "a294d387-05b1-4b7d-b005-c5274bc9c041",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{0: {1: 4.0, 3: 7.0},\n",
" 1: {0: 9.0},\n",
" 2: {0: 14.0, 1: 3.0, 4: 21.0},\n",
" 3: {2: 6.0},\n",
" 4: {0: 11.0}}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"G.matrix_to_dicts(M)"
]
},
{
"cell_type": "markdown",
"id": "478cdcac-7632-44c7-b27a-0f362570a019",
"metadata": {},
"source": [
"<br>\n",
"\n",
"**If there is a need to convert the OpenBLAS graph to a NetworkX graph, call `to_networkx`:**"
]
},
{
"cell_type": "code",
"execution_count": 92,
"id": "896c02ec-b8c4-48e5-8cc0-bf609a278a2d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'networkx.classes.graph.Graph'>\n"
]
}
],
"source": [
"Gn = G.to_networkx()\n",
"\n",
"print(type(Gn))\n"
]
}
],
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment