From a73c93d5a44f27df854c7eb76d3098a86b6b5255 Mon Sep 17 00:00:00 2001 From: Joseph White Date: Fri, 1 Dec 2023 10:54:36 -0500 Subject: [PATCH 1/2] Add reports --- ACCESS/PIs and Allocations.ipynb | 312 +++++++++++++++++++++++++ ACCESS/README.md | 11 + ACCESS/User-Resource-Overlaps.ipynb | 348 ++++++++++++++++++++++++++++ 3 files changed, 671 insertions(+) create mode 100644 ACCESS/PIs and Allocations.ipynb create mode 100644 ACCESS/README.md create mode 100644 ACCESS/User-Resource-Overlaps.ipynb diff --git a/ACCESS/PIs and Allocations.ipynb b/ACCESS/PIs and Allocations.ipynb new file mode 100644 index 0000000..a891c09 --- /dev/null +++ b/ACCESS/PIs and Allocations.ipynb @@ -0,0 +1,312 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "db4061c7-2b36-4284-af31-4ae940a07768", + "metadata": { + "tags": [] + }, + "source": [ + "# XDMoD Data Analytics Framework — PIs with allocations\n", + "v1.0.0\n", + "\n", + "© 2023 University at Buffalo Center for Computational Research\n", + "\n", + "See the [xdmod-notebooks](https://github.com/ubccr/xdmod-notebooks) repository for licensing information." + ] + }, + { + "cell_type": "markdown", + "id": "77f9e969-5120-4a7a-a844-fa6fda893755", + "metadata": {}, + "source": [ + "## Introduction\n", + "The XDMoD Data Analytics Framework provides API access to the data in XDMoD via the [`xdmod_data` Python module](https://pypi.org/project/xdmod-data). This notebook provides an introductory example showing how to use the module. You will use the XDMoD API to request data, load them into a [Pandas](https://pandas.pydata.org/) [DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html), and generate plots. The dataset in this example contains the number of active users of [ACCESS](https://access-ci.org/)-allocated resources per day of the week over a 4-month period." + ] + }, + { + "cell_type": "markdown", + "id": "84713a67-80c4-4803-8a45-0decdb65b500", + "metadata": {}, + "source": [ + "## Install/upgrade the required modules\n", + "Run the code below to install/upgrade the modules needed to run this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43521c0d-ca9e-47cd-ba5a-c1f9d0b83290", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "! {sys.executable} -m pip install --upgrade xdmod-data python-dotenv tabulate" + ] + }, + { + "cell_type": "markdown", + "id": "56c7d25d-241b-4c65-a77b-7eca37386714", + "metadata": {}, + "source": [ + "If running that code caused a new version of Plotly to be installed/upgraded, you may need to refresh your browser window for plots to appear correctly." + ] + }, + { + "cell_type": "markdown", + "id": "cdc4dfd8-5e8c-407c-ace6-f484608e4141", + "metadata": { + "tags": [] + }, + "source": [ + "## Configure notebook formatting" + ] + }, + { + "cell_type": "markdown", + "id": "7242d35a-7d1b-4b14-9aa5-b4a9bcb10a91", + "metadata": {}, + "source": [ + "### Tables\n", + "Run the code below to set up for displaying Pandas DataFrames as Markdown tables in this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2678201f-feba-4b2a-897f-284f05119b9c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from IPython.display import display, Markdown\n", + "def display_df_md_table(df):\n", + " return display(Markdown(df.replace('\\n', '
', regex=True).to_markdown()))" + ] + }, + { + "cell_type": "markdown", + "id": "67311e00-9fd8-4b1c-80cc-44b0d4b18a7f", + "metadata": {}, + "source": [ + "## Obtain an API token\n", + "Follow [these instructions](https://github.com/ubccr/xdmod-data#api-token-access) to obtain an API token." + ] + }, + { + "cell_type": "markdown", + "id": "035a27ba-a47b-4fe6-a7ea-b73e5f5a308a", + "metadata": { + "tags": [] + }, + "source": [ + "## Create an environment file\n", + "The `xdmod-data.env` file will store your XDMoD API token.\n", + "\n", + "Run the code below to create the file in your home directory (if it does not already exist) and allow only you to read and write to it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d216a32-11c6-4ae4-98e9-1b2c19d442d2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from os.path import expanduser\n", + "xdmod_data_env_path = Path(expanduser('~/xdmod-data.env'))\n", + "try:\n", + " with open(xdmod_data_env_path):\n", + " pass\n", + "except FileNotFoundError:\n", + " with open(xdmod_data_env_path, 'w') as xdmod_data_env_file:\n", + " xdmod_data_env_file.write('XDMOD_API_TOKEN=')\n", + " xdmod_data_env_path.chmod(0o600)" + ] + }, + { + "cell_type": "markdown", + "id": "ae55bfed-eedc-4a72-88d9-510fe271ed36", + "metadata": {}, + "source": [ + "## Store your API token in the environment file\n", + "Open the `xdmod-data.env` file and paste your token after `XDMOD_API_TOKEN=`.\n", + "\n", + "Save the file." + ] + }, + { + "cell_type": "markdown", + "id": "02193bb2-1b80-4b9d-8733-ad292a877ccf", + "metadata": { + "tags": [] + }, + "source": [ + "## Load your XDMoD API token into the environment\n", + "Run the code below to load the contents of the `xdmod-data.env` file into the environment. It will print `True` if it successfully loaded the file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d5eefbd5-8eab-4ac2-87fe-2c6271c7b9cd", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from dotenv import load_dotenv\n", + "load_dotenv(xdmod_data_env_path, override=True)" + ] + }, + { + "cell_type": "markdown", + "id": "bc6c166c-5e03-403b-88e1-4b4b2735c690", + "metadata": {}, + "source": [ + "## Initialize the XDMoD Data Warehouse\n", + "Run the code below to prepare for getting data from the XDMoD data warehouse at the given URL." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57583c14-0196-4e1d-bc63-3a66c493fa44", + "metadata": {}, + "outputs": [], + "source": [ + "from xdmod_data.warehouse import DataWarehouse\n", + "dw = DataWarehouse('https://xdmod.access-ci.org')" + ] + }, + { + "cell_type": "markdown", + "id": "3738a176-5b11-4a27-bf5c-2e785f07210d", + "metadata": {}, + "source": [ + "## Get the data from XDMoD\n", + "\n", + "The following code queries XDMoD to get the list of PIs from UC San Diego for projects that have had any usage during the report period. It then queries the allocation information for each PI." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00e141b1-3554-44e6-a08b-85b3f6b19fd3", + "metadata": {}, + "outputs": [], + "source": [ + "report_start = '2022-12-01'\n", + "report_end = '2023-11-30'\n", + "\n", + "output = {'PI': [], 'Allocation': [], 'ACCESS Credit Equivalents': []}\n", + "with dw:\n", + " pis = dw.get_data(\n", + " duration=(report_start, report_end),\n", + " realm='Jobs',\n", + " metric='Number of Jobs Ended',\n", + " dataset_type='aggregate',\n", + " dimension='PI',\n", + " filters={\n", + " 'PI Institution': ['UC San Diego - University of California, San Diego']\n", + " }\n", + " )\n", + " for pi in pis.index:\n", + " allocs = dw.get_data(\n", + " duration=(report_start, report_end),\n", + " realm='Jobs',\n", + " metric='ACCESS Credit Equivalents Charged: Total (SU)',\n", + " dataset_type='aggregate',\n", + " dimension='Allocation',\n", + " filters={\n", + " 'PI': [pi]\n", + " }\n", + " )\n", + " for alloc in allocs.index:\n", + " output['PI'].append(pi)\n", + " output['Allocation'].append(alloc)\n", + " output['ACCESS Credit Equivalents'].append(allocs[alloc])\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85992b84-6c73-4110-80e2-288f64e84db4", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "data= pd.DataFrame(output)\n", + "display_df_md_table(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7f77dfa4-69d1-4ad8-bb87-170470940846", + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Javascript\n", + "js_download = \"\"\"\n", + "var csv = `%s`;\n", + "\n", + "var filename = 'UC_PI_Allocations.csv';\n", + "var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n", + "if (navigator.msSaveBlob) { // IE 10+\n", + " navigator.msSaveBlob(blob, filename);\n", + "} else {\n", + " var link = document.createElement(\"a\");\n", + " link.innerHTML = 'Download as CSV';\n", + " if (link.download !== undefined) { // feature detection\n", + " // Browsers that support HTML5 download attribute\n", + " var url = URL.createObjectURL(blob);\n", + " link.setAttribute(\"href\", url);\n", + " link.setAttribute(\"download\", filename);\n", + " document.body.appendChild(link);\n", + " }\n", + "}\n", + "\"\"\" % data.to_csv(index=False)\n", + "\n", + "# Note this javascript link is intended for use when you export the notebook to html\n", + "# via jupyter nbconvert --to html [NOTEBOOK]\n", + "Javascript(js_download)" + ] + }, + { + "cell_type": "markdown", + "id": "b9cb8874-138a-45f4-a06b-244c67f510f2", + "metadata": {}, + "source": [ + "---\n", + "![XDMoD](data:image/png;base64,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) XDMoD Data Analytics Framework v1.0.0" + ] + } + ], + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ACCESS/README.md b/ACCESS/README.md new file mode 100644 index 0000000..6fedf24 --- /dev/null +++ b/ACCESS/README.md @@ -0,0 +1,11 @@ +# xdmod-notebooks/ACCESS + +This directory contains example Jupyter notebooks demonstrating how to use the XDMoD Data Analytics +framework for various analysis of usage and performance of ACCESS-allocated CI resources. + +If you are new to the XDMoD Data Analytics Framework then please see the `XDMoD-Data-First-Example.ipynb` +notebook in the parent directory. + +## Setup + +Please see the [setup instructions](../README.md#Setup) diff --git a/ACCESS/User-Resource-Overlaps.ipynb b/ACCESS/User-Resource-Overlaps.ipynb new file mode 100644 index 0000000..5f159dc --- /dev/null +++ b/ACCESS/User-Resource-Overlaps.ipynb @@ -0,0 +1,348 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "db4061c7-2b36-4284-af31-4ae940a07768", + "metadata": { + "tags": [] + }, + "source": [ + "# XDMoD Data Analytics Framework — User Resource Overlaps\n", + "v1.0.0\n", + "\n", + "© 2023 University at Buffalo Center for Computational Research\n", + "\n", + "See the [xdmod-notebooks](https://github.com/ubccr/xdmod-notebooks) repository for licensing information." + ] + }, + { + "cell_type": "markdown", + "id": "77f9e969-5120-4a7a-a844-fa6fda893755", + "metadata": {}, + "source": [ + "## Introduction\n", + "The XDMoD Data Analytics Framework provides API access to the data in XDMoD via the [`xdmod_data` Python module](https://pypi.org/project/xdmod-data). This notebook provides an introductory example showing how to use the module. You will use the XDMoD API to request data, load them into a [Pandas](https://pandas.pydata.org/) [DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html), and generate plots. The dataset in this example contains the number of active users of [ACCESS](https://access-ci.org/)-allocated resources per day of the week over a 4-month period." + ] + }, + { + "cell_type": "markdown", + "id": "84713a67-80c4-4803-8a45-0decdb65b500", + "metadata": {}, + "source": [ + "## Install/upgrade the required modules\n", + "Run the code below to install/upgrade the modules needed to run this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43521c0d-ca9e-47cd-ba5a-c1f9d0b83290", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "! {sys.executable} -m pip install --upgrade xdmod-data python-dotenv tabulate\n", + "\n", + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "56c7d25d-241b-4c65-a77b-7eca37386714", + "metadata": {}, + "source": [ + "If running that code caused a new version of Plotly to be installed/upgraded, you may need to refresh your browser window for plots to appear correctly." + ] + }, + { + "cell_type": "markdown", + "id": "cdc4dfd8-5e8c-407c-ace6-f484608e4141", + "metadata": { + "tags": [] + }, + "source": [ + "## Configure notebook formatting" + ] + }, + { + "cell_type": "markdown", + "id": "7242d35a-7d1b-4b14-9aa5-b4a9bcb10a91", + "metadata": {}, + "source": [ + "### Tables\n", + "Run the code below to set up for displaying Pandas DataFrames as Markdown tables in this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2678201f-feba-4b2a-897f-284f05119b9c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from IPython.display import display, Markdown\n", + "def display_df_md_table(df):\n", + " return display(Markdown(df.replace('\\n', '
', regex=True).to_markdown()))" + ] + }, + { + "cell_type": "markdown", + "id": "035a27ba-a47b-4fe6-a7ea-b73e5f5a308a", + "metadata": {}, + "source": [ + "## Create an environment file\n", + "The `xdmod-data.env` file will store your XDMoD API token.\n", + "\n", + "Run the code below to create the file in your home directory (if it does not already exist) and allow only you to read and write to it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d216a32-11c6-4ae4-98e9-1b2c19d442d2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from os.path import expanduser\n", + "xdmod_data_env_path = Path(expanduser('~/xdmod-data.env'))\n", + "try:\n", + " with open(xdmod_data_env_path):\n", + " pass\n", + "except FileNotFoundError:\n", + " with open(xdmod_data_env_path, 'w') as xdmod_data_env_file:\n", + " xdmod_data_env_file.write('XDMOD_API_TOKEN=')\n", + " xdmod_data_env_path.chmod(0o600)" + ] + }, + { + "cell_type": "markdown", + "id": "67311e00-9fd8-4b1c-80cc-44b0d4b18a7f", + "metadata": {}, + "source": [ + "## Obtain an API token\n", + "Follow [these instructions](https://github.com/ubccr/xdmod-data#api-token-access) to obtain an API token." + ] + }, + { + "cell_type": "markdown", + "id": "ae55bfed-eedc-4a72-88d9-510fe271ed36", + "metadata": {}, + "source": [ + "## Store your API token in the environment file\n", + "Open the `xdmod-data.env` file and paste your token after `XDMOD_API_TOKEN=`.\n", + "\n", + "Save the file." + ] + }, + { + "cell_type": "markdown", + "id": "02193bb2-1b80-4b9d-8733-ad292a877ccf", + "metadata": { + "tags": [] + }, + "source": [ + "## Load your XDMoD API token into the environment\n", + "Run the code below to load the contents of the `xdmod-data.env` file into the environment. It will print `True` if it successfully loaded the file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d5eefbd5-8eab-4ac2-87fe-2c6271c7b9cd", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from dotenv import load_dotenv\n", + "load_dotenv(xdmod_data_env_path, override=True)" + ] + }, + { + "cell_type": "markdown", + "id": "bc6c166c-5e03-403b-88e1-4b4b2735c690", + "metadata": {}, + "source": [ + "## Initialize the XDMoD Data Warehouse\n", + "Run the code below to prepare for getting data from the XDMoD data warehouse at the given URL." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57583c14-0196-4e1d-bc63-3a66c493fa44", + "metadata": {}, + "outputs": [], + "source": [ + "from xdmod_data.warehouse import DataWarehouse\n", + "dw = DataWarehouse('https://xdmod.access-ci.org')" + ] + }, + { + "cell_type": "markdown", + "id": "3738a176-5b11-4a27-bf5c-2e785f07210d", + "metadata": {}, + "source": [ + "## Get the list of resource that have run compute jobs\n", + "\n", + "Get the list of compute resources that have run compute jobs during the specific times and how many distinct ACCESS users have used it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00e141b1-3554-44e6-a08b-85b3f6b19fd3", + "metadata": {}, + "outputs": [], + "source": [ + "report_start = '2022-10-01'\n", + "report_end = '2023-09-30'\n", + "\n", + "with dw:\n", + " resources = dw.get_data(\n", + " duration=(report_start, report_end),\n", + " realm='Jobs',\n", + " metric='Number of Users: Active',\n", + " dataset_type='aggregate',\n", + " dimension='Resource'\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "258e366e-04fb-4a99-b1cf-31dc07bfc676", + "metadata": {}, + "source": [ + "Then for each resource we can obtain the list of users and the number of service units consumed during the report period. In this case we just stored the list of users for each resource." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79a95d2c-eba2-48bd-8770-1b957679da54", + "metadata": {}, + "outputs": [], + "source": [ + "resource_people = {}\n", + "for resource in resources.index:\n", + " with dw: \n", + " people = dw.get_data(\n", + " duration=(report_start, report_end),\n", + " realm='Jobs',\n", + " metric='ACCESS Credit Equivalents Charged: Total (SU)',\n", + " dataset_type='aggregate',\n", + " dimension='User',\n", + " filters={\n", + " 'Resource': [resource]\n", + " }\n", + " )\n", + " resource_people[resource] = set(people.index)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "5edfdc87-1134-4ed6-be8b-f720e6e4dc8d", + "metadata": {}, + "source": [ + "Then compute the overlap of users between different resources and display in a table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70e10722-6ddf-4667-9930-059b1b3721b4", + "metadata": {}, + "outputs": [], + "source": [ + "out = {'Resource': []}\n", + "for r1, r1p in resource_people.items():\n", + " out['Resource'].append(r1)\n", + " for r2, r2p in resource_people.items():\n", + " if r2 not in out:\n", + " out[r2] = []\n", + " out[r2].append(len(r1p.intersection(r2p)))\n", + " \n", + "data = pd.DataFrame(out)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a3f5cba7-9f1e-4545-8aa0-7c1ddc81506d", + "metadata": {}, + "outputs": [], + "source": [ + "data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62b2bc6b-3ce2-4d70-ae50-73f125d184c5", + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Javascript\n", + "js_download = \"\"\"\n", + "var csv = `%s`;\n", + "\n", + "var filename = 'User-Resource-Overlap.csv';\n", + "var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n", + "if (navigator.msSaveBlob) { // IE 10+\n", + " navigator.msSaveBlob(blob, filename);\n", + "} else {\n", + " var link = document.createElement(\"a\");\n", + " link.innerHTML = 'Download as CSV';\n", + " if (link.download !== undefined) { // feature detection\n", + " // Browsers that support HTML5 download attribute\n", + " var url = URL.createObjectURL(blob);\n", + " link.setAttribute(\"href\", url);\n", + " link.setAttribute(\"download\", filename);\n", + " document.body.appendChild(link);\n", + " }\n", + "}\n", + "\"\"\" % data.to_csv(index=False)\n", + "\n", + "# Note this javascript link is intended for use when you export the notebook to html\n", + "# via jupyter nbconvert --to html [NOTEBOOK]\n", + "Javascript(js_download)" + ] + }, + { + "cell_type": "markdown", + "id": "b9cb8874-138a-45f4-a06b-244c67f510f2", + "metadata": {}, + "source": [ + "---\n", + "![XDMoD](data:image/png;base64,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) XDMoD Data Analytics Framework v1.0.0" + ] + } + ], + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ed2752884e2b49e0a2bcfff3c4e238526d119b90 Mon Sep 17 00:00:00 2001 From: Joseph White Date: Fri, 1 Dec 2023 11:41:28 -0500 Subject: [PATCH 2/2] Add histogram plot too. --- ACCESS/User-Resource-Overlaps.ipynb | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/ACCESS/User-Resource-Overlaps.ipynb b/ACCESS/User-Resource-Overlaps.ipynb index 5f159dc..8aa0796 100644 --- a/ACCESS/User-Resource-Overlaps.ipynb +++ b/ACCESS/User-Resource-Overlaps.ipynb @@ -87,6 +87,28 @@ " return display(Markdown(df.replace('\\n', '
', regex=True).to_markdown()))" ] }, + { + "cell_type": "markdown", + "id": "d9e37669-ca38-42a6-b97c-a361cc3ab21e", + "metadata": {}, + "source": [ + "## Plotting\n", + "Run the code below to import plotly libraries and set the XDMoD theme" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cccc2e6-48e8-474f-bbb3-83e2e36869a1", + "metadata": {}, + "outputs": [], + "source": [ + "import plotly.express as px\n", + "import plotly.io as pio\n", + "import xdmod_data.themes\n", + "pio.templates.default = \"timeseries\"" + ] + }, { "cell_type": "markdown", "id": "035a27ba-a47b-4fe6-a7ea-b73e5f5a308a", @@ -314,6 +336,40 @@ "Javascript(js_download)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "2eb42a63-bf40-493e-85c3-37e20ece8c97", + "metadata": {}, + "outputs": [], + "source": [ + "allpeople = set()\n", + "for r, p in resource_people.items():\n", + " allpeople |= p\n", + " \n", + "out = {'Person': list(allpeople), 'Resource Count': []}\n", + "for p in out['Person']:\n", + " count = 0\n", + " for pet in resource_people.values():\n", + " if p in pet:\n", + " count += 1\n", + " out['Resource Count'].append(count)\n", + "\n", + "data = pd.DataFrame(out)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c8a20af7-90e8-4c6f-a276-5413a60be922", + "metadata": {}, + "outputs": [], + "source": [ + "fig = px.histogram(data, x='Resource Count', log_y=True, text_auto=True)\n", + "fig.update_layout(yaxis_title=\"Number of Users (log scale)\")\n", + "fig.show()" + ] + }, { "cell_type": "markdown", "id": "b9cb8874-138a-45f4-a06b-244c67f510f2",