diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..830855e --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,34 @@ +# This file will lint the specified files/directories. + +name: lint + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install python and dependencies + uses: actions/setup-python@v4 + with: + python-version: '3.13' + cache: 'pip' + - run: pip install -r requirements.txt + + - name: Lint model code + run: | + flake8 ./simulation + pylint ./simulation + + - name: Lint tests + run: | + flake8 ./tests + pylint ./tests diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 7530402..40c777d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,4 +1,4 @@ -# This file runs the tests in `tests/` with every push to GitHub +# This file runs the tests in `tests/` # They will run in parallel, and run on three operating systems: # Ubuntu, Windows and Mac. @@ -6,6 +6,8 @@ name: tests on: push: + branches: [main] + pull_request: workflow_dispatch: jobs: diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..c1b664a --- /dev/null +++ b/.pylintrc @@ -0,0 +1,4 @@ +[MESSAGES CONTROL] +disable= + too-few-public-methods, + too-many-instance-attributes \ No newline at end of file diff --git a/CITATION.cff b/CITATION.cff index 6698525..1200eff 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,8 +3,7 @@ cff-version: 1.2.0 title: >- - Simple Reproducible Python Discrete-Event Simulation (DES) - Template + Python DES RAP Template message: >- If you use this software, please cite it using the metadata from this file. @@ -18,8 +17,8 @@ authors: repository-code: >- https://github.com/pythonhealthdatascience/rap_template_python_des abstract: >- - Template reproducible analytical pipeline (RAP) for simple - python DES model. + A template for creating discrete-event simulation (DES) models in Python + within a reproducible analytical pipeline (RAP). license: MIT # TODO: Manually update with each GitHub release version: '0.1.0' diff --git a/README.md b/README.md index 58523a3..6aa5a16 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@
-# Simple Reproducible Python
Discrete-Event Simulation (DES) Template +# Python DES RAP Template [![python](https://img.shields.io/badge/-Python_3.13-306998?logo=python&logoColor=white)](https://www.python.org/) [![licence](https://img.shields.io/badge/Licence-MIT-green.svg?labelColor=gray)](https://github.com/pythonhealthdatascience/rap_template_python_des/blob/main/LICENSE) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14622466.svg)](https://doi.org/10.5281/zenodo.14622466) [![Tests](https://github.com/pythonhealthdatascience/rap_template_python_des/actions/workflows/tests.yaml/badge.svg)](https://github.com/pythonhealthdatascience/rap_template_python_des/actions/workflows/tests.yaml) -A simple template for creating DES models in Python, within a **reproducible analytical pipeline (RAP)**
+
A template for creating **discrete-event simulation (DES)** models in Python
+within a **reproducible analytical pipeline (RAP)**.

Click on Use this template to initialise new repository.
A `README` template is provided at the **end of this file**. @@ -41,9 +42,9 @@ This repository provides a template for building discrete-event simulation (DES) ♻️ **Reproducible:** This template is designed to function as a RAP. It adheres to reproducibility recommendations from: * ["Levels of RAP" framework](https://nhsdigital.github.io/rap-community-of-practice/introduction_to_RAP/levels_of_RAP/) from the NHS RAP Community of Practice (`docs/nhs_rap.md`). -* Recommendations from [Heather et al. 2025](TODO:ADDLINK) "*On the reproducibility of discrete-event simulation studies in health research: an empirical study using open models*" (`docs/heather_2025.md`). +* Recommendations from [Heather et al. 2025](https://doi.org/10.48550/arXiv.2501.13137) "*On the reproducibility of discrete-event simulation studies in health research: an empirical study using open models*" (`docs/heather_2025.md`). -🚀 **Extendable:** This template adapts from and complements material from Sammi Rosser and Dan Chalk (2024) ["HSMA - the little book of DES"](https://github.com/hsma-programme/hsma6_des_book). The book includes additional advanced features that can be used to extend the model in this template, including: +🚀 **Extendable:** This template adapts from Sammi Rosser and Dan Chalk (2024) ["HSMA - the little book of DES"](https://github.com/hsma-programme/hsma6_des_book). The book includes additional advanced features that can be used to extend the model in this template, including: * Multiple activities * Branching paths @@ -149,6 +150,12 @@ To run tests, ensure environment is active and located in main directory (i.e. p pytest ``` +To run tests in parallel - + +``` +pytest -n auto +``` + The repository contains a GitHub action `tests.yaml` which will automatically run tests with new commits to GitHub. This is continuous integration, helping to catch bugs early and keep the code stable. It will run the tests on three operating systems: Ubuntu, Windows and Mac. If you have changed the model behaviour, you may wish to amend, remove or write new tests. @@ -184,10 +191,12 @@ This section describes the purposes of each class in the simulation. * `generate_patient_arrivals()` to handle patient creation, then sending them on to `attend_clinic()`. * `interval_audit()` to record utilisation and wait times at specified intervals during the simulation. -**Trial Class Usage:** +**Runner Class Usage:** + +Having set up `experiment = Runner()`... -* **Single Run:** Use `trial.run_single()` to execute a single model run. -* **Multiple Runs:** Use `trial.run_trial()` to perform multiple replications of the model. +* **Single Run:** Use `experiment.run_single()` to execute a single model run. +* **Multiple Runs:** Use `experiment.run_reps()` to perform multiple replications of the model.
@@ -210,6 +219,7 @@ repo/ ├── simulation/ # Local package containing code for the DES model ├── tests/ # Unit and back testing of the DES model ├── .gitignore # Untracked files +├── .pylintrc # Pylint settings ├── CHANGELOG.md # Describes changes between releases ├── CITATION.cff # How to cite the repository ├── CONTRIBUTING.md # Contribution instructions @@ -230,6 +240,8 @@ The overall run time will vary depending on how the template model is used. A fe * `choosing_parameters.ipynb` - 22s * `generate_exp_results.ipynb` - 0s + + These times were obtained on an Intel Core i7-12700H with 32GB RAM running Ubuntu 24.04.1 Linux.
diff --git a/docs/heather_2025.md b/docs/heather_2025.md index 4bf6ffc..cd74a26 100644 --- a/docs/heather_2025.md +++ b/docs/heather_2025.md @@ -1,6 +1,6 @@ # Reproducibility recommendations from Heather et al. 2025 -As part of the project STARS (Sharing Tools and Artefacts for Reproducible Simulations), a series of computational reproducibility assessments were conducted by Heather et al. 2025 (**TODO: add DOI of pre-print**). From these, several recommendations were shared to support reproducibility of healthcare discrete-event simulation (DES) models. These are copied below. Those marked with a star (⭐) were identified as having the greatest impact in Heather et al. 2025. +As part of the project STARS (Sharing Tools and Artefacts for Reproducible Simulations), a series of computational reproducibility assessments were conducted by [Heather et al. 2025](https://doi.org/10.48550/arXiv.2501.13137). From these, several recommendations were shared to support reproducibility of healthcare discrete-event simulation (DES) models. These are copied below. Those marked with a star (⭐) were identified as having the greatest impact in Heather et al. 2025. ## Recommendations to support reproduction diff --git a/docs/hsma_changes.md b/docs/hsma_changes.md index 26eb513..7508b8b 100644 --- a/docs/hsma_changes.md +++ b/docs/hsma_changes.md @@ -132,9 +132,9 @@ param.patient_inter = 10 model = Model(param) ``` -## Saving trial results +## Saving replication results -To save trial-level results in the HSMA models, an empty dataframe is initialised during the __init__ method of the `Trial` class. +To save results from each run in the HSMA models, an empty dataframe is initialised during the __init__ method of the `Trial` class (equivalent to the `Runner` class in this template). ``` self.df_trial_results = pd.DataFrame() @@ -164,7 +164,7 @@ In the template, results are instead saved as a dictionary into a list as the ru Also, some of the calculations have been performed directly during the `run_single()` method, instead of from a seperate method `calculate_run_results()`. This is to help simplify the code, as it makes clear how each metric was calculated in one place, rather than needing to refer elsewhere. ``` -trial_results = { +run_results = { 'run_number': run, 'scenario': self.param.scenario_name, 'arrivals': len(patient_results), @@ -176,7 +176,7 @@ trial_results = { ... -self.trial_results_df = pd.DataFrame(trial_results_list) +self.run_results_df = pd.DataFrame(run_results_list) ``` ## Extra features diff --git a/docs/nhs_rap.md b/docs/nhs_rap.md index 2250234..0b05fa1 100644 --- a/docs/nhs_rap.md +++ b/docs/nhs_rap.md @@ -15,7 +15,7 @@ RAP fundamentals offering resilience against future change. | Data produced by code in an open-source language (e.g., Python, R, SQL). | ✅ | Python | | Code is version controlled (see [Git basics](https://nhsdigital.github.io/rap-community-of-practice/training_resources/git/introduction-to-git/) and [using Git collaboratively](https://nhsdigital.github.io/rap-community-of-practice/training_resources/git/using-git-collaboratively/) guides). | ✅ | [GitHub](https://github.com/pythonhealthdatascience/rap_template_python_des/) | | Repository includes a README.md file (or equivalent) that clearly details steps a user must follow to reproduce the code (use [NHS Open Source Policy section on Readmes](https://github.com/nhsx/open-source-policy/blob/main/open-source-policy.md#b-readmes) as a guide). | ✅ | - | -| Code has been [peer reviewed](https://nhsdigital.github.io/rap-community-of-practice/implementing_RAP/workflow/code-review/). | ❌ | **TODO: Have code peer reviewed, record on GitHub - this would typically be through working on branches and then reviewing code in a pull request before it is merged into the already approved code. Could create empty branch.** | +| Code has been [peer reviewed](https://nhsdigital.github.io/rap-community-of-practice/implementing_RAP/workflow/code-review/). | ✅ | Peer reviewed by Tom Monks | | Code is [published in the open](https://nhsdigital.github.io/rap-community-of-practice/implementing_RAP/publishing_code/how-to-publish-your-code-in-the-open/) and linked to & from accompanying publication (if relevant). | ✅ & N/A | Shared openly. No publication. | ## 🥈 Silver diff --git a/docs/time_weighted_averages.ipynb b/docs/time_weighted_averages.ipynb new file mode 100644 index 0000000..9894ae1 --- /dev/null +++ b/docs/time_weighted_averages.ipynb @@ -0,0 +1,373 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Time-weighted averages\n", + "\n", + "This notebook provides some simple examples to explain the time-weighted average calculation used in the model." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext pycodestyle_magic\n", + "%pycodestyle_on\n", + "\n", + "import plotly.express as px\n", + "import plotly.io as pio\n", + "\n", + "pio.renderers.default = 'svg'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 1: Queue size" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we have a given queue size over time:\n", + "\n", + "| Interval | Queue Size | Duration |\n", + "|-------------|------------|----------|\n", + "| 0 - 14.4 | 0 | 14.4 |\n", + "| 14.4 - 15.2 | 1 | 0.8 |\n", + "| 15.2 - 16.1 | 2 | 0.9 |\n", + "| 16.1 - 17.0 | 3 | 0.9 |\n", + "\n", + "You can see that, for most of the time, there is no-one in the queue, but then a few people join at the end.\n", + "\n", + "Hence, we would logically expect to see an average queue size fairly close to 0." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "02468101214160123TimeQueue size" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Given data\n", + "time = [0.0, 14.4, 15.2, 16.1, 17.0]\n", + "queue = [0, 1, 2, 3, 3]\n", + "\n", + "fig = px.line(x=time, y=queue)\n", + "fig.update_traces(mode='lines', line_shape='hv')\n", + "fig.update_xaxes(dtick=2)\n", + "fig.update_yaxes(dtick=1)\n", + "fig.update_layout(\n", + " xaxis_title='Time',\n", + " yaxis_title='Queue size',\n", + " template='plotly_white')\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Simple average\n", + "\n", + "#### Formula for simple average queue size:\n", + "\n", + "$$\n", + "\\text{Simple Average} = \\frac{\\sum (\\text{Queue Size})}{\\text{Number of Intervals}}\n", + "$$\n", + "\n", + "#### Applying values:\n", + "\n", + "$$\n", + "= \\frac{0 + 1 + 2 + 3}{4}\n", + "$$\n", + "\n", + "$$\n", + "= \\frac{6}{4} = 1.5\n", + "$$\n", + "\n", + "With a simple average, we find quite a high average: 1.5." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simple Average Queue Size: 1.5\n" + ] + } + ], + "source": [ + "simple_avg = sum(queue[:-1]) / len(queue[:-1])\n", + "print(f'Simple Average Queue Size: {simple_avg}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time-weighted average\n", + "\n", + "#### Formula for time-weighted average queue size:\n", + "\n", + "$$\n", + "\\text{Time-Weighted Average} = \\frac{\\sum (\\text{Queue Size} \\times \\text{Time Duration})}{\\text{Total Time}}\n", + "$$\n", + "\n", + "#### Applying values:\n", + "\n", + "$$\n", + "= \\frac{(0 \\times 14.4) + (1 \\times 0.8) + (2 \\times 0.9) + (3 \\times 0.9)}{17.0}\n", + "$$\n", + "\n", + "$$\n", + "= \\frac{0 + 0.8 + 1.8 + 2.7}{17.0}\n", + "$$\n", + "\n", + "$$\n", + "= \\frac{5.3}{17.0} \\approx 0.312\n", + "$$\n", + "\n", + "The time-weighted average better meets our expectations, being fairly close to 0." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Time-Weighted Average Queue Size: 0.3117647058823529\n" + ] + } + ], + "source": [ + "# Compute time-weighted sum\n", + "weighted_sum = sum(\n", + " queue[i] * (time[i+1] - time[i]) for i in range(len(time)-1))\n", + "\n", + "# Total time duration\n", + "total_time = time[-1] - time[0]\n", + "\n", + "# Compute time-weighted average\n", + "time_weighted_avg = weighted_sum / total_time\n", + "\n", + "print(f'Time-Weighted Average Queue Size: {time_weighted_avg}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 2: Utilisation\n", + "\n", + "Building on our queue example:\n", + "\n", + "* There are **2 nurses** in this system.\n", + "* Five patients arrive during the observation period - 2 at the start, and 3 near the end.\n", + "* **Patients A and B** are seen immediately, and each has a long consultation.\n", + "* **Patients C, D, and E** arrive and wait in the queue since no nurses are available, and are still waiting at the end of the observation period." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| Time | Event | Patients in system | Nurses busy | Queue size |\n", + "| - | - | - | - | - |\n", + "| 0.0 | Clinic opens |0 | 0 | 0 |\n", + "| 1.2 | Patient A arrives, sees nurse for 19 | 1 | 1 | 0 |\n", + "| 2.3 | Patient B arrives, sees nurse for 20 | 2 | 2 | 0 |\n", + "| 14.4 | Patient C arrives, waits for nurse | 3 | 2 | 1 |\n", + "| 15.2 | Patient D arrives, waits for nurse | 4 | 2 | 2 |\n", + "| 16.1 | Patient E arrives, waits for nurse | 5 | 2 | 3 |\n", + "| 17.0 | Simulation ends, three patients waiting still | 5 | 2 | 3 |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The utilisation of the nurses will depend on how many are busy at each point in time.\n", + "\n", + "* When **no nurses** are busy, utilisation is **0.0** (i.e. 0%).\n", + "* When **one nurse** is busy, utilisation is **0.5** (i.e. 50%).\n", + "* When **two nurses** are busy, utilisation is **1.0** (i.e. 100%)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "024681012141600.51TimeNurse utilisation" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "time = [0.0, 1.2, 2.3, 14.4, 15.2, 16.1, 17.0]\n", + "utilisation = [0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0]\n", + "\n", + "fig = px.line(x=time, y=utilisation)\n", + "fig.update_traces(mode='lines', line_shape='hv')\n", + "fig.update_xaxes(dtick=2)\n", + "fig.update_yaxes(dtick=0.5)\n", + "fig.update_layout(\n", + " xaxis_title='Time',\n", + " yaxis_title='Nurse utilisation',\n", + " template='plotly_white')\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this scenario, we'd expect to see an average utilisation close to 1, as there was full utilisation for most of the observation period." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Simple average\n", + "\n", + "#### Formula for simple average utilisation\n", + "\n", + "$$\n", + "\\text{Simple Average} = \\frac{\\sum (\\text{Utilisation})}{\\text{Number of Intervals}}\n", + "$$\n", + "\n", + "#### Applying values:\n", + "\n", + "$$\n", + "= \\frac{0 + 0.5 + 1 + 1 + 1 + 1 + 1}{7} = 0.7857\n", + "$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simple Average Utilisation: 0.7857142857142857\n" + ] + } + ], + "source": [ + "simple_avg = sum(utilisation) / len(utilisation)\n", + "print(f'Simple Average Utilisation: {simple_avg}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time-weighted average\n", + "\n", + "#### Formula for time-weighted utilisation\n", + "\n", + "$$\n", + "\\text{Time-Weighted Average} = \\frac{\\sum (\\text{Utilisation} \\times \\text{Time Duration})}{\\text{Total Time}}\n", + "$$\n", + "\n", + "#### Applying values:\n", + "\n", + "$$\n", + "= \\frac{(0 \\times 1.2) + (0.5 \\times 1.1) + (1 \\times 14.7)}{17.0}\n", + "$$\n", + "\n", + "$$\n", + "= \\frac{0 + 0.55 + 14.7}{17.0} \\approx 0.897\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Time-Weighted Average Utilisation: 0.8970588235294119\n" + ] + } + ], + "source": [ + "weighted_sum = sum(\n", + " utilisation[i] * (time[i+1] - time[i]) for i in range(len(time)-1)\n", + ")\n", + "\n", + "# Total time duration\n", + "total_time = time[-1] - time[0]\n", + "\n", + "time_weighted_avg = weighted_sum / total_time\n", + "print(f'Time-Weighted Average Utilisation: {time_weighted_avg}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When calculating the time-weighted average, we indeed observe a higher average utilisation, better reflecting the reality of utilisation during the observation period." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "template-des", + "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.13.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/environment.yaml b/environment.yaml index f05fd0c..f34ad17 100644 --- a/environment.yaml +++ b/environment.yaml @@ -14,7 +14,9 @@ dependencies: - pip=24.3.1 - plotly_express=0.4.1 - pycodestyle=2.12.1 + - pylint=3.3.3 - pytest=8.3.4 + - pytest-xdist=3.6.1 - python=3.13.0 - simpy=4.1.1 - pip: diff --git a/images/model_structure.drawio b/images/model_structure.drawio index 204927a..fffe8e4 100644 --- a/images/model_structure.drawio +++ b/images/model_structure.drawio @@ -1,58 +1,58 @@ - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + @@ -60,7 +60,7 @@ - + @@ -77,19 +77,19 @@ - + - + - + - + @@ -99,35 +99,35 @@ - + - + - + - + - + - + - + - + - - + + @@ -139,13 +139,13 @@ - + - - + + - - + + @@ -153,34 +153,34 @@ - - + + - + - - + + - + - - + + - + - + - + - + - + @@ -190,10 +190,10 @@ - + - + @@ -203,7 +203,7 @@ - + @@ -213,43 +213,58 @@ - + - - + + - - + + - - - - + + - - - - - - - + + - + - + - - + + - + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/model_structure.png b/images/model_structure.png index b8b399d..10326e7 100644 Binary files a/images/model_structure.png and b/images/model_structure.png differ diff --git a/notebooks/analysis.ipynb b/notebooks/analysis.ipynb index 1d9eb88..d7a2e7f 100644 --- a/notebooks/analysis.ipynb +++ b/notebooks/analysis.ipynb @@ -16,7 +16,7 @@ "\n", "Credit:\n", "\n", - "* Analysis of the spread of replication results was adapted from Tom Monks (2024) HPDM097 - Making a difference with health data (https://github.com/health-data-science-OR/stochastic_systems) (MIT License)." + "* Analysis of the spread of replication results was adapted from Tom Monks (2024) HPDM097 - Making a difference with health data (https://github.com/health-data-science-OR/stochastic_systems) (MIT Licence)." ] }, { @@ -98,17 +98,17 @@ " # set up ONE trace\n", " first_col = included_columns[0]\n", " first_friendly_name = (\n", - " name_mappings[first_col][\"friendly_name\"]\n", + " name_mappings[first_col]['friendly_name']\n", " if name_mappings and first_col in name_mappings\n", " else first_col\n", " )\n", " first_units = (\n", - " name_mappings[first_col][\"units\"]\n", + " name_mappings[first_col]['units']\n", " if name_mappings and first_col in name_mappings\n", - " else \"\"\n", + " else ''\n", " )\n", " first_x_title = (\n", - " f\"{first_friendly_name} ({first_units})\"\n", + " f'{first_friendly_name} ({first_units})'\n", " if first_units\n", " else first_friendly_name\n", " )\n", @@ -121,18 +121,18 @@ " # create list of drop down items - KPIs\n", " for col in included_columns:\n", " if name_mappings and col in name_mappings:\n", - " friendly_name = name_mappings[col][\"friendly_name\"]\n", - " units = name_mappings[col][\"units\"]\n", - " x_title = f\"{friendly_name} ({units})\" if units else friendly_name\n", + " friendly_name = name_mappings[col]['friendly_name']\n", + " units = name_mappings[col]['units']\n", + " x_title = f'{friendly_name} ({units})' if units else friendly_name\n", " else:\n", " friendly_name = col\n", " x_title = col\n", "\n", " buttons.append(\n", " dict(\n", - " method=\"update\",\n", + " method='update',\n", " label=friendly_name,\n", - " args=[{\"x\": [results[col]]}, {\"xaxis\": {\"title\": x_title}}],\n", + " args=[{'x': [results[col]]}, {'xaxis': {'title': x_title}}],\n", " )\n", " )\n", "\n", @@ -141,9 +141,9 @@ " your_menu = dict()\n", " updatemenu.append(your_menu)\n", "\n", - " updatemenu[0][\"buttons\"] = buttons\n", - " updatemenu[0][\"direction\"] = \"down\"\n", - " updatemenu[0][\"showactive\"] = True\n", + " updatemenu[0]['buttons'] = buttons\n", + " updatemenu[0]['direction'] = 'down'\n", + " updatemenu[0]['showactive'] = True\n", "\n", " # add dropdown menus to the figure\n", " fig.update_layout(showlegend=False, updatemenus=updatemenu)\n", @@ -151,9 +151,9 @@ " # Add annotation as instruction\n", " if include_instruct:\n", " fig.add_annotation(\n", - " text=\"Select a KPI from the drop down list\",\n", - " xref=\"paper\",\n", - " yref=\"paper\",\n", + " text='Select a KPI from the drop down list',\n", + " xref='paper',\n", + " yref='paper',\n", " x=0.0,\n", " y=1.1, # Positions the text above the plot\n", " showarrow=False,\n", @@ -216,21 +216,22 @@ "metadata": {}, "outputs": [], "source": [ - "import itertools\n", "import os\n", "import pandas as pd\n", "import plotly.express as px\n", + "import plotly.io as pio\n", "import time\n", "\n", "from simulation.logging import SimLogger\n", - "from simulation.model import Defaults, Model, Trial, summary_stats" + "from simulation.model import (\n", + " Defaults, Model, Runner, summary_stats, run_scenarios)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Start timer." + "Display plotly express figures as non-interactive figures. This means they will be visible when browsing the notebooks on GitHub. To switch these back to interactive figures, simply remove this line." ] }, { @@ -238,6 +239,22 @@ "execution_count": 7, "metadata": {}, "outputs": [], + "source": [ + "pio.renderers.default = 'svg'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start timer." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], "source": [ "start_time = time.time()" ] @@ -251,11 +268,11 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "output_dir = \"../outputs/\"" + "output_dir = '../outputs/'" ] }, { @@ -274,13 +291,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "param = Defaults()\n", - "trial = Trial(param)\n", - "trial.run_trial()" + "experiment = Runner(param)\n", + "experiment.run_reps()" ] }, { @@ -293,7 +310,7 @@ "\n", "```python\n", "# Save file\n", - "trial.patient_results_df.to_csv(\n", + "experiment.patient_results_df.to_csv(\n", " os.path.join(output_dir, 'example_patient.csv.gz'),\n", " index=False, compression='gzip')\n", "\n", @@ -306,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -396,12 +413,12 @@ } ], "source": [ - "display(trial.patient_results_df.head())" + "display(experiment.patient_results_df.head())" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -431,6 +448,8 @@ " mean_q_time_nurse\n", " mean_time_with_nurse\n", " mean_nurse_utilisation\n", + " mean_nurse_utilisation_tw\n", + " mean_nurse_q_length\n", " \n", " \n", " \n", @@ -442,6 +461,8 @@ " 0.504541\n", " 9.842268\n", " 0.499639\n", + " 0.499740\n", + " 0.128144\n", " \n", " \n", " 1\n", @@ -451,6 +472,8 @@ " 0.514151\n", " 10.060481\n", " 0.501991\n", + " 0.502069\n", + " 0.128347\n", " \n", " \n", " 2\n", @@ -460,6 +483,8 @@ " 0.523235\n", " 9.925025\n", " 0.498130\n", + " 0.498260\n", + " 0.132669\n", " \n", " \n", " 3\n", @@ -469,6 +494,8 @@ " 0.479149\n", " 9.937057\n", " 0.498220\n", + " 0.498269\n", + " 0.120131\n", " \n", " \n", " 4\n", @@ -478,6 +505,8 @@ " 0.461457\n", " 10.015904\n", " 0.496870\n", + " 0.497106\n", + " 0.114510\n", " \n", " \n", "\n", @@ -491,12 +520,12 @@ "3 3 0 10831 0.479149 9.937057 \n", "4 4 0 10720 0.461457 10.015904 \n", "\n", - " mean_nurse_utilisation \n", - "0 0.499639 \n", - "1 0.501991 \n", - "2 0.498130 \n", - "3 0.498220 \n", - "4 0.496870 " + " mean_nurse_utilisation mean_nurse_utilisation_tw mean_nurse_q_length \n", + "0 0.499639 0.499740 0.128144 \n", + "1 0.501991 0.502069 0.128347 \n", + "2 0.498130 0.498260 0.132669 \n", + "3 0.498220 0.498269 0.120131 \n", + "4 0.496870 0.497106 0.114510 " ] }, "metadata": {}, @@ -504,15 +533,14 @@ } ], "source": [ - "display(trial.trial_results_df.head())\n", - "trial.trial_results_df.to_csv(\n", - " os.path.join(output_dir, \"example_trial.csv\"), index=False\n", - ")" + "display(experiment.run_results_df.head())\n", + "experiment.run_results_df.to_csv(\n", + " os.path.join(output_dir, 'example_run.csv'), index=False)" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -615,15 +643,14 @@ } ], "source": [ - "display(trial.interval_audit_df.head())\n", - "trial.interval_audit_df.to_csv(\n", - " os.path.join(output_dir, \"example_interval_audit.csv\"), index=False\n", - ")" + "display(experiment.interval_audit_df.head())\n", + "experiment.interval_audit_df.to_csv(\n", + " os.path.join(output_dir, 'example_interval_audit.csv'), index=False)" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -651,6 +678,8 @@ " mean_q_time_nurse\n", " mean_time_with_nurse\n", " mean_nurse_utilisation\n", + " mean_nurse_utilisation_tw\n", + " mean_nurse_q_length\n", " \n", " \n", " \n", @@ -660,6 +689,8 @@ " 0.499037\n", " 9.978457\n", " 0.497670\n", + " 0.497804\n", + " 0.124599\n", " \n", " \n", " std_dev\n", @@ -667,6 +698,8 @@ " 0.067393\n", " 0.115138\n", " 0.007524\n", + " 0.007541\n", + " 0.017213\n", " \n", " \n", " lower_95_ci\n", @@ -674,6 +707,8 @@ " 0.474317\n", " 9.936224\n", " 0.494910\n", + " 0.495038\n", + " 0.118285\n", " \n", " \n", " upper_95_ci\n", @@ -681,6 +716,8 @@ " 0.523757\n", " 10.020690\n", " 0.500430\n", + " 0.500570\n", + " 0.130912\n", " \n", " \n", "\n", @@ -693,11 +730,17 @@ "lower_95_ci 10734.264952 0.474317 9.936224 \n", "upper_95_ci 10819.218919 0.523757 10.020690 \n", "\n", - " mean_nurse_utilisation \n", - "mean 0.497670 \n", - "std_dev 0.007524 \n", - "lower_95_ci 0.494910 \n", - "upper_95_ci 0.500430 " + " mean_nurse_utilisation mean_nurse_utilisation_tw \\\n", + "mean 0.497670 0.497804 \n", + "std_dev 0.007524 0.007541 \n", + "lower_95_ci 0.494910 0.495038 \n", + "upper_95_ci 0.500430 0.500570 \n", + "\n", + " mean_nurse_q_length \n", + "mean 0.124599 \n", + "std_dev 0.017213 \n", + "lower_95_ci 0.118285 \n", + "upper_95_ci 0.130912 " ] }, "metadata": {}, @@ -705,10 +748,9 @@ } ], "source": [ - "display(trial.overall_results_df.head())\n", - "trial.overall_results_df.to_csv(\n", - " os.path.join(output_dir, \"example_overall.csv\"), index=False\n", - ")" + "display(experiment.overall_results_df.head())\n", + "experiment.overall_results_df.to_csv(\n", + " os.path.join(output_dir, 'example_overall.csv'), index=False)" ] }, { @@ -722,1146 +764,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "type": "histogram", - "x": [ - 10972, - 10784, - 10854, - 10831, - 10720, - 10772, - 10831, - 10781, - 10772, - 10705, - 10927, - 10688, - 11092, - 10640, - 10904, - 10849, - 10719, - 10713, - 10568, - 10707, - 10845, - 10726, - 10618, - 10914, - 10660, - 10685, - 10806, - 10748, - 10589, - 10863, - 10796 - ] - } - ], - "layout": { - "annotations": [ - { - "font": { - "size": 12 - }, - "showarrow": false, - "text": "Select a KPI from the drop down list", - "x": 0, - "xref": "paper", - "y": 1.1, - "yref": "paper" - } - ], - "showlegend": false, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "updatemenus": [ - { - "buttons": [ - { - "args": [ - { - "x": [ - [ - 10972, - 10784, - 10854, - 10831, - 10720, - 10772, - 10831, - 10781, - 10772, - 10705, - 10927, - 10688, - 11092, - 10640, - 10904, - 10849, - 10719, - 10713, - 10568, - 10707, - 10845, - 10726, - 10618, - 10914, - 10660, - 10685, - 10806, - 10748, - 10589, - 10863, - 10796 - ] - ] - }, - { - "xaxis": { - "title": "Patient Arrivals (n)" - } - } - ], - "label": "Patient Arrivals", - "method": "update" - }, - { - "args": [ - { - "x": [ - [ - 0.504541081338615, - 0.514150649003393, - 0.5232349226016817, - 0.4791488631810612, - 0.46145745726579823, - 0.3882646868128185, - 0.4669381081669874, - 0.625888360901447, - 0.4684971326393017, - 0.5634349862001105, - 0.562585969190057, - 0.39781182403365434, - 0.44530362984867583, - 0.4397605749351992, - 0.6107822771635987, - 0.47670998312351787, - 0.428336230071242, - 0.505574486075843, - 0.3615821082986753, - 0.4191589720392036, - 0.6120142008002236, - 0.5173212645251098, - 0.5316566599495316, - 0.5270546197660896, - 0.5029697553047842, - 0.6270646900660448, - 0.5061794260886525, - 0.4925537687951073, - 0.4577189216542841, - 0.5422405738480466, - 0.5102078888697092 - ] - ] - }, - { - "xaxis": { - "title": "Nurse waiting time (minutes)" - } - } - ], - "label": "Nurse waiting time", - "method": "update" - }, - { - "args": [ - { - "x": [ - [ - 9.84226781662332, - 10.060480983450425, - 9.925024519746302, - 9.9370571543943, - 10.015904147971671, - 9.884995942861282, - 10.041799654744745, - 10.086979128063648, - 10.202270228377186, - 10.09260227901333, - 10.083553615426284, - 9.893334037740962, - 9.810905063859671, - 9.933879963761742, - 10.167683587926042, - 9.975581276412813, - 9.809804967118032, - 9.989154604862323, - 9.800182515281657, - 9.9193906381964, - 9.813774247048583, - 9.858186468091487, - 9.969891296475984, - 9.925291785145637, - 9.96454608027881, - 10.236338445072258, - 10.039653295082593, - 10.050997027592315, - 10.044180668559221, - 10.034383892923174, - 9.922063713004379 - ] - ] - }, - { - "xaxis": { - "title": "Patient contact time (minutes)" - } - } - ], - "label": "Patient contact time", - "method": "update" - }, - { - "args": [ - { - "x": [ - [ - 0.4996386466177992, - 0.5019905433327594, - 0.4981297032213408, - 0.49822049332297624, - 0.4968703372055205, - 0.492904233058074, - 0.503356251584998, - 0.5034489381047406, - 0.508790994907774, - 0.49997178325917613, - 0.5098373896503802, - 0.4895233535105571, - 0.5034276977164731, - 0.48925457544062534, - 0.513130373051619, - 0.5009629889699926, - 0.4866947365248423, - 0.4954087210793937, - 0.4793715775153063, - 0.4915291568180775, - 0.49261944375555833, - 0.48940978932654106, - 0.4892835610032433, - 0.5013818263178943, - 0.49160360886911897, - 0.5060501169430693, - 0.5022615440123254, - 0.4999546777219452, - 0.4923573694687436, - 0.5046064549261675, - 0.49578999982774674 - ] - ] - }, - { - "xaxis": { - "title": "Nurse Utilization (%)" - } - } - ], - "label": "Nurse Utilization", - "method": "update" - } - ], - "direction": "down", - "showactive": true - } - ], - "xaxis": { - "title": { - "text": "Patient Arrivals (n)" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "10.6k10.8k11k024681012Patient Arrivals (n)Select a KPI from the drop down listPatient Arrivals" ] }, "metadata": {}, @@ -1871,23 +780,23 @@ "source": [ "# optional name mappings to help user. if excluded then column names used.\n", "name_mappings = {\n", - " \"arrivals\": {\"friendly_name\": \"Patient Arrivals\", \"units\": \"n\"},\n", - " \"mean_q_time_nurse\": {\n", - " \"friendly_name\": \"Nurse waiting time\",\n", - " \"units\": \"minutes\",\n", + " 'arrivals': {'friendly_name': 'Patient Arrivals', 'units': 'n'},\n", + " 'mean_q_time_nurse': {\n", + " 'friendly_name': 'Nurse waiting time',\n", + " 'units': 'minutes',\n", " },\n", - " \"mean_time_with_nurse\": {\n", - " \"friendly_name\": \"Patient contact time\",\n", - " \"units\": \"minutes\",\n", + " 'mean_time_with_nurse': {\n", + " 'friendly_name': 'Patient contact time',\n", + " 'units': 'minutes',\n", " },\n", - " \"mean_nurse_utilisation\": {\n", - " \"friendly_name\": \"Nurse Utilization\",\n", - " \"units\": \"%\",\n", + " 'mean_nurse_utilisation': {\n", + " 'friendly_name': 'Nurse Utilization',\n", + " 'units': '%',\n", " },\n", "}\n", "\n", "create_user_controlled_hist(\n", - " trial.trial_results_df,\n", + " experiment.run_results_df,\n", " exclude_columns=[0, 1],\n", " name_mappings=name_mappings,\n", " include_instruct=True,\n", @@ -1896,7 +805,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -1905,9 +814,6 @@ " Plot spread of results from across replications, for chosen column.\n", " Show figure and save under specified file name.\n", "\n", - " TM patch so that `trial.trial_results_df` is a parameter rather \n", - " than using notebook scope variable.\n", - "\n", " Arguments:\n", " rep_results (pandas.DataFrame)\n", " The dataframe of replication results. \n", @@ -1919,7 +825,11 @@ " Filename to save figure to.\n", " \"\"\"\n", " fig = px.histogram(rep_results[column])\n", - " fig.update_layout(xaxis_title=x_label, yaxis_title=\"Frequency\")\n", + " fig.update_layout(\n", + " xaxis_title=x_label,\n", + " yaxis_title='Frequency',\n", + " template='plotly_white',\n", + " showlegend=False)\n", "\n", " # Show figure\n", " fig.show()\n", @@ -1930,944 +840,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "bingroup": "x", - "hovertemplate": "variable=arrivals
value=%{x}
count=%{y}", - "legendgroup": "arrivals", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "arrivals", - "offsetgroup": "arrivals", - "orientation": "v", - "showlegend": true, - "type": "histogram", - "x": [ - 10972, - 10784, - 10854, - 10831, - 10720, - 10772, - 10831, - 10781, - 10772, - 10705, - 10927, - 10688, - 11092, - 10640, - 10904, - 10849, - 10719, - 10713, - 10568, - 10707, - 10845, - 10726, - 10618, - 10914, - 10660, - 10685, - 10806, - 10748, - 10589, - 10863, - 10796 - ], - "xaxis": "x", - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Arrivals" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Frequency" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "10.5k10.6k10.7k10.8k10.9k11k024681012ArrivalsFrequency" ] }, "metadata": {}, @@ -2875,939 +854,8 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "bingroup": "x", - "hovertemplate": "variable=mean_q_time_nurse
value=%{x}
count=%{y}", - "legendgroup": "mean_q_time_nurse", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "mean_q_time_nurse", - "offsetgroup": "mean_q_time_nurse", - "orientation": "v", - "showlegend": true, - "type": "histogram", - "x": [ - 0.504541081338615, - 0.514150649003393, - 0.5232349226016817, - 0.4791488631810612, - 0.46145745726579823, - 0.3882646868128185, - 0.4669381081669874, - 0.625888360901447, - 0.4684971326393017, - 0.5634349862001105, - 0.562585969190057, - 0.39781182403365434, - 0.44530362984867583, - 0.4397605749351992, - 0.6107822771635987, - 0.47670998312351787, - 0.428336230071242, - 0.505574486075843, - 0.3615821082986753, - 0.4191589720392036, - 0.6120142008002236, - 0.5173212645251098, - 0.5316566599495316, - 0.5270546197660896, - 0.5029697553047842, - 0.6270646900660448, - 0.5061794260886525, - 0.4925537687951073, - 0.4577189216542841, - 0.5422405738480466, - 0.5102078888697092 - ], - "xaxis": "x", - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean wait time for nurse" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Frequency" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "0.350.40.450.50.550.60.650246810Mean wait time for nurseFrequency" ] }, "metadata": {}, @@ -3815,939 +863,8 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "bingroup": "x", - "hovertemplate": "variable=mean_time_with_nurse
value=%{x}
count=%{y}", - "legendgroup": "mean_time_with_nurse", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "mean_time_with_nurse", - "offsetgroup": "mean_time_with_nurse", - "orientation": "v", - "showlegend": true, - "type": "histogram", - "x": [ - 9.84226781662332, - 10.060480983450425, - 9.925024519746302, - 9.9370571543943, - 10.015904147971671, - 9.884995942861282, - 10.041799654744745, - 10.086979128063648, - 10.202270228377186, - 10.09260227901333, - 10.083553615426284, - 9.893334037740962, - 9.810905063859671, - 9.933879963761742, - 10.167683587926042, - 9.975581276412813, - 9.809804967118032, - 9.989154604862323, - 9.800182515281657, - 9.9193906381964, - 9.813774247048583, - 9.858186468091487, - 9.969891296475984, - 9.925291785145637, - 9.96454608027881, - 10.236338445072258, - 10.039653295082593, - 10.050997027592315, - 10.044180668559221, - 10.034383892923174, - 9.922063713004379 - ], - "xaxis": "x", - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean length of nurse consultation" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Frequency" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "9.89.91010.110.20123456789Mean length of nurse consultationFrequency" ] }, "metadata": {}, @@ -4755,939 +872,8 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "bingroup": "x", - "hovertemplate": "variable=mean_nurse_utilisation
value=%{x}
count=%{y}", - "legendgroup": "mean_nurse_utilisation", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "mean_nurse_utilisation", - "offsetgroup": "mean_nurse_utilisation", - "orientation": "v", - "showlegend": true, - "type": "histogram", - "x": [ - 0.4996386466177992, - 0.5019905433327594, - 0.4981297032213408, - 0.49822049332297624, - 0.4968703372055205, - 0.492904233058074, - 0.503356251584998, - 0.5034489381047406, - 0.508790994907774, - 0.49997178325917613, - 0.5098373896503802, - 0.4895233535105571, - 0.5034276977164731, - 0.48925457544062534, - 0.513130373051619, - 0.5009629889699926, - 0.4866947365248423, - 0.4954087210793937, - 0.4793715775153063, - 0.4915291568180775, - 0.49261944375555833, - 0.48940978932654106, - 0.4892835610032433, - 0.5013818263178943, - 0.49160360886911897, - 0.5060501169430693, - 0.5022615440123254, - 0.4999546777219452, - 0.4923573694687436, - 0.5046064549261675, - 0.49578999982774674 - ], - "xaxis": "x", - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean nurse utilisation" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Frequency" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "0.480.490.50.51012345678Mean nurse utilisationFrequency" ] }, "metadata": {}, @@ -5696,31 +882,31 @@ ], "source": [ "plot_results_spread(\n", - " rep_results=trial.trial_results_df,\n", - " column=\"arrivals\", \n", - " x_label=\"Arrivals\", \n", - " file=\"spread_arrivals.png\"\n", + " rep_results=experiment.run_results_df,\n", + " column='arrivals', \n", + " x_label='Arrivals', \n", + " file='spread_arrivals.png'\n", ")\n", "\n", "plot_results_spread(\n", - " rep_results=trial.trial_results_df,\n", - " column=\"mean_q_time_nurse\",\n", - " x_label=\"Mean wait time for nurse\",\n", - " file=\"spread_nurse_wait.png\",\n", + " rep_results=experiment.run_results_df,\n", + " column='mean_q_time_nurse',\n", + " x_label='Mean wait time for nurse',\n", + " file='spread_nurse_wait.png',\n", ")\n", "\n", "plot_results_spread(\n", - " rep_results=trial.trial_results_df,\n", - " column=\"mean_time_with_nurse\",\n", - " x_label=\"Mean length of nurse consultation\",\n", - " file=\"spread_nurse_time.png\",\n", + " rep_results=experiment.run_results_df,\n", + " column='mean_time_with_nurse',\n", + " x_label='Mean length of nurse consultation',\n", + " file='spread_nurse_time.png',\n", ")\n", "\n", "plot_results_spread(\n", - " rep_results=trial.trial_results_df,\n", - " column=\"mean_nurse_utilisation\",\n", - " x_label=\"Mean nurse utilisation\",\n", - " file=\"spread_nurse_util.png\",\n", + " rep_results=experiment.run_results_df,\n", + " column='mean_nurse_utilisation',\n", + " x_label='Mean nurse utilisation',\n", + " file='spread_nurse_util.png',\n", ")" ] }, @@ -5728,52 +914,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Scenario analysis" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "def run_scenarios(scenarios):\n", - " \"\"\"\n", - " Run a set of scenarios and return the scenario-level results.\n", + "## Scenario analysis\n", "\n", - " Arguments:\n", - " scenarios (dict):\n", - " Dictionary where key is name of parameter and value is a list\n", - " with different values to run in scenarios.\n", - " \"\"\"\n", - " # Find every possible permutation of the scenarios\n", - " all_scenarios_tuples = list(itertools.product(*scenarios.values()))\n", - " # Convert back into dictionaries\n", - " all_scenarios_dicts = [\n", - " dict(zip(scenarios.keys(), p)) for p in all_scenarios_tuples\n", - " ]\n", - " # Preview some of the scenarios\n", - " print(f\"There are {len(all_scenarios_dicts)} scenarios. Running:\")\n", - "\n", - " # Run the scenarios...\n", - " results = []\n", - " for index, scenario_to_run in enumerate(all_scenarios_dicts):\n", - " print(scenario_to_run)\n", - "\n", - " # Overwrite defaults from the passed dictionary\n", - " param = Defaults()\n", - " param.scenario_name = index\n", - " for key in scenario_to_run:\n", - " setattr(param, key, scenario_to_run[key])\n", - "\n", - " # Run trial and keep trial-level results, adding the scenario values to\n", - " # the results dataframe\n", - " scenario_trial = Trial(param)\n", - " scenario_trial.run_trial()\n", - " for key in scenario_to_run:\n", - " scenario_trial.trial_results_df[key] = scenario_to_run[key]\n", - " results.append(scenario_trial.trial_results_df)\n", - " return pd.concat(results)" + "We can use the `run_scenarios()` function to run scenarios on the default model, executing it with every possible combination of the specified parameters." ] }, { @@ -5812,7 +955,7 @@ "source": [ "# Run scenarios\n", "scenario_results = run_scenarios(\n", - " {\"patient_inter\": [3, 4, 5, 6, 7], \"number_of_nurses\": [5, 6, 7, 8]}\n", + " {'patient_inter': [3, 4, 5, 6, 7], 'number_of_nurses': [5, 6, 7, 8]}\n", ")" ] }, @@ -5848,6 +991,8 @@ " mean_q_time_nurse\n", " mean_time_with_nurse\n", " mean_nurse_utilisation\n", + " mean_nurse_utilisation_tw\n", + " mean_nurse_q_length\n", " patient_inter\n", " number_of_nurses\n", " \n", @@ -5861,6 +1006,8 @@ " 1.906132\n", " 9.949058\n", " 0.667461\n", + " 0.667636\n", + " 0.639392\n", " 3\n", " 5\n", " \n", @@ -5872,6 +1019,8 @@ " 1.918952\n", " 10.148115\n", " 0.676693\n", + " 0.677008\n", + " 0.640044\n", " 3\n", " 5\n", " \n", @@ -5883,6 +1032,8 @@ " 1.976377\n", " 9.931685\n", " 0.665045\n", + " 0.665109\n", + " 0.661766\n", " 3\n", " 5\n", " \n", @@ -5894,6 +1045,8 @@ " 1.959961\n", " 10.003235\n", " 0.667725\n", + " 0.667792\n", + " 0.655062\n", " 3\n", " 5\n", " \n", @@ -5905,6 +1058,8 @@ " 1.780232\n", " 9.980463\n", " 0.664761\n", + " 0.664891\n", + " 0.592875\n", " 3\n", " 5\n", " \n", @@ -5920,12 +1075,19 @@ "3 3 0 14424 1.959961 10.003235 \n", "4 4 0 14387 1.780232 9.980463 \n", "\n", - " mean_nurse_utilisation patient_inter number_of_nurses \n", - "0 0.667461 3 5 \n", - "1 0.676693 3 5 \n", - "2 0.665045 3 5 \n", - "3 0.667725 3 5 \n", - "4 0.664761 3 5 " + " mean_nurse_utilisation mean_nurse_utilisation_tw mean_nurse_q_length \\\n", + "0 0.667461 0.667636 0.639392 \n", + "1 0.676693 0.677008 0.640044 \n", + "2 0.665045 0.665109 0.661766 \n", + "3 0.667725 0.667792 0.655062 \n", + "4 0.664761 0.664891 0.592875 \n", + "\n", + " patient_inter number_of_nurses \n", + "0 3 5 \n", + "1 3 5 \n", + "2 3 5 \n", + "3 3 5 \n", + "4 3 5 " ] }, "execution_count": 19, @@ -5950,15 +1112,8 @@ "metadata": {}, "outputs": [], "source": [ - "def plot_scenario(\n", - " results,\n", - " x_var,\n", - " result_var,\n", - " colour_var,\n", - " xaxis_title,\n", - " yaxis_title,\n", - " legend_title,\n", - "):\n", + "def plot_scenario(results, x_var, result_var, colour_var, xaxis_title,\n", + " yaxis_title, legend_title):\n", " \"\"\"\n", " Plot results from different model scenarios.\n", "\n", @@ -5992,28 +1147,23 @@ " .apply(pd.Series)\n", " .reset_index()\n", " )\n", - " df.columns = list(df.columns[:-4]) + [\n", - " \"mean\",\n", - " \"std_dev\",\n", - " \"ci_lower\",\n", - " \"ci_upper\",\n", - " ]\n", + " df.columns = (list(df.columns[:-4]) +\n", + " ['mean', 'std_dev', 'ci_lower', 'ci_upper'])\n", "\n", " # Plot mean line\n", - " fig = px.line(df, x=x_var, y=\"mean\", color=colour_var)\n", + " fig = px.line(df, x=x_var, y='mean', color=colour_var)\n", " fig.update_layout(\n", " xaxis_title=xaxis_title,\n", " yaxis_title=yaxis_title,\n", " legend_title_text=legend_title,\n", + " template='plotly_white'\n", " )\n", "\n", " # Plot confidence interval lines\n", - " for ci in [\"ci_upper\", \"ci_lower\"]:\n", - " trace = (\n", - " px.line(df, x=x_var, y=ci, color=colour_var)\n", - " .update_traces(opacity=0.5, showlegend=False)\n", - " .select_traces()\n", - " )\n", + " for ci in ['ci_upper', 'ci_lower']:\n", + " trace = (px.line(df, x=x_var, y=ci, color=colour_var)\n", + " .update_traces(opacity=0.5, showlegend=False)\n", + " .select_traces())\n", " # Add to figure\n", " fig.add_traces(list(trace))\n", "\n", @@ -6034,1278 +1184,8 @@ "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
mean=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 1.846285616686509, - 0.499036905566402, - 0.194497876257302, - 0.09372843902830016, - 0.04938957697913878 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
mean=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.5209908642986794, - 0.12771103309436083, - 0.04427475966483545, - 0.018276596349722098, - 0.007970112406855502 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
mean=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.15588633865729268, - 0.03167317049201888, - 0.00958386104923847, - 0.003532456325865035, - 0.0013379412503489922 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
mean=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.04633029368960636, - 0.007822215694493135, - 0.001918494900705937, - 0.0007798073458787395, - 0.0002570374972292345 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 1.9169425248521754, - 0.5237570297813028, - 0.2056486098939343, - 0.1012766400255499, - 0.05432123323283068 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.5429561524395957, - 0.13665147067462188, - 0.048599598752307765, - 0.021145477001450797, - 0.009465622722952823 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.16477408790387119, - 0.035120185404281336, - 0.011401481662795056, - 0.004702049303971073, - 0.0018910006400875352 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.05001429048579607, - 0.009184602532823655, - 0.002589891135992146, - 0.0012038368091218648, - 0.0004402274375241695 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 1.7756287085208424, - 0.47431678135150124, - 0.1833471426206697, - 0.08618023803105043, - 0.04445792072544688 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.499025576157763, - 0.11877059551409978, - 0.03994992057736313, - 0.015407715697993398, - 0.006474602090758182 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.14699858941071417, - 0.02822615557975642, - 0.0077662404356818844, - 0.0023628633477589967, - 0.0007848818606104493 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.042646296893416646, - 0.0064598288561626156, - 0.0012470986654197283, - 0.0003557778826356141, - 7.38475569342995e-05 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "Nurses" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Patient inter-arrival time" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean wait time for nurse (minutes)" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "3456700.511.52Nurses5678Patient inter-arrival timeMean wait time for nurse (minutes)" ] }, "metadata": {}, @@ -7315,17 +1195,16 @@ "source": [ "result, fig = plot_scenario(\n", " results=scenario_results,\n", - " x_var=\"patient_inter\",\n", - " result_var=\"mean_q_time_nurse\",\n", - " colour_var=\"number_of_nurses\",\n", - " xaxis_title=\"Patient inter-arrival time\",\n", - " yaxis_title=\"Mean wait time for nurse (minutes)\",\n", - " legend_title=\"Nurses\",\n", - ")\n", + " x_var='patient_inter',\n", + " result_var='mean_q_time_nurse',\n", + " colour_var='number_of_nurses',\n", + " xaxis_title='Patient inter-arrival time',\n", + " yaxis_title='Mean wait time for nurse (minutes)',\n", + " legend_title='Nurses')\n", "\n", "fig.show()\n", "\n", - "fig.write_image(os.path.join(output_dir, \"scenario_nurse_wait.png\"))" + "fig.write_image(os.path.join(output_dir, 'scenario_nurse_wait.png'))" ] }, { @@ -7342,1278 +1221,8 @@ "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
mean=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.6631648808967003, - 0.49767035119563796, - 0.3996749025127357, - 0.3330896999785892, - 0.28578397443647 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
mean=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.5526433836201494, - 0.4147299909091962, - 0.33306573632813413, - 0.2775742508735594, - 0.2381519421139213 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
mean=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.4736994683790893, - 0.355484213624623, - 0.2854853321983711, - 0.23792078646305095, - 0.20413023609764683 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
mean=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.41448870138132116, - 0.3110493156249044, - 0.24979966567357464, - 0.20818068815516955, - 0.17861395658544094 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.6663216731194718, - 0.5004303474716477, - 0.4020643907650562, - 0.33476508901100027, - 0.28732862850808133 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.5552768316790022, - 0.41703074200388013, - 0.3350569007886222, - 0.2789706828159496, - 0.2394393487693585 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.4759564748237934, - 0.35745649018143, - 0.2871921279442676, - 0.23911772812795684, - 0.205233727516593 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
ci_upper=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.41646364586365403, - 0.31277508414642846, - 0.2512931119512341, - 0.20922801211196218, - 0.17957951157701885 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=5
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "5", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "5", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.6600080886739289, - 0.4949103549196282, - 0.3972854142604152, - 0.3314143109461782, - 0.2842393203648587 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=6
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "6", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "6", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.5500099355612966, - 0.4124292398145123, - 0.33107457186764605, - 0.2761778189311692, - 0.2368645354584841 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=7
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "7", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "7", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.47144246193438516, - 0.35351193706781603, - 0.2837785364524746, - 0.23672384479814507, - 0.20302674467870066 - ], - "yaxis": "y" - }, - { - "hovertemplate": "number_of_nurses=8
patient_inter=%{x}
ci_lower=%{y}", - "legendgroup": "8", - "line": { - "color": "#ab63fa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "8", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 3, - 4, - 5, - 6, - 7 - ], - "xaxis": "x", - "y": [ - 0.4125137568989883, - 0.30932354710338034, - 0.2483062193959152, - 0.2071333641983769, - 0.17764840159386303 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "Nurses" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Patient inter-arrival time" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean nurse utilisation" - } - } - } - }, - "text/html": [ - "
" + "image/svg+xml": [ + "345670.20.30.40.50.6Nurses5678Patient inter-arrival timeMean nurse utilisation" ] }, "metadata": {}, @@ -8623,17 +1232,16 @@ "source": [ "result, fig = plot_scenario(\n", " results=scenario_results,\n", - " x_var=\"patient_inter\",\n", - " result_var=\"mean_nurse_utilisation\",\n", - " colour_var=\"number_of_nurses\",\n", - " xaxis_title=\"Patient inter-arrival time\",\n", - " yaxis_title=\"Mean nurse utilisation\",\n", - " legend_title=\"Nurses\",\n", - ")\n", + " x_var='patient_inter',\n", + " result_var='mean_nurse_utilisation',\n", + " colour_var='number_of_nurses',\n", + " xaxis_title='Patient inter-arrival time',\n", + " yaxis_title='Mean nurse utilisation',\n", + " legend_title='Nurses')\n", "\n", "fig.show()\n", "\n", - "fig.write_image(os.path.join(output_dir, \"scenario_nurse_util.png\"))" + "fig.write_image(os.path.join(output_dir, 'scenario_nurse_util.png'))" ] }, { @@ -8672,24 +1280,23 @@ "table = result.copy()\n", "\n", "# Combine mean and CI into single column, and round\n", - "table[\"mean_ci\"] = table.apply(\n", - " lambda row: f\"{row['mean']:.2f} ({row['ci_lower']:.2f}, {row['ci_upper']:.2f})\",\n", - " axis=1,\n", + "table['mean_ci'] = table.apply(\n", + " lambda row:\n", + " f'{row['mean']:.2f} ({row['ci_lower']:.2f}, {row['ci_upper']:.2f})', axis=1\n", ")\n", "\n", "# Convert from long to wide format\n", "table = (\n", - " table.pivot(\n", - " index=\"patient_inter\", columns=\"number_of_nurses\", values=\"mean_ci\"\n", - " )\n", - " .rename_axis(\"Patient inter-arrival time\", axis=\"index\")\n", - " .rename_axis(\"Number of nurses\", axis=\"columns\")\n", + " table\n", + " .pivot(index='patient_inter', columns='number_of_nurses', values='mean_ci')\n", + " .rename_axis('Patient inter-arrival time', axis='index')\n", + " .rename_axis('Number of nurses', axis='columns')\n", ")\n", "\n", "# Convert to latex, display and save\n", "table_latex = table.to_latex()\n", "print(table_latex)\n", - "with open(os.path.join(output_dir, \"scenario_nurse_util.tex\"), \"w\") as tf:\n", + "with open(os.path.join(output_dir, 'scenario_nurse_util.tex'), 'w') as tf:\n", " tf.write(table_latex)" ] }, @@ -8731,7 +1338,7 @@ "source": [ "# Run scenarios\n", "sensitivity_consult = run_scenarios(\n", - " {\"mean_n_consult_time\": [8, 9, 10, 11, 12, 13, 14, 15]}\n", + " {'mean_n_consult_time': [8, 9, 10, 11, 12, 13, 14, 15]}\n", ")" ] }, @@ -8742,1003 +1349,8 @@ "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "mean_n_consult_time=%{x}
mean=%{y}", - "legendgroup": "", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "", - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15 - ], - "xaxis": "x", - "y": [ - 0.15117881736778396, - 0.28394136348868726, - 0.499036905566402, - 0.8385104727236156, - 1.355692289891784, - 2.1482656075001905, - 3.3720354896743534, - 5.303240505365226 - ], - "yaxis": "y" - }, - { - "hovertemplate": "mean_n_consult_time=%{x}
ci_upper=%{y}", - "legendgroup": "", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15 - ], - "xaxis": "x", - "y": [ - 0.15983016146041065, - 0.2991290227720832, - 0.5237570297813028, - 0.87899921832706, - 1.4189265664774497, - 2.2439600794885455, - 3.520325590336425, - 5.544361101434637 - ], - "yaxis": "y" - }, - { - "hovertemplate": "mean_n_consult_time=%{x}
ci_lower=%{y}", - "legendgroup": "", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "", - "opacity": 0.5, - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15 - ], - "xaxis": "x", - "y": [ - 0.14252747327515727, - 0.2687537042052913, - 0.47431678135150124, - 0.7980217271201712, - 1.2924580133061183, - 2.0525711355118355, - 3.223745389012282, - 5.062119909295815 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "Nurses" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean nurse consultation time (minutes)" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Mean wait time for nurse (minutes)" - } - } - } - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApwAAAFoCAYAAAD6oCs3AAAgAElEQVR4XuydB3xb1fXHj+Qdb2fvBDLJHhAIDYS9RyDs0QAJLaPsMkrLaNmj7BaaQsJuKHslrBLgT1iZZO/tJLYT721L/3Puk2zZsnX1fC3Hz/7d1h8b694Xv5+O7K/OdHl5ERYUgAJQAApAASgABaAAFIiQAi4AZ4SUxWWhABSAAlAACkABKAAFlAIAThgCFIACUAAKQAEoAAWgQEQVAHBGVF5cHApAASgABaAAFIACUADACRuAAlAACkABKAAFoAAUiKgCAM6IyouLQwEoAAWgABSAAlAACgA4YQNQAApAASgABaAAFIACEVUAwBlReXFxKAAFoAAUgAJQAApAAQAnbAAKQAEoAAWgABSAAlAgogoAOCMqLy4OBaAAFIACUAAKQAEoAOCEDUABKAAFoAAUgAJQAApEVAEAZ0TlxcWhABSAAlAACkABKAAFAJywASgABaAAFIACUAAKQIGIKgDgjKi8uDgUgAJQAApAASgABaAAgBM2AAWgABSAAlAACkABKBBRBQCcEZUXF4cCUAAKQAEoAAWgABQAcMIGoAAUgAJQAApAASgABSKqAIAzovLi4lAACkABKAAFoAAUgAIATtgAFIACUAAKQAEoAAWgQEQVAHBGVF5cHApAASgABaAAFIACUADACRuAAlAACkABKAAFoAAUiKgCAM6IyouLQwEoAAWgABSAAlAACgA4YQNQAApAASgABaAAFIACEVUAwBlReXFxKAAFoAAUgAJQAApAAQAnbAAKQAEoAAWgABSAAlAgogoAOCMqLy4OBaAAFIACUAAKQAEoAOCEDUABKAAFoAAUgAJQAApEVAEAZ0TlxcWhABSAAlAACkABKAAFAJywASgABaAAFIACUAAKQIGIKgDgjKi8uDgUgAJQAApAASgABaAAgBM2AAWgABSAAlAACkABKBBRBQCcEZUXF4cCUAAKQAEoAAWgABQAcMIGoAAUgAJQAApAASgABSKqAIAzovLi4lAACkABKAAFoAAUgAIATtgAFIACUAAKQAEoAAWgQEQVAHBGVF5cHApAASgABaAAFIACUADACRuAAlAACkABKAAFoAAUiKgCAM6IyouLQwEoAAWgABSAAlAACgA4YQNQAApAASgABaAAFIACEVUAwBlReXFxKAAF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", - "text/html": [ - "
" + "image/svg+xml": [ + "89101112131415012345Mean nurse consultation time (minutes)Mean wait time for nurse (minutes)" ] }, "metadata": {}, @@ -9748,17 +1360,17 @@ "source": [ "result, fig = plot_scenario(\n", " results=sensitivity_consult,\n", - " x_var=\"mean_n_consult_time\",\n", - " result_var=\"mean_q_time_nurse\",\n", + " x_var='mean_n_consult_time',\n", + " result_var='mean_q_time_nurse',\n", " colour_var=None,\n", - " xaxis_title=\"Mean nurse consultation time (minutes)\",\n", - " yaxis_title=\"Mean wait time for nurse (minutes)\",\n", - " legend_title=\"Nurses\",\n", + " xaxis_title='Mean nurse consultation time (minutes)',\n", + " yaxis_title='Mean wait time for nurse (minutes)',\n", + " legend_title='Nurses',\n", ")\n", "\n", "fig.show()\n", "\n", - "fig.write_image(os.path.join(output_dir, \"sensitivity_consult_time.png\"))" + "fig.write_image(os.path.join(output_dir, 'sensitivity_consult_time.png'))" ] }, { @@ -9792,22 +1404,22 @@ "table = result.copy()\n", "\n", "# Combine mean and CI into single column, and round\n", - "table[\"mean_ci\"] = table.apply(\n", - " lambda row: f\"{row['mean']:.2f} ({row['ci_lower']:.2f}, {row['ci_upper']:.2f})\",\n", - " axis=1,\n", + "table['mean_ci'] = table.apply(\n", + " lambda row:\n", + " f'{row['mean']:.2f} ({row['ci_lower']:.2f}, {row['ci_upper']:.2f})', axis=1\n", ")\n", "\n", "# Select relevant columns and rename\n", "cols = {\n", - " \"mean_n_consult_time\": \"Mean nurse consultation time\",\n", - " \"mean_ci\": \"Mean wait time for nurse (95 percent confidence interval)\",\n", + " 'mean_n_consult_time': 'Mean nurse consultation time',\n", + " 'mean_ci': 'Mean wait time for nurse (95 percent confidence interval)'\n", "}\n", "table = table[cols.keys()].rename(columns=cols)\n", "\n", "# Convert to latex, display and save\n", "table_latex = table.to_latex()\n", "print(table_latex)\n", - "with open(os.path.join(output_dir, \"sensitivity_consult_time.tex\"), \"w\") as tf:\n", + "with open(os.path.join(output_dir, 'sensitivity_consult_time.tex'), 'w') as tf:\n", " tf.write(table_latex)" ] }, @@ -9915,9 +1527,9 @@ "source": [ "param = Defaults()\n", "param.patient_inter = 2\n", - "trial = Trial(param)\n", - "trial.run_trial()\n", - "trial.patient_results_df.tail()" + "nan_experiment = Runner(param)\n", + "nan_experiment.run_reps()\n", + "nan_experiment.patient_results_df.tail()" ] }, { @@ -9942,70 +1554,73 @@ "name": "stdout", "output_type": "stream", "text": [ - "2025-01-24 17:33:23,382 - INFO - logging.py:log():128 - Initialised model: {'param': , 'run_number': 0, 'env': , 'nurse': , 'patients': [], 'nurse_time_used': 0, 'nurse_consult_count': 0, 'running_mean_nurse_wait': 0, 'audit_list': [], 'results_list': [], 'patient_inter_arrival_dist': , 'nurse_consult_time_dist': }\n", - "2025-01-24 17:33:23,382 - INFO - logging.py:log():128 - Parameters: {'_initialising': False, 'patient_inter': 4, 'mean_n_consult_time': 10, 'number_of_nurses': 5, 'warm_up_period': 50, 'data_collection_period': 100, 'number_of_runs': 1, 'audit_interval': 120, 'scenario_name': 0, 'cores': 0, 'logger': }\n", - "2025-01-24 17:33:23,383 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 0.000\n", - "2025-01-24 17:33:23,383 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 0.000 minutes. Consultation length: 8.031 minutes.\n", - "2025-01-24 17:33:23,383 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 13.174\n", - "2025-01-24 17:33:23,384 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 13.174 minutes. Consultation length: 3.820 minutes.\n", - "2025-01-24 17:33:23,384 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 16.227\n", - "2025-01-24 17:33:23,385 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 16.227 minutes. Consultation length: 3.642 minutes.\n", - "2025-01-24 17:33:23,385 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 21.236\n", - "2025-01-24 17:33:23,386 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 21.236 minutes. Consultation length: 5.295 minutes.\n", - "2025-01-24 17:33:23,386 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 22.140\n", - "2025-01-24 17:33:23,386 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 22.140 minutes. Consultation length: 27.884 minutes.\n", - "2025-01-24 17:33:23,386 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 23.023\n", - "2025-01-24 17:33:23,387 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 23.023 minutes. Consultation length: 19.610 minutes.\n", - "2025-01-24 17:33:23,387 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 30.223\n", - "2025-01-24 17:33:23,387 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 30.223 minutes. Consultation length: 9.490 minutes.\n", - "2025-01-24 17:33:23,387 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 30.487\n", - "2025-01-24 17:33:23,388 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 30.487 minutes. Consultation length: 41.665 minutes.\n", - "2025-01-24 17:33:23,388 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 34.089\n", - "2025-01-24 17:33:23,389 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 34.089 minutes. Consultation length: 5.874 minutes.\n", - "2025-01-24 17:33:23,389 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 35.270\n", - "2025-01-24 17:33:23,389 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 35.270 minutes. Consultation length: 27.882 minutes.\n", - "2025-01-24 17:33:23,389 - INFO - logging.py:log():128 - Patient X (warm-up) arrives at: 44.470\n", - "2025-01-24 17:33:23,390 - INFO - logging.py:log():128 - Patient X (warm-up) is seen by nurse after 44.470 minutes. Consultation length: 24.915 minutes.\n", - "2025-01-24 17:33:23,390 - INFO - logging.py:log():128 - Patient 1 arrives at: 51.904\n", - "2025-01-24 17:33:23,390 - INFO - logging.py:log():128 - Patient 1 is seen by nurse after 51.904 minutes. Consultation length: 18.079 minutes.\n", - "2025-01-24 17:33:23,390 - INFO - logging.py:log():128 - Patient 2 arrives at: 51.963\n", - "2025-01-24 17:33:23,391 - INFO - logging.py:log():128 - Patient 2 is seen by nurse after 51.963 minutes. Consultation length: 3.102 minutes.\n", - "2025-01-24 17:33:23,391 - INFO - logging.py:log():128 - Patient 3 arrives at: 74.349\n", - "2025-01-24 17:33:23,391 - INFO - logging.py:log():128 - Patient 3 is seen by nurse after 74.349 minutes. Consultation length: 26.745 minutes.\n", - "2025-01-24 17:33:23,392 - INFO - logging.py:log():128 - Patient 4 arrives at: 77.534\n", - "2025-01-24 17:33:23,392 - INFO - logging.py:log():128 - Patient 4 is seen by nurse after 77.534 minutes. Consultation length: 0.748 minutes.\n", - "2025-01-24 17:33:23,393 - INFO - logging.py:log():128 - Patient 5 arrives at: 78.932\n", - "2025-01-24 17:33:23,393 - INFO - logging.py:log():128 - Patient 5 is seen by nurse after 78.932 minutes. Consultation length: 0.528 minutes.\n", - "2025-01-24 17:33:23,393 - INFO - logging.py:log():128 - Patient 6 arrives at: 86.815\n", - "2025-01-24 17:33:23,393 - INFO - logging.py:log():128 - Patient 6 is seen by nurse after 86.815 minutes. Consultation length: 2.435 minutes.\n", - "2025-01-24 17:33:23,394 - INFO - logging.py:log():128 - Patient 7 arrives at: 89.783\n", - "2025-01-24 17:33:23,394 - INFO - logging.py:log():128 - Patient 7 is seen by nurse after 89.783 minutes. Consultation length: 9.666 minutes.\n", - "2025-01-24 17:33:23,394 - INFO - logging.py:log():128 - Patient 8 arrives at: 89.807\n", - "2025-01-24 17:33:23,394 - INFO - logging.py:log():128 - Patient 8 is seen by nurse after 89.807 minutes. Consultation length: 7.005 minutes.\n", - "2025-01-24 17:33:23,395 - INFO - logging.py:log():128 - Patient 9 arrives at: 93.118\n", - "2025-01-24 17:33:23,395 - INFO - logging.py:log():128 - Patient 9 is seen by nurse after 93.118 minutes. Consultation length: 20.185 minutes.\n", - "2025-01-24 17:33:23,395 - INFO - logging.py:log():128 - Patient 10 arrives at: 95.598\n", - "2025-01-24 17:33:23,395 - INFO - logging.py:log():128 - Patient 10 is seen by nurse after 95.598 minutes. Consultation length: 7.651 minutes.\n", - "2025-01-24 17:33:23,395 - INFO - logging.py:log():128 - Patient 11 arrives at: 98.019\n", - "2025-01-24 17:33:23,396 - INFO - logging.py:log():128 - Patient 11 is seen by nurse after 98.019 minutes. Consultation length: 27.908 minutes.\n", - "2025-01-24 17:33:23,396 - INFO - logging.py:log():128 - Patient 12 arrives at: 109.379\n", - "2025-01-24 17:33:23,396 - INFO - logging.py:log():128 - Patient 12 is seen by nurse after 109.379 minutes. Consultation length: 16.811 minutes.\n", - "2025-01-24 17:33:23,396 - INFO - logging.py:log():128 - Patient 13 arrives at: 110.322\n", - "2025-01-24 17:33:23,397 - INFO - logging.py:log():128 - Patient 13 is seen by nurse after 110.322 minutes. Consultation length: 24.157 minutes.\n", - "2025-01-24 17:33:23,397 - INFO - logging.py:log():128 - Patient 14 arrives at: 120.342\n", - "2025-01-24 17:33:23,397 - INFO - logging.py:log():128 - Patient 14 is seen by nurse after 120.342 minutes. Consultation length: 1.451 minutes.\n", - "2025-01-24 17:33:23,397 - INFO - logging.py:log():128 - Patient 15 arrives at: 121.643\n", - "2025-01-24 17:33:23,397 - INFO - logging.py:log():128 - Patient 15 is seen by nurse after 121.643 minutes. Consultation length: 1.343 minutes.\n", - "2025-01-24 17:33:23,398 - INFO - logging.py:log():128 - Patient 16 arrives at: 127.827\n", - "2025-01-24 17:33:23,398 - INFO - logging.py:log():128 - Patient 16 is seen by nurse after 127.827 minutes. Consultation length: 1.554 minutes.\n", - "2025-01-24 17:33:23,398 - INFO - logging.py:log():128 - Patient 17 arrives at: 132.055\n", - "2025-01-24 17:33:23,398 - INFO - logging.py:log():128 - Patient 17 is seen by nurse after 132.055 minutes. Consultation length: 15.623 minutes.\n", - "2025-01-24 17:33:23,399 - INFO - logging.py:log():128 - Patient 18 arrives at: 133.617\n", - "2025-01-24 17:33:23,399 - INFO - logging.py:log():128 - Patient 18 is seen by nurse after 133.617 minutes. Consultation length: 4.688 minutes.\n", - "2025-01-24 17:33:23,399 - INFO - logging.py:log():128 - Patient 19 arrives at: 136.346\n", - "2025-01-24 17:33:23,400 - INFO - logging.py:log():128 - Patient 19 is seen by nurse after 136.346 minutes. Consultation length: 2.612 minutes.\n", - "2025-01-24 17:33:23,400 - INFO - logging.py:log():128 - Patient 20 arrives at: 144.142\n", - "2025-01-24 17:33:23,400 - INFO - logging.py:log():128 - Patient 20 is seen by nurse after 144.142 minutes. Consultation length: 6.348 minutes.\n" + "2025-01-29 13:39:29,576 - INFO - logging.py:log():128 - Initialised model: {'param': , 'run_number': 0, 'env': , 'nurse': , 'patients': [], 'nurse_time_used': 0, 'nurse_consult_count': 0, 'running_mean_nurse_wait': 0, 'audit_list': [], 'results_list': [], 'patient_inter_arrival_dist': , 'nurse_consult_time_dist': }\n", + "2025-01-29 13:39:29,577 - INFO - logging.py:log():128 - Parameters: {'_initialising': False, 'patient_inter': 4, 'mean_n_consult_time': 10, 'number_of_nurses': 5, 'warm_up_period': 50, 'data_collection_period': 100, 'number_of_runs': 1, 'audit_interval': 120, 'scenario_name': 0, 'cores': 0, 'logger': }\n", + "2025-01-29 13:39:29,577 - INFO - logging.py:log():128 - Patient 1 arrives at: 0.000\n", + "2025-01-29 13:39:29,577 - INFO - logging.py:log():128 - Patient 1 is seen by nurse after 0.000 minutes. Consultation length: 8.031 minutes.\n", + "2025-01-29 13:39:29,578 - INFO - logging.py:log():128 - Patient 2 arrives at: 13.174\n", + "2025-01-29 13:39:29,578 - INFO - logging.py:log():128 - Patient 2 is seen by nurse after 13.174 minutes. Consultation length: 3.820 minutes.\n", + "2025-01-29 13:39:29,578 - INFO - logging.py:log():128 - Patient 3 arrives at: 16.227\n", + "2025-01-29 13:39:29,578 - INFO - logging.py:log():128 - Patient 3 is seen by nurse after 16.227 minutes. Consultation length: 3.642 minutes.\n", + "2025-01-29 13:39:29,578 - INFO - logging.py:log():128 - Patient 4 arrives at: 21.236\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 4 is seen by nurse after 21.236 minutes. Consultation length: 5.295 minutes.\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 5 arrives at: 22.140\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 5 is seen by nurse after 22.140 minutes. Consultation length: 27.884 minutes.\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 6 arrives at: 23.023\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 6 is seen by nurse after 23.023 minutes. Consultation length: 19.610 minutes.\n", + "2025-01-29 13:39:29,579 - INFO - logging.py:log():128 - Patient 7 arrives at: 30.223\n", + "2025-01-29 13:39:29,580 - INFO - logging.py:log():128 - Patient 7 is seen by nurse after 30.223 minutes. Consultation length: 9.490 minutes.\n", + "2025-01-29 13:39:29,580 - INFO - logging.py:log():128 - Patient 8 arrives at: 30.487\n", + "2025-01-29 13:39:29,580 - INFO - logging.py:log():128 - Patient 8 is seen by nurse after 30.487 minutes. Consultation length: 41.665 minutes.\n", + "2025-01-29 13:39:29,580 - INFO - logging.py:log():128 - Patient 9 arrives at: 34.089\n", + "2025-01-29 13:39:29,580 - INFO - logging.py:log():128 - Patient 9 is seen by nurse after 34.089 minutes. Consultation length: 5.874 minutes.\n", + "2025-01-29 13:39:29,581 - INFO - logging.py:log():128 - Patient 10 arrives at: 35.270\n", + "2025-01-29 13:39:29,581 - INFO - logging.py:log():128 - Patient 10 is seen by nurse after 35.270 minutes. Consultation length: 27.882 minutes.\n", + "2025-01-29 13:39:29,581 - INFO - logging.py:log():128 - Patient 11 arrives at: 44.470\n", + "2025-01-29 13:39:29,581 - INFO - logging.py:log():128 - Patient 11 is seen by nurse after 44.470 minutes. Consultation length: 24.915 minutes.\n", + "2025-01-29 13:39:29,582 - INFO - logging.py:log():128 - ──────────\n", + "2025-01-29 13:39:29,582 - INFO - logging.py:log():128 - 50.00: Warm up complete.\n", + "2025-01-29 13:39:29,582 - INFO - logging.py:log():128 - ──────────\n", + "2025-01-29 13:39:29,582 - INFO - logging.py:log():128 - Patient 1 arrives at: 51.904\n", + "2025-01-29 13:39:29,582 - INFO - logging.py:log():128 - Patient 1 is seen by nurse after 51.904 minutes. Consultation length: 18.079 minutes.\n", + "2025-01-29 13:39:29,583 - INFO - logging.py:log():128 - Patient 2 arrives at: 51.963\n", + "2025-01-29 13:39:29,583 - INFO - logging.py:log():128 - Patient 2 is seen by nurse after 51.963 minutes. Consultation length: 3.102 minutes.\n", + "2025-01-29 13:39:29,583 - INFO - logging.py:log():128 - Patient 3 arrives at: 74.349\n", + "2025-01-29 13:39:29,583 - INFO - logging.py:log():128 - Patient 3 is seen by nurse after 74.349 minutes. Consultation length: 26.745 minutes.\n", + "2025-01-29 13:39:29,583 - INFO - logging.py:log():128 - Patient 4 arrives at: 77.534\n", + "2025-01-29 13:39:29,584 - INFO - logging.py:log():128 - Patient 4 is seen by nurse after 77.534 minutes. Consultation length: 0.748 minutes.\n", + "2025-01-29 13:39:29,584 - INFO - logging.py:log():128 - Patient 5 arrives at: 78.932\n", + "2025-01-29 13:39:29,584 - INFO - logging.py:log():128 - Patient 5 is seen by nurse after 78.932 minutes. Consultation length: 0.528 minutes.\n", + "2025-01-29 13:39:29,584 - INFO - logging.py:log():128 - Patient 6 arrives at: 86.815\n", + "2025-01-29 13:39:29,584 - INFO - logging.py:log():128 - Patient 6 is seen by nurse after 86.815 minutes. Consultation length: 2.435 minutes.\n", + "2025-01-29 13:39:29,585 - INFO - logging.py:log():128 - Patient 7 arrives at: 89.783\n", + "2025-01-29 13:39:29,585 - INFO - logging.py:log():128 - Patient 7 is seen by nurse after 89.783 minutes. Consultation length: 9.666 minutes.\n", + "2025-01-29 13:39:29,585 - INFO - logging.py:log():128 - Patient 8 arrives at: 89.807\n", + "2025-01-29 13:39:29,585 - INFO - logging.py:log():128 - Patient 8 is seen by nurse after 89.807 minutes. Consultation length: 7.005 minutes.\n", + "2025-01-29 13:39:29,585 - INFO - logging.py:log():128 - Patient 9 arrives at: 93.118\n", + "2025-01-29 13:39:29,586 - INFO - logging.py:log():128 - Patient 9 is seen by nurse after 93.118 minutes. Consultation length: 20.185 minutes.\n", + "2025-01-29 13:39:29,586 - INFO - logging.py:log():128 - Patient 10 arrives at: 95.598\n", + "2025-01-29 13:39:29,586 - INFO - logging.py:log():128 - Patient 10 is seen by nurse after 95.598 minutes. Consultation length: 7.651 minutes.\n", + "2025-01-29 13:39:29,587 - INFO - logging.py:log():128 - Patient 11 arrives at: 98.019\n", + "2025-01-29 13:39:29,587 - INFO - logging.py:log():128 - Patient 11 is seen by nurse after 98.019 minutes. Consultation length: 27.908 minutes.\n", + "2025-01-29 13:39:29,587 - INFO - logging.py:log():128 - Patient 12 arrives at: 109.379\n", + "2025-01-29 13:39:29,587 - INFO - logging.py:log():128 - Patient 12 is seen by nurse after 109.379 minutes. Consultation length: 16.811 minutes.\n", + "2025-01-29 13:39:29,587 - INFO - logging.py:log():128 - Patient 13 arrives at: 110.322\n", + "2025-01-29 13:39:29,588 - INFO - logging.py:log():128 - Patient 13 is seen by nurse after 110.322 minutes. Consultation length: 24.157 minutes.\n", + "2025-01-29 13:39:29,588 - INFO - logging.py:log():128 - Patient 14 arrives at: 120.342\n", + "2025-01-29 13:39:29,588 - INFO - logging.py:log():128 - Patient 14 is seen by nurse after 120.342 minutes. Consultation length: 1.451 minutes.\n", + "2025-01-29 13:39:29,588 - INFO - logging.py:log():128 - Patient 15 arrives at: 121.643\n", + "2025-01-29 13:39:29,588 - INFO - logging.py:log():128 - Patient 15 is seen by nurse after 121.643 minutes. Consultation length: 1.343 minutes.\n", + "2025-01-29 13:39:29,589 - INFO - logging.py:log():128 - Patient 16 arrives at: 127.827\n", + "2025-01-29 13:39:29,589 - INFO - logging.py:log():128 - Patient 16 is seen by nurse after 127.827 minutes. Consultation length: 1.554 minutes.\n", + "2025-01-29 13:39:29,589 - INFO - logging.py:log():128 - Patient 17 arrives at: 132.055\n", + "2025-01-29 13:39:29,589 - INFO - logging.py:log():128 - Patient 17 is seen by nurse after 132.055 minutes. Consultation length: 15.623 minutes.\n", + "2025-01-29 13:39:29,589 - INFO - logging.py:log():128 - Patient 18 arrives at: 133.617\n", + "2025-01-29 13:39:29,590 - INFO - logging.py:log():128 - Patient 18 is seen by nurse after 133.617 minutes. Consultation length: 4.688 minutes.\n", + "2025-01-29 13:39:29,590 - INFO - logging.py:log():128 - Patient 19 arrives at: 136.346\n", + "2025-01-29 13:39:29,590 - INFO - logging.py:log():128 - Patient 19 is seen by nurse after 136.346 minutes. Consultation length: 2.612 minutes.\n", + "2025-01-29 13:39:29,590 - INFO - logging.py:log():128 - Patient 20 arrives at: 144.142\n", + "2025-01-29 13:39:29,590 - INFO - logging.py:log():128 - Patient 20 is seen by nurse after 144.142 minutes. Consultation length: 6.348 minutes.\n" ] } ], @@ -10155,13 +1770,13 @@ "runtime = round(end_time - start_time)\n", "\n", "# Display converted to minutes and seconds\n", - "print(f\"Notebook run time: {runtime // 60}m {runtime % 60}s\")" + "print(f'Notebook run time: {runtime // 60}m {runtime % 60}s')" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "template-des", "language": "python", "name": "python3" }, diff --git a/notebooks/changes.md b/notebooks/changes.md deleted file mode 100644 index 5b65c4c..0000000 --- a/notebooks/changes.md +++ /dev/null @@ -1,10 +0,0 @@ -## Added - -* `analysis.ipynb`: Added `create_user_controlled_hist` to allow users to decide the KPI histogram to view. - -## Changed - -* `analysis.ipynb`: modified `plot_results_spread` to accept `DataFrame` parameter containing results rather than using a variable with notebook scope. -* `environment.yaml`: patched to include channel. It now installs correctly -* `environment.yaml`: added `nbqa` and `black` to auto-format notebooks. -* `environment.yaml`: added `jinja2` upgraded from 3.1.4 to 3.1.5 due to dependabot security flag. \ No newline at end of file diff --git a/notebooks/choosing_parameters.ipynb b/notebooks/choosing_parameters.ipynb index 44d707e..23e89c6 100644 --- a/notebooks/choosing_parameters.ipynb +++ b/notebooks/choosing_parameters.ipynb @@ -11,19 +11,20 @@ "* Length of warm-up period\n", "* Number of replications\n", "* Number of CPU cores\n", - "* Sampling distributions\n", "\n", "The run time is provided at the end of the notebook.\n", "\n", + "\n", + "\n", "Credit:\n", "\n", - "* Code for choice of warm-up period, replication number and distributions was adapted from Tom Monks (2024) [HPDM097 - Making a difference with health data](https://github.com/health-data-science-OR/stochastic_systems) (MIT License).\n", + "* Code for choice of warm-up period and replication number was adapted from Tom Monks (2024) [HPDM097 - Making a difference with health data](https://github.com/health-data-science-OR/stochastic_systems) (MIT Licence).\n", "* Code for running the model with a varying number of CPU cores was adapted from Sammi Rosser and Dan Chalk (2024) [HSMA - the\n", - " little book of DES](https://github.com/hsma-programme/hsma6_des_book) (MIT License).\n", + " little book of DES](https://github.com/hsma-programme/hsma6_des_book) (MIT Licence).\n", "\n", - "License:\n", + "Licence:\n", "\n", - "* This project is licensed under the MIT License. See the `LICENSE` file for more details." + "* This project is licensed under the MIT Licence. See the `LICENSE` file for more details." ] }, { @@ -79,11 +80,16 @@ "metadata": {}, "outputs": [], "source": [ - "from simulation.model import Defaults, Trial, summary_stats\n", - "import time\n", + "from simulation.model import Defaults, Runner, summary_stats\n", + "\n", "from IPython.display import display\n", + "import os\n", "import pandas as pd\n", "import plotly.express as px\n", + "import plotly.io as pio\n", + "import plotly.graph_objects as go\n", + "import plotly.subplots as sp\n", + "import time\n", "import warnings" ] }, @@ -91,7 +97,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Start timer." + "Display plotly express figures as non-interactive figures. This means they will be visible when browsing the notebooks on GitHub. To switch these back to interactive figures, simply remove this line." ] }, { @@ -99,10 +105,42 @@ "execution_count": 5, "metadata": {}, "outputs": [], + "source": [ + "pio.renderers.default = 'svg'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start timer." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], "source": [ "notebook_start_time = time.time()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define path to outputs folder" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "output_dir = '../outputs/'" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -118,15 +156,17 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "def time_series_inspection(data_collection_period, warm_up=None):\n", + "def time_series_inspection(file, data_collection_period, warm_up=None):\n", " \"\"\"\n", " Time series inspection method for determining length of warm-up.\n", "\n", " Arguments:\n", + " file (str):\n", + " Filename to save figure to.\n", " data_collection_period (float):\n", " Length of time to run the simulation for.\n", " warm_up (float, optional):\n", @@ -142,8 +182,8 @@ " # display(param.__dict__)\n", "\n", " # Run model\n", - " choose_warmup = Trial(param)\n", - " choose_warmup.run_trial()\n", + " choose_warmup = Runner(param)\n", + " choose_warmup.run_reps()\n", "\n", " # Filter to nurse results\n", " nurse = choose_warmup.interval_audit_df[\n", @@ -154,6 +194,11 @@ " 'utilisation': 'Cumulative mean nurse utilisation',\n", " 'running_mean_wait_time': 'Running mean nurse wait time'\n", " }\n", + "\n", + " # Create 1x2 subplot\n", + " full_figure = sp.make_subplots(rows=2, cols=1, shared_xaxes=True)\n", + "\n", + " i = 1\n", " for var, label in plot.items():\n", " # Reformat so index is simulation time and columns are each run\n", " reformat = (\n", @@ -169,17 +214,45 @@ " elif var == 'running_mean_wait_time':\n", " cumulative = reformat.copy()\n", "\n", - " # Create plot. If specified, add vertical line to indicate suggested\n", - " # warm-up length\n", - " fig = px.line(cumulative)\n", - " fig.update_layout(\n", - " xaxis_title='Run time (minutes)',\n", - " yaxis_title=label,\n", - " showlegend=False\n", + " # Create plot (using go.Scatter instead of px.express, for sub-plots)\n", + " full_figure.add_trace(\n", + " go.Scatter(\n", + " x=cumulative.index,\n", + " y=cumulative[0],\n", + " mode='lines',\n", + " line=dict(color='royalblue')\n", + " ),\n", + " row=i, col=1\n", " )\n", + "\n", + " # Add y axis label\n", + " full_figure.update_yaxes(title_text=label, row=i, col=1)\n", + "\n", + " # Add vertical line for warm-up period specified\n", " if warm_up is not None:\n", - " fig.add_vline(x=warm_up, line_color='red', line_dash='dash')\n", - " fig.show()" + " full_figure.add_vline(\n", + " x=warm_up, line_color='red', line_dash='dash',\n", + " annotation_text='Suggested warm-up length',\n", + " annotation_position='top left',\n", + " annotation_font_color='red')\n", + " i += 1\n", + "\n", + " # Add x axis title\n", + " full_figure.update_xaxes(title_text='Run time (minutes)')\n", + "\n", + " # Set figure dimensions and hide legend\n", + " full_figure.update_layout(\n", + " width=1400,\n", + " height=800,\n", + " showlegend=False,\n", + " template='plotly_white'\n", + " )\n", + "\n", + " # Show figure\n", + " full_figure.show()\n", + "\n", + " # Save figure\n", + " full_figure.write_image(os.path.join(output_dir, file))" ] }, { @@ -191,1952 +264,22 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "run=0
simulation_time=%{x}
value=%{y}", - "legendgroup": "0", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "0", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 0, - 120, - 240, - 360, - 480, - 600, - 720, - 840, - 960, - 1080, - 1200, - 1320, - 1440, - 1560, - 1680, - 1800, - 1920, - 2040, - 2160, - 2280, - 2400, - 2520, - 2640, - 2760, - 2880, - 3000, - 3120, - 3240, - 3360, - 3480, - 3600, - 3720, - 3840, - 3960, - 4080, - 4200 - ], - "xaxis": "x", - "y": [ - 0, - 0.3, - 0.39999999999999997, - 0.35, - 0.32, - 0.26666666666666666, - 0.2571428571428572, - 0.25, - 0.26666666666666666, - 0.27999999999999997, - 0.29090909090909095, - 0.2833333333333333, - 0.3384615384615385, - 0.35714285714285715, - 0.3466666666666667, - 0.3875, - 0.3764705882352941, - 0.37777777777777777, - 0.38947368421052636, - 0.39, - 0.4, - 0.4090909090909091, - 0.39999999999999997, - 0.39999999999999997, - 0.4, - 0.4, - 0.4148148148148148, - 0.39999999999999997, - 0.40689655172413797, - 0.42, - 0.4258064516129032, - 0.41875, - 0.4303030303030303, - 0.4294117647058823, - 0.4342857142857143, - 0.4222222222222222 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "run" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 2520, - "x1": 2520, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "showlegend": false, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Run time (minutes)" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Cumulative mean nurse utilisation" - } - } - } - } - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "run=0
simulation_time=%{x}
value=%{y}", - "legendgroup": "0", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "0", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 0, - 120, - 240, - 360, - 480, - 600, - 720, - 840, - 960, - 1080, - 1200, - 1320, - 1440, - 1560, - 1680, - 1800, - 1920, - 2040, - 2160, - 2280, - 2400, - 2520, - 2640, - 2760, - 2880, - 3000, - 3120, - 3240, - 3360, - 3480, - 3600, - 3720, - 3840, - 3960, - 4080, - 4200 - ], - "xaxis": "x", - "y": [ - 0, - 0.1850812125177364, - 0.27293124698759036, - 0.16748053792420323, - 0.12815902032460771, - 0.10757873968853933, - 0.7775449421583632, - 0.6405489285399849, - 0.5855465140647299, - 0.5957191187844486, - 0.548688662038308, - 0.5817940262693283, - 0.5353593851431566, - 0.4954821346023178, - 0.47245100669119877, - 0.4868107775118521, - 0.46015274287212593, - 0.44014610187768555, - 0.4227129753701152, - 0.4000169766925251, - 0.3857768901436003, - 0.4124383536388688, - 0.3977084124374807, - 0.37748595078811714, - 0.45739615362189323, - 0.44211042098157305, - 0.44090411421823766, - 0.428276788751367, - 0.412287664630186, - 0.4016807112895885, - 0.4117119594328106, - 0.40236404193605335, - 0.3973051982695963, - 0.4218534759267196, - 0.40954103826584787, - 0.401190803936053 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "run" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 2520, - "x1": 2520, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "showlegend": false, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Run time (minutes)" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Running mean nurse wait time" - } - } - } - } + "image/svg+xml": [ + "0.30.350.40.450.50.550.650010001500200025003000350040000.10.20.30.40.50.60.70.8Run time (minutes)Run time (minutes)Cumulative mean nurse utilisationRunning mean nurse wait timeSuggested warm-up lengthSuggested warm-up lengthSuggested warm-up length" + ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "time_series_inspection(data_collection_period=1440*3, warm_up=2520)" + "time_series_inspection(file='choose_param_time_series_1.png',\n", + " data_collection_period=1440*3, warm_up=2520)" ] }, { @@ -2148,3728 +291,22 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "run=0
simulation_time=%{x}
value=%{y}", - "legendgroup": "0", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "0", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 0, - 120, - 240, - 360, - 480, - 600, - 720, - 840, - 960, - 1080, - 1200, - 1320, - 1440, - 1560, - 1680, - 1800, - 1920, - 2040, - 2160, - 2280, - 2400, - 2520, - 2640, - 2760, - 2880, - 3000, - 3120, - 3240, - 3360, - 3480, - 3600, - 3720, - 3840, - 3960, - 4080, - 4200, - 4320, - 4440, - 4560, - 4680, - 4800, - 4920, - 5040, - 5160, - 5280, - 5400, - 5520, - 5640, - 5760, - 5880, - 6000, - 6120, - 6240, - 6360, - 6480, - 6600, - 6720, - 6840, - 6960, - 7080, - 7200, - 7320, - 7440, - 7560, - 7680, - 7800, - 7920, - 8040, - 8160, - 8280, - 8400, - 8520, - 8640, - 8760, - 8880, - 9000, - 9120, - 9240, - 9360, - 9480, - 9600, - 9720, - 9840, - 9960, - 10080, - 10200, - 10320, - 10440, - 10560, - 10680, - 10800, - 10920, - 11040, - 11160, - 11280, - 11400, - 11520, - 11640, - 11760, - 11880, - 12000, - 12120, - 12240, - 12360, - 12480, - 12600, - 12720, - 12840, - 12960, - 13080, - 13200, - 13320, - 13440, - 13560, - 13680, - 13800, - 13920, - 14040, - 14160, - 14280, - 14400, - 14520, - 14640, - 14760, - 14880, - 15000, - 15120, - 15240, - 15360, - 15480, - 15600, - 15720, - 15840, - 15960, - 16080, - 16200, - 16320, - 16440, - 16560, - 16680, - 16800, - 16920, - 17040, - 17160, - 17280, - 17400, - 17520, - 17640, - 17760, - 17880, - 18000, - 18120, - 18240, - 18360, - 18480, - 18600, - 18720, - 18840, - 18960, - 19080, - 19200, - 19320, - 19440, - 19560, - 19680, - 19800, - 19920, - 20040, - 20160, - 20280, - 20400, - 20520, - 20640, - 20760, - 20880, - 21000, - 21120, - 21240, - 21360, - 21480, - 21600, - 21720, - 21840, - 21960, - 22080, - 22200, - 22320, - 22440, - 22560, - 22680, - 22800, - 22920, - 23040, - 23160, - 23280, - 23400, - 23520, - 23640, - 23760, - 23880, - 24000, - 24120, - 24240, - 24360, - 24480, - 24600, - 24720, - 24840, - 24960, - 25080, - 25200, - 25320, - 25440, - 25560, - 25680, - 25800, - 25920, - 26040, - 26160, - 26280, - 26400, - 26520, - 26640, - 26760, - 26880, - 27000, - 27120, - 27240, - 27360, - 27480, - 27600, - 27720, - 27840, - 27960, - 28080, - 28200, - 28320, - 28440, - 28560, - 28680, - 28800, - 28920, - 29040, - 29160, - 29280, - 29400, - 29520, - 29640, - 29760, - 29880, - 30000, - 30120, - 30240, - 30360, - 30480, - 30600, - 30720, - 30840, - 30960, - 31080, - 31200, - 31320, - 31440, - 31560, - 31680, - 31800, - 31920, - 32040, - 32160, - 32280, - 32400, - 32520, - 32640, - 32760, - 32880, - 33000, - 33120, - 33240, - 33360, - 33480, - 33600, - 33720, - 33840, - 33960, - 34080, - 34200, - 34320, - 34440, - 34560, - 34680, - 34800, - 34920, - 35040, - 35160, - 35280, - 35400, - 35520, - 35640, - 35760, - 35880, - 36000, - 36120, - 36240, - 36360, - 36480, - 36600, - 36720, - 36840, - 36960, - 37080, - 37200, - 37320, - 37440, - 37560, - 37680, - 37800, - 37920, - 38040, - 38160, - 38280, - 38400, - 38520, - 38640, - 38760, - 38880, - 39000, - 39120, - 39240, - 39360, - 39480, - 39600, - 39720, - 39840, - 39960, - 40080, - 40200, - 40320, - 40440, - 40560, - 40680, - 40800, - 40920, - 41040, - 41160, - 41280, - 41400, - 41520, - 41640, - 41760, - 41880, - 42000, - 42120, - 42240, - 42360, - 42480, - 42600, - 42720, - 42840, - 42960, - 43080, - 43200, - 43320, - 43440, - 43560, - 43680, - 43800, - 43920, - 44040, - 44160, - 44280, - 44400, - 44520, - 44640, - 44760, - 44880, - 45000, - 45120, - 45240, - 45360, - 45480, - 45600, - 45720, - 45840, - 45960, - 46080, - 46200, - 46320, - 46440, - 46560, - 46680, - 46800, - 46920, - 47040, - 47160, - 47280, - 47400, - 47520, - 47640, - 47760, - 47880, - 48000, - 48120, - 48240, - 48360, - 48480, - 48600, - 48720, - 48840, - 48960, - 49080, - 49200, - 49320, - 49440, - 49560, - 49680, - 49800, - 49920, - 50040, - 50160, - 50280, - 50400, - 50520, - 50640, - 50760, - 50880, - 51000, - 51120, - 51240, - 51360, - 51480, - 51600, - 51720, - 51840, - 51960, - 52080, - 52200, - 52320, - 52440, - 52560, - 52680, - 52800, - 52920, - 53040, - 53160, - 53280, - 53400, - 53520, - 53640, - 53760, - 53880, - 54000, - 54120, - 54240, - 54360, - 54480, - 54600, - 54720, - 54840, - 54960, - 55080, - 55200, - 55320, - 55440, - 55560, - 55680, - 55800, - 55920, - 56040, - 56160, - 56280, - 56400, - 56520, - 56640, - 56760, - 56880, - 57000, - 57120, - 57240, - 57360, - 57480 - ], - "xaxis": "x", - "y": [ - 0, - 0.3, - 0.39999999999999997, - 0.35, - 0.32, - 0.26666666666666666, - 0.2571428571428572, - 0.25, - 0.26666666666666666, - 0.27999999999999997, - 0.29090909090909095, - 0.2833333333333333, - 0.3384615384615385, - 0.35714285714285715, - 0.3466666666666667, - 0.3875, - 0.3764705882352941, - 0.37777777777777777, - 0.38947368421052636, - 0.39, - 0.4, - 0.4090909090909091, - 0.39999999999999997, - 0.39999999999999997, - 0.4, - 0.4, - 0.4148148148148148, - 0.39999999999999997, - 0.40689655172413797, - 0.42, - 0.4258064516129032, - 0.41875, - 0.4303030303030303, - 0.4294117647058823, - 0.4342857142857143, - 0.4222222222222222, - 0.43243243243243246, - 0.4263157894736842, - 0.4307692307692308, - 0.44000000000000006, - 0.43414634146341463, - 0.44761904761904764, - 0.4372093023255814, - 0.45, - 0.4444444444444444, - 0.43478260869565216, - 0.4297872340425532, - 0.4291666666666667, - 0.4244897959183674, - 0.42, - 0.4156862745098039, - 0.4153846153846154, - 0.41132075471698115, - 0.4074074074074074, - 0.41090909090909095, - 0.4035714285714286, - 0.4070175438596491, - 0.39999999999999997, - 0.4, - 0.39666666666666667, - 0.39999999999999997, - 0.3967741935483871, - 0.40634920634920635, - 0.4125, - 0.4153846153846154, - 0.4121212121212121, - 0.417910447761194, - 0.42058823529411765, - 0.42318840579710143, - 0.41714285714285715, - 0.4140845070422535, - 0.41944444444444445, - 0.41643835616438357, - 0.4135135135135135, - 0.42133333333333334, - 0.41842105263157897, - 0.4233766233766234, - 0.42051282051282046, - 0.42784810126582273, - 0.42750000000000005, - 0.4296296296296296, - 0.4268292682926829, - 0.42891566265060244, - 0.430952380952381, - 0.4329411764705882, - 0.43255813953488376, - 0.43448275862068964, - 0.43409090909090914, - 0.4337078651685393, - 0.4355555555555556, - 0.4351648351648352, - 0.43478260869565216, - 0.4344086021505376, - 0.43829787234042555, - 0.4357894736842105, - 0.4375, - 0.44329896907216493, - 0.44285714285714284, - 0.4484848484848485, - 0.45, - 0.4514851485148515, - 0.44901960784313727, - 0.44660194174757284, - 0.45000000000000007, - 0.44761904761904764, - 0.44716981132075473, - 0.4504672897196262, - 0.45, - 0.44770642201834865, - 0.4472727272727273, - 0.4486486486486487, - 0.4517857142857143, - 0.45132743362831856, - 0.4543859649122807, - 0.4504347826086957, - 0.4465517241379311, - 0.44273504273504277, - 0.4406779661016949, - 0.4403361344537815, - 0.445, - 0.4413223140495868, - 0.4426229508196721, - 0.44390243902439025, - 0.4435483870967742, - 0.448, - 0.4492063492063492, - 0.447244094488189, - 0.44375000000000003, - 0.4449612403100775, - 0.4430769230769231, - 0.44580152671755724, - 0.44696969696969696, - 0.4481203007518797, - 0.44477611940298506, - 0.442962962962963, - 0.4397058823529412, - 0.4437956204379562, - 0.4434782608695652, - 0.4474820143884892, - 0.4471428571428572, - 0.44680851063829785, - 0.4507042253521127, - 0.45174825174825173, - 0.44999999999999996, - 0.45241379310344826, - 0.4520547945205479, - 0.45306122448979586, - 0.44999999999999996, - 0.4536912751677852, - 0.456, - 0.45430463576158936, - 0.4526315789473684, - 0.45490196078431366, - 0.4584415584415584, - 0.45806451612903226, - 0.46153846153846156, - 0.46242038216560505, - 0.4620253164556962, - 0.46289308176100624, - 0.46624999999999994, - 0.4670807453416149, - 0.4666666666666666, - 0.4687116564417178, - 0.46829268292682924, - 0.4678787878787879, - 0.46746987951807223, - 0.4646706586826347, - 0.4642857142857143, - 0.4627218934911243, - 0.46352941176470586, - 0.4631578947368421, - 0.46279069767441855, - 0.4635838150289017, - 0.464367816091954, - 0.46285714285714286, - 0.4659090909090909, - 0.46440677966101696, - 0.4640449438202247, - 0.46368715083798884, - 0.46222222222222226, - 0.46519337016574586, - 0.46593406593406594, - 0.4644808743169399, - 0.46413043478260874, - 0.4616216216216216, - 0.46021505376344085, - 0.45989304812834225, - 0.4606382978723404, - 0.45925925925925926, - 0.4610526315789473, - 0.46387434554973817, - 0.465625, - 0.4683937823834197, - 0.4690721649484536, - 0.4697435897435897, - 0.46938775510204084, - 0.47005076142131974, - 0.4727272727272727, - 0.4733668341708543, - 0.475, - 0.47562189054726367, - 0.4752475247524752, - 0.4729064039408867, - 0.47352941176470587, - 0.47317073170731705, - 0.47281553398058257, - 0.4714975845410628, - 0.46923076923076923, - 0.47081339712918663, - 0.47047619047619044, - 0.46919431279620855, - 0.4679245283018868, - 0.46572769953051646, - 0.46822429906542057, - 0.4697674418604651, - 0.4722222222222222, - 0.4737327188940092, - 0.4724770642201835, - 0.4712328767123288, - 0.4709090909090909, - 0.47058823529411764, - 0.4702702702702703, - 0.47264573991031394, - 0.47053571428571433, - 0.4728888888888889, - 0.47345132743362833, - 0.47224669603524233, - 0.47192982456140353, - 0.4707423580786026, - 0.46956521739130436, - 0.4683982683982684, - 0.4706896551724138, - 0.47124463519313303, - 0.4726495726495727, - 0.47489361702127664, - 0.47288135593220343, - 0.47257383966244726, - 0.4714285714285714, - 0.4719665271966527, - 0.4741666666666667, - 0.4730290456431535, - 0.47107438016528924, - 0.471604938271605, - 0.4704918032786885, - 0.4702040816326531, - 0.4691056910569106, - 0.46963562753036436, - 0.47096774193548385, - 0.47148594377510045, - 0.47040000000000004, - 0.4717131474103586, - 0.4722222222222222, - 0.4743083003952569, - 0.4732283464566929, - 0.47137254901960784, - 0.4734375, - 0.47392996108949415, - 0.4728682170542636, - 0.4725868725868726, - 0.4723076923076923, - 0.4720306513409962, - 0.47175572519083975, - 0.4737642585551331, - 0.471969696969697, - 0.47396226415094345, - 0.47443609022556393, - 0.4749063670411985, - 0.4753731343283582, - 0.47360594795539035, - 0.47333333333333333, - 0.47453874538745383, - 0.4735294117647059, - 0.4725274725274725, - 0.47226277372262776, - 0.4741818181818182, - 0.4746376811594203, - 0.47436823104693143, - 0.47338129496402875, - 0.4731182795698925, - 0.4742857142857143, - 0.4740213523131672, - 0.475886524822695, - 0.47632508833922266, - 0.47816901408450707, - 0.47719298245614034, - 0.47692307692307695, - 0.4766550522648084, - 0.47708333333333336, - 0.47750865051903113, - 0.47586206896551725, - 0.4762886597938144, - 0.4773972602739726, - 0.4778156996587031, - 0.4768707482993197, - 0.4766101694915254, - 0.4756756756756757, - 0.47542087542087536, - 0.47516778523489933, - 0.47424749163879604, - 0.474, - 0.4750830564784053, - 0.47549668874172185, - 0.4745874587458746, - 0.47302631578947374, - 0.4727868852459016, - 0.4725490196078431, - 0.4723127035830619, - 0.4733766233766234, - 0.4737864077669903, - 0.4729032258064516, - 0.47266881028938906, - 0.4724358974358975, - 0.47348242811501595, - 0.4726114649681529, - 0.4742857142857143, - 0.47468354430379744, - 0.4744479495268139, - 0.47358490566037736, - 0.4752351097178683, - 0.47562499999999996, - 0.47538940809968844, - 0.4751552795031056, - 0.47554179566563465, - 0.47592592592592586, - 0.47692307692307695, - 0.4760736196319018, - 0.47706422018348627, - 0.4774390243902439, - 0.47598784194528876, - 0.47575757575757577, - 0.4773413897280967, - 0.4771084337349398, - 0.4762762762762763, - 0.4754491017964072, - 0.4740298507462687, - 0.4738095238095238, - 0.4741839762611276, - 0.47455621301775147, - 0.4731563421828909, - 0.4747058823529412, - 0.47448680351906164, - 0.47368421052631576, - 0.4728862973760933, - 0.47267441860465115, - 0.47130434782608693, - 0.46994219653179187, - 0.47031700288184436, - 0.4718390804597701, - 0.47048710601719196, - 0.4714285714285714, - 0.47065527065527063, - 0.4710227272727273, - 0.47138810198300285, - 0.4717514124293785, - 0.4715492957746479, - 0.4724719101123595, - 0.4722689075630252, - 0.4715083798882682, - 0.471866295264624, - 0.4722222222222222, - 0.4714681440443213, - 0.4729281767955801, - 0.4721763085399449, - 0.471978021978022, - 0.4723287671232877, - 0.4715846994535519, - 0.4708446866485014, - 0.47119565217391307, - 0.47208672086720865, - 0.47297297297297297, - 0.4738544474393531, - 0.47258064516129034, - 0.4723860589812332, - 0.47379679144385023, - 0.47519999999999996, - 0.474468085106383, - 0.47480106100795755, - 0.47460317460317464, - 0.47493403693931396, - 0.4763157894736842, - 0.4755905511811024, - 0.47591623036649217, - 0.47676240208877285, - 0.47708333333333336, - 0.47688311688311685, - 0.4782383419689119, - 0.47855297157622745, - 0.4798969072164949, - 0.47969151670951155, - 0.478974358974359, - 0.4787723785166241, - 0.47857142857142854, - 0.47938931297709925, - 0.4796954314720812, - 0.479493670886076, - 0.4808080808080808, - 0.48010075566750626, - 0.4793969849246231, - 0.47869674185463656, - 0.47800000000000004, - 0.47680798004987535, - 0.47611940298507466, - 0.47593052109181144, - 0.4747524752475248, - 0.47456790123456793, - 0.4758620689655173, - 0.47665847665847666, - 0.47794117647058826, - 0.4792176039119804, - 0.4790243902439025, - 0.4798053527980536, - 0.479126213592233, - 0.4794188861985472, - 0.4806763285024155, - 0.48048192771084336, - 0.4807692307692308, - 0.48009592326139094, - 0.48038277511961724, - 0.48019093078758956, - 0.4804761904761905, - 0.48028503562945374, - 0.48151658767772515, - 0.4813238770685579, - 0.480188679245283, - 0.48, - 0.4812206572769953, - 0.4814988290398126, - 0.48130841121495327, - 0.4811188811188811, - 0.48093023255813955, - 0.4798143851508121, - 0.4791666666666667, - 0.47852193995381065, - 0.47834101382488475, - 0.4781609195402299, - 0.4775229357798165, - 0.4778032036613273, - 0.4771689497716895, - 0.4774487471526196, - 0.47863636363636364, - 0.4789115646258504, - 0.47828054298642536, - 0.47765237020316026, - 0.4774774774774775, - 0.4782022471910113, - 0.47757847533632286, - 0.4769574944071589, - 0.4772321428571429, - 0.4770601336302896, - 0.47733333333333333, - 0.4776053215077605, - 0.47699115044247786, - 0.47770419426048566, - 0.4775330396475771, - 0.4773626373626374, - 0.4780701754385965, - 0.47921225382932164, - 0.4790393013100437, - 0.4784313725490196, - 0.4782608695652174, - 0.47852494577006505, - 0.47748917748917746, - 0.4777537796976242, - 0.47801724137931034, - 0.4791397849462366, - 0.48025751072961376, - 0.4813704496788009, - 0.4811965811965812, - 0.48059701492537316, - 0.4812765957446809, - 0.48067940552016986, - 0.48135593220338985, - 0.481183932346723, - 0.4810126582278481, - 0.48126315789473684, - 0.4810924369747899, - 0.4817610062893082, - 0.48158995815899586, - 0.4810020876826722, - 0.48041666666666666 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "run" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 18720, - "x1": 18720, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "showlegend": false, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Run time (minutes)" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Cumulative mean nurse utilisation" - } - } - } - } - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "run=0
simulation_time=%{x}
value=%{y}", - "legendgroup": "0", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "0", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 0, - 120, - 240, - 360, - 480, - 600, - 720, - 840, - 960, - 1080, - 1200, - 1320, - 1440, - 1560, - 1680, - 1800, - 1920, - 2040, - 2160, - 2280, - 2400, - 2520, - 2640, - 2760, - 2880, - 3000, - 3120, - 3240, - 3360, - 3480, - 3600, - 3720, - 3840, - 3960, - 4080, - 4200, - 4320, - 4440, - 4560, - 4680, - 4800, - 4920, - 5040, - 5160, - 5280, - 5400, - 5520, - 5640, - 5760, - 5880, - 6000, - 6120, - 6240, - 6360, - 6480, - 6600, - 6720, - 6840, - 6960, - 7080, - 7200, - 7320, - 7440, - 7560, - 7680, - 7800, - 7920, - 8040, - 8160, - 8280, - 8400, - 8520, - 8640, - 8760, - 8880, - 9000, - 9120, - 9240, - 9360, - 9480, - 9600, - 9720, - 9840, - 9960, - 10080, - 10200, - 10320, - 10440, - 10560, - 10680, - 10800, - 10920, - 11040, - 11160, - 11280, - 11400, - 11520, - 11640, - 11760, - 11880, - 12000, - 12120, - 12240, - 12360, - 12480, - 12600, - 12720, - 12840, - 12960, - 13080, - 13200, - 13320, - 13440, - 13560, - 13680, - 13800, - 13920, - 14040, - 14160, - 14280, - 14400, - 14520, - 14640, - 14760, - 14880, - 15000, - 15120, - 15240, - 15360, - 15480, - 15600, - 15720, - 15840, - 15960, - 16080, - 16200, - 16320, - 16440, - 16560, - 16680, - 16800, - 16920, - 17040, - 17160, - 17280, - 17400, - 17520, - 17640, - 17760, - 17880, - 18000, - 18120, - 18240, - 18360, - 18480, - 18600, - 18720, - 18840, - 18960, - 19080, - 19200, - 19320, - 19440, - 19560, - 19680, - 19800, - 19920, - 20040, - 20160, - 20280, - 20400, - 20520, - 20640, - 20760, - 20880, - 21000, - 21120, - 21240, - 21360, - 21480, - 21600, - 21720, - 21840, - 21960, - 22080, - 22200, - 22320, - 22440, - 22560, - 22680, - 22800, - 22920, - 23040, - 23160, - 23280, - 23400, - 23520, - 23640, - 23760, - 23880, - 24000, - 24120, - 24240, - 24360, - 24480, - 24600, - 24720, - 24840, - 24960, - 25080, - 25200, - 25320, - 25440, - 25560, - 25680, - 25800, - 25920, - 26040, - 26160, - 26280, - 26400, - 26520, - 26640, - 26760, - 26880, - 27000, - 27120, - 27240, - 27360, - 27480, - 27600, - 27720, - 27840, - 27960, - 28080, - 28200, - 28320, - 28440, - 28560, - 28680, - 28800, - 28920, - 29040, - 29160, - 29280, - 29400, - 29520, - 29640, - 29760, - 29880, - 30000, - 30120, - 30240, - 30360, - 30480, - 30600, - 30720, - 30840, - 30960, - 31080, - 31200, - 31320, - 31440, - 31560, - 31680, - 31800, - 31920, - 32040, - 32160, - 32280, - 32400, - 32520, - 32640, - 32760, - 32880, - 33000, - 33120, - 33240, - 33360, - 33480, - 33600, - 33720, - 33840, - 33960, - 34080, - 34200, - 34320, - 34440, - 34560, - 34680, - 34800, - 34920, - 35040, - 35160, - 35280, - 35400, - 35520, - 35640, - 35760, - 35880, - 36000, - 36120, - 36240, - 36360, - 36480, - 36600, - 36720, - 36840, - 36960, - 37080, - 37200, - 37320, - 37440, - 37560, - 37680, - 37800, - 37920, - 38040, - 38160, - 38280, - 38400, - 38520, - 38640, - 38760, - 38880, - 39000, - 39120, - 39240, - 39360, - 39480, - 39600, - 39720, - 39840, - 39960, - 40080, - 40200, - 40320, - 40440, - 40560, - 40680, - 40800, - 40920, - 41040, - 41160, - 41280, - 41400, - 41520, - 41640, - 41760, - 41880, - 42000, - 42120, - 42240, - 42360, - 42480, - 42600, - 42720, - 42840, - 42960, - 43080, - 43200, - 43320, - 43440, - 43560, - 43680, - 43800, - 43920, - 44040, - 44160, - 44280, - 44400, - 44520, - 44640, - 44760, - 44880, - 45000, - 45120, - 45240, - 45360, - 45480, - 45600, - 45720, - 45840, - 45960, - 46080, - 46200, - 46320, - 46440, - 46560, - 46680, - 46800, - 46920, - 47040, - 47160, - 47280, - 47400, - 47520, - 47640, - 47760, - 47880, - 48000, - 48120, - 48240, - 48360, - 48480, - 48600, - 48720, - 48840, - 48960, - 49080, - 49200, - 49320, - 49440, - 49560, - 49680, - 49800, - 49920, - 50040, - 50160, - 50280, - 50400, - 50520, - 50640, - 50760, - 50880, - 51000, - 51120, - 51240, - 51360, - 51480, - 51600, - 51720, - 51840, - 51960, - 52080, - 52200, - 52320, - 52440, - 52560, - 52680, - 52800, - 52920, - 53040, - 53160, - 53280, - 53400, - 53520, - 53640, - 53760, - 53880, - 54000, - 54120, - 54240, - 54360, - 54480, - 54600, - 54720, - 54840, - 54960, - 55080, - 55200, - 55320, - 55440, - 55560, - 55680, - 55800, - 55920, - 56040, - 56160, - 56280, - 56400, - 56520, - 56640, - 56760, - 56880, - 57000, - 57120, - 57240, - 57360, - 57480 - ], - "xaxis": "x", - "y": [ - 0, - 0.1850812125177364, - 0.27293124698759036, - 0.16748053792420323, - 0.12815902032460771, - 0.10757873968853933, - 0.7775449421583632, - 0.6405489285399849, - 0.5855465140647299, - 0.5957191187844486, - 0.548688662038308, - 0.5817940262693283, - 0.5353593851431566, - 0.4954821346023178, - 0.47245100669119877, - 0.4868107775118521, - 0.46015274287212593, - 0.44014610187768555, - 0.4227129753701152, - 0.4000169766925251, - 0.3857768901436003, - 0.4124383536388688, - 0.3977084124374807, - 0.37748595078811714, - 0.45739615362189323, - 0.44211042098157305, - 0.44090411421823766, - 0.428276788751367, - 0.412287664630186, - 0.4016807112895885, - 0.4117119594328106, - 0.40236404193605335, - 0.3973051982695963, - 0.4218534759267196, - 0.40954103826584787, - 0.401190803936053, - 0.3936752248630797, - 0.38673209920411894, - 0.37741325344016424, - 0.3790608189493043, - 0.3704521229859087, - 0.3666684112093553, - 0.35982012959921933, - 0.3541981683964747, - 0.38523896779470446, - 0.3801402167503627, - 0.396941843930088, - 0.3886027295618088, - 0.3819165160456043, - 0.38628700852869746, - 0.3791352962464029, - 0.375115528085878, - 0.3700852432264889, - 0.36449905087590034, - 0.3581912799089502, - 0.3514575445073871, - 0.3462087759215539, - 0.35781845886993224, - 0.3884708700783271, - 0.3822807037955309, - 0.3857614550170858, - 0.3805001149322918, - 0.3841437176412842, - 0.38140246619005375, - 0.3780264734740002, - 0.38048338443571317, - 0.3910980358329828, - 0.44307813054061207, - 0.44115445318264646, - 0.44361513727966445, - 0.43838714241240806, - 0.4377580524118717, - 0.4335060084245224, - 0.4285505213597702, - 0.42626413266078583, - 0.4250180083345155, - 0.42150248228749787, - 0.41589355757239915, - 0.42145016535205815, - 0.44027556960662306, - 0.4353471117378922, - 0.4305277710175466, - 0.46993365458393677, - 0.4647376423044281, - 0.46157742166213167, - 0.45787482017504816, - 0.4831754631715794, - 0.4833357962795798, - 0.48300620316176707, - 0.4798689908515143, - 0.47494426312936056, - 0.470272680213334, - 0.4698121041492425, - 0.4643084479771, - 0.45909333027430366, - 0.4549415297222578, - 0.4568906748912471, - 0.4543350074193327, - 0.4783073604122729, - 0.49286863973483025, - 0.48783439662715994, - 0.4843709933532162, - 0.4808041204907635, - 0.4776979100144966, - 0.477423508162683, - 0.47412057823199766, - 0.4702082937379254, - 0.4671531037105441, - 0.4643660927444776, - 0.46107846702166944, - 0.45760448659224656, - 0.45396324793944076, - 0.45613929588140695, - 0.45251594754695623, - 0.4535325408966958, - 0.45102974732218604, - 0.4487611252072768, - 0.4447886537962473, - 0.44082916200063704, - 0.44801743945307104, - 0.44918327131031816, - 0.44633406688667304, - 0.4438855084699072, - 0.4407493608557178, - 0.4401384555583535, - 0.43717335065370905, - 0.4373158525933378, - 0.4403461307322662, - 0.4361043169241189, - 0.4371090202310064, - 0.4335279939515921, - 0.4308804947518877, - 0.43355005344792485, - 0.43168599160180954, - 0.4285749345052756, - 0.4260134935335736, - 0.4230884376682131, - 0.42458741107824094, - 0.4216793375678051, - 0.4324950783003846, - 0.42940509203007926, - 0.42747013885075374, - 0.4291093930183234, - 0.4271522789084772, - 0.4235114969873499, - 0.42852405654047804, - 0.4259734270383347, - 0.4249648373783751, - 0.42682623018822213, - 0.44001310808118466, - 0.4392556508851206, - 0.43775646943895313, - 0.4374400111857146, - 0.4349150070337013, - 0.43269200986280654, - 0.43046641872763575, - 0.4276253586934529, - 0.4251812679473218, - 0.423041235915345, - 0.42740773620080935, - 0.44085442604884445, - 0.43881341201899193, - 0.43620624362141963, - 0.43493662689076, - 0.43170676992779433, - 0.4321484491946318, - 0.42998943416068586, - 0.4274269226341025, - 0.4256683537664904, - 0.4475974503427971, - 0.44506766549385124, - 0.44329239040217233, - 0.44141859156509083, - 0.4389676746293473, - 0.4453810304867603, - 0.44276857789544727, - 0.44062679583749054, - 0.4379382425140786, - 0.43541339863869505, - 0.43323794309405317, - 0.432677344808932, - 0.4338988889218631, - 0.43319477000587975, - 0.43078509306240736, - 0.42891738011385233, - 0.4409065434818109, - 0.43964020054183256, - 0.4374575896171569, - 0.4350662679317166, - 0.4329287252922907, - 0.4319952677678144, - 0.4304895655907654, - 0.42853847084935937, - 0.4320731023635356, - 0.4300110524460004, - 0.42897982369652776, - 0.4702039412350683, - 0.46752021889127243, - 0.4667678551466583, - 0.4644704386332219, - 0.4651659138109862, - 0.4634852355216379, - 0.4740068171219543, - 0.4916165075017119, - 0.4913272753204745, - 0.48884989133338885, - 0.48689823894064926, - 0.48449972544833086, - 0.48272512618668323, - 0.4814299356650332, - 0.4798479764450189, - 0.47910418079672934, - 0.47846891365760524, - 0.4875642507877192, - 0.4852917417368004, - 0.4835037463727102, - 0.4820067862774509, - 0.47973213102176504, - 0.4777636407006733, - 0.4758177034101442, - 0.47405531663541983, - 0.4726362017824475, - 0.4715104481002665, - 0.47064351006274896, - 0.475988542712476, - 0.4757559011157227, - 0.4740494468811493, - 0.4764058202237804, - 0.4746096265860458, - 0.47323712911182353, - 0.4864835499625991, - 0.48490769808510664, - 0.489296257258989, - 0.48730420618338044, - 0.48494115216582767, - 0.48371085748802856, - 0.48398807536897026, - 0.4822293486101174, - 0.4806935112100291, - 0.4993371227786035, - 0.4995618700065461, - 0.4977769849412486, - 0.4953273340570725, - 0.4940444524666848, - 0.4917685909046258, - 0.4904376880875632, - 0.49152302465222514, - 0.4894756927870687, - 0.49015693546541594, - 0.4890430187610261, - 0.48736045709796055, - 0.4863903055455151, - 0.48447513174759327, - 0.4827643249784086, - 0.48106678643229467, - 0.4836437561810941, - 0.4884427620789517, - 0.4871763378330814, - 0.486797742126044, - 0.48531015327960864, - 0.4833896374149022, - 0.48186166410154124, - 0.49146212751730006, - 0.49264009260729813, - 0.49191858525866405, - 0.4907014022394553, - 0.49261296328031845, - 0.4921015679229963, - 0.4914086624541346, - 0.4969362948105312, - 0.49451781910881315, - 0.49301818962340316, - 0.493139981657704, - 0.492699364995897, - 0.49277356882964113, - 0.49317461759100745, - 0.4914723962258396, - 0.48976342816070856, - 0.4904248212924081, - 0.48903797132056664, - 0.4884068002214369, - 0.48711895935448624, - 0.4873226837541425, - 0.49158019503215583, - 0.4958158729868385, - 0.4936455005443202, - 0.49222795660754004, - 0.49185825796855026, - 0.4907109054163872, - 0.489343917739968, - 0.4877925556819155, - 0.48619612366354564, - 0.486287440867833, - 0.4847623458471903, - 0.483160359919501, - 0.4821317832100534, - 0.48108965522126484, - 0.4792856353384454, - 0.477915193622972, - 0.4771715317521856, - 0.47540095092935736, - 0.4832525754428418, - 0.4828573167794596, - 0.48157811585936067, - 0.48387973537706797, - 0.48284036316059925, - 0.48154741017441516, - 0.47963204375218293, - 0.47850950572257184, - 0.4856936495040175, - 0.4844622267712798, - 0.48303053978035587, - 0.4813567786869736, - 0.48213279108769436, - 0.4855192338311378, - 0.4914412137579184, - 0.4968012766088033, - 0.495368245214444, - 0.4936459148090579, - 0.49241085423502734, - 0.49115649742270767, - 0.4907057306199548, - 0.48909422038328926, - 0.4881543204958327, - 0.48697222951693037, - 0.4856003387405469, - 0.48418757692037484, - 0.4832180383202139, - 0.4824021237355283, - 0.4814407803243376, - 0.4842048046699344, - 0.48344188875529487, - 0.48204287246278493, - 0.4848959388377649, - 0.4840799682843253, - 0.4890862181258771, - 0.48878797611411606, - 0.48885375143389437, - 0.494892473360869, - 0.49399723385099115, - 0.4931123704338077, - 0.49249891976792615, - 0.4912199550454755, - 0.4903288743555896, - 0.48902157969914734, - 0.4879992996959754, - 0.4868712140054762, - 0.4861915279175096, - 0.48536695995645, - 0.4843236658508559, - 0.48663843454464756, - 0.486050464733403, - 0.4847361313084035, - 0.4835651623021766, - 0.482489278006705, - 0.48176911227708563, - 0.48052394198005355, - 0.4811855868054409, - 0.48144254344162696, - 0.48103156880001835, - 0.47967457738744224, - 0.47884700811625347, - 0.49196555461057123, - 0.49222525048814225, - 0.4912501081638973, - 0.48997058120712045, - 0.48894659574253924, - 0.48794089267492363, - 0.4865485163091667, - 0.4853580213651703, - 0.48396950274010103, - 0.4829846935245811, - 0.48181967470630627, - 0.48051324701195713, - 0.47923740727072767, - 0.4779798963621191, - 0.47689537962371126, - 0.4828739824522451, - 0.4820358050829477, - 0.4926867231089775, - 0.49178039062325446, - 0.4904923907821662, - 0.4892820364317005, - 0.4881507969229101, - 0.48747610260278873, - 0.4863261927316303, - 0.4851703372527671, - 0.48501728577287934, - 0.48415710816953234, - 0.4829742475008788, - 0.48281871650789765, - 0.482582448609397, - 0.4840848163873462, - 0.483277806607589, - 0.4822728203186862, - 0.4843148414272392, - 0.4865297696253941, - 0.4860132381985209, - 0.48506136086802726, - 0.48394444326076536, - 0.4826077646158507, - 0.4813446001738657, - 0.4802286137100032, - 0.479251029202003, - 0.4783551600804453, - 0.48054923966902224, - 0.48106999550397506, - 0.4806279758469445, - 0.4808429110366816, - 0.48097972273284084, - 0.47994751232637756, - 0.4792573468104413, - 0.4784162090657402, - 0.4780298724945213, - 0.48064337121961886, - 0.4793879310383423, - 0.4792118622596814, - 0.4782301802222758, - 0.47721498918005556, - 0.47616674098855616, - 0.475723113180055, - 0.476021897541076, - 0.47535215376141815, - 0.47439147315529323, - 0.47528448022802533, - 0.4749294823095646, - 0.47453056976025687, - 0.47647632372478615, - 0.47690981877366473, - 0.476106817395047, - 0.4750524380361729, - 0.47462257108108463, - 0.47437313071250126, - 0.47536192894997076, - 0.4742479117291173, - 0.47446809107028376, - 0.47332565473362087, - 0.47240146826448026, - 0.47119475722708776, - 0.4710887899426334, - 0.47556882534238837, - 0.4747551009722891, - 0.47492126514372707, - 0.4793202224319916, - 0.47849867906699817, - 0.4773686452861756, - 0.47777444860024504, - 0.4764105697587513, - 0.47691942462908943, - 0.4761460279284954, - 0.47556841158595875, - 0.4745197957457272, - 0.47365822301759564, - 0.4727020046022226, - 0.4719453417259112, - 0.47917328952650773, - 0.4790636246109847, - 0.47877874028183864, - 0.4776654887343246, - 0.4767082432659191, - 0.4758907955781238, - 0.4793678981448613, - 0.47824310145552823, - 0.47998150657581995, - 0.4793904205834992, - 0.4835712940840089, - 0.48347625611477696, - 0.4844570699566931, - 0.48367645396895276, - 0.4828934391793077, - 0.4822635791446351, - 0.48137682439925916, - 0.48095402954096433, - 0.4801528289642319, - 0.484079412380386, - 0.4833123031027946, - 0.4825960272491216, - 0.48270616964234175, - 0.48574094851801636, - 0.4847409328403097 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "run" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 18720, - "x1": 18720, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "showlegend": false, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Run time (minutes)" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Running mean nurse wait time" - } - } - } - } + "image/svg+xml": [ + "0.30.350.40.450.50.550.610k20k30k40k50k0.10.20.30.40.50.60.70.8Run time (minutes)Run time (minutes)Cumulative mean nurse utilisationRunning mean nurse wait timeSuggested warm-up lengthSuggested warm-up lengthSuggested warm-up length" + ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "time_series_inspection(data_collection_period=1440*40, warm_up=1440*13)" + "time_series_inspection(file='choose_param_time_series_2.png',\n", + " data_collection_period=1440*40, warm_up=1440*13)" ] }, { @@ -5889,34 +326,38 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "def confidence_interval_method(replications, metric, desired_precision,\n", - " min_rep=None):\n", + "def confidence_interval_method(file, replications, metric, desired_precision,\n", + " yaxis_title, min_rep=None):\n", " \"\"\"\n", " Use the confidence interval method to select the number of replications.\n", "\n", " Arguments:\n", + " file (str):\n", + " Filename to save figure to.\n", " replications (int):\n", " Number of times to run the model.\n", " metric (string):\n", " Name of performance metric to assess.\n", " desired_precision (float):\n", " Desired mean deviation from confidence interval.\n", + " yaxis_title (str):\n", + " Label for y axis.\n", " min_rep (int):\n", " A suggested minimum number of replications.\n", " \"\"\"\n", " param = Defaults()\n", " param.number_of_runs = replications\n", - " choose_rep = Trial(param)\n", - " choose_rep.run_trial()\n", + " choose_rep = Runner(param)\n", + " choose_rep.run_reps()\n", "\n", " # If mean of metric is less than 1, multiply by 100\n", - " if choose_rep.trial_results_df[metric].mean() < 1:\n", - " choose_rep.trial_results_df[f'adj_{metric}'] = (\n", - " choose_rep.trial_results_df[metric]*100)\n", + " if choose_rep.run_results_df[metric].mean() < 1:\n", + " choose_rep.run_results_df[f'adj_{metric}'] = (\n", + " choose_rep.run_results_df[metric]*100)\n", " metric = f'adj_{metric}'\n", "\n", " # Initialise list to store the results\n", @@ -5926,7 +367,7 @@ " # then perform calculations\n", " for i in range(1, replications+1):\n", " mean, std_dev, ci_lower, ci_upper = summary_stats(\n", - " choose_rep.trial_results_df[metric].iloc[:i])\n", + " choose_rep.run_results_df[metric].iloc[:i])\n", " deviation = ((ci_upper-mean)/mean)*100\n", " cumulative_list.append({\n", " 'replications': i,\n", @@ -5955,16 +396,22 @@ " y=['cumulative_mean', 'lower_ci', 'upper_ci'])\n", " fig.update_layout(\n", " xaxis_title='Number of replications',\n", - " yaxis_title=metric\n", + " yaxis_title=yaxis_title,\n", + " template='plotly_white'\n", " )\n", " if min_rep is not None:\n", " fig.add_vline(x=min_rep, line_color='red', line_dash='dash')\n", - " fig.show()" + "\n", + " # Show figure\n", + " fig.show()\n", + "\n", + " # Save figure\n", + " fig.write_image(os.path.join(output_dir, file))" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -6239,1061 +686,9 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "variable=cumulative_mean
replications=%{x}
value=%{y}", - "legendgroup": "cumulative_mean", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "cumulative_mean", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - 9.84226781662332, - 9.951374400036872, - 9.942591106606683, - 9.941207618553587, - 9.956146924437203, - 9.944288427507884, - 9.958218602827435, - 9.974313668481962, - 9.999642175136987, - 10.008938185524622, - 10.015721406424772, - 10.005522459034454, - 9.990551890174856, - 9.986503895431062, - 9.998582541597393, - 9.997144962523357, - 9.986124962793632, - 9.986293276241893, - 9.97649797303346, - 9.973642606291607 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=lower_ci
replications=%{x}
value=%{y}", - "legendgroup": "lower_ci", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "lower_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - null, - 8.565043813091666, - 9.668933313439396, - 9.798014217052518, - 9.850865099446205, - 9.859061957546787, - 9.881649039803216, - 9.89978266327813, - 9.912922219809905, - 9.92999589179406, - 9.943783596856044, - 9.936878667457163, - 9.9200461110227, - 9.921192666323249, - 9.932895347421631, - 9.936005476017742, - 9.924412811154433, - 9.928386334642774, - 9.918201270401944, - 9.918222229071448 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=upper_ci
replications=%{x}
value=%{y}", - "legendgroup": "upper_ci", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "upper_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - null, - 11.337704986982079, - 10.21624889977397, - 10.084401020054656, - 10.0614287494282, - 10.02951489746898, - 10.034788165851653, - 10.048844673685794, - 10.08636213046407, - 10.087880479255183, - 10.0876592159935, - 10.074166250611745, - 10.061057669327013, - 10.051815124538875, - 10.064269735773156, - 10.058284449028973, - 10.04783711443283, - 10.044200217841013, - 10.034794675664976, - 10.029062983511766 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 3, - "x1": 3, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Number of replications" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "mean_time_with_nurse" - } - } - } - } + "image/svg+xml": [ + "51015208.599.51010.511variablecumulative_meanlower_ciupper_ciNumber of replicationsMean time with nurse" + ] }, "metadata": {}, "output_type": "display_data" @@ -7301,9 +696,11 @@ ], "source": [ "confidence_interval_method(\n", + " file='choose_param_conf_int_1.png',\n", " replications=20,\n", " metric='mean_time_with_nurse',\n", " desired_precision=0.05,\n", + " yaxis_title='Mean time with nurse',\n", " min_rep=3\n", ")" ] @@ -7317,7 +714,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -7922,1241 +1319,9 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "variable=cumulative_mean
replications=%{x}
value=%{y}", - "legendgroup": "cumulative_mean", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "cumulative_mean", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50 - ], - "xaxis": "x", - "y": [ - 50.454108133861496, - 50.9345865171004, - 51.397555098122986, - 50.52688790311877, - 49.65065946781098, - 47.84662767005613, - 47.68193954814792, - 49.54530161589753, - 49.24579179901227, - 49.955562481112146, - 50.52856561182975, - 49.63295034445772, - 49.240443624489245, - 48.86441604370572, - 49.67867015521599, - 49.55319066503698, - 49.157921979277404, - 49.23567345862779, - 48.547385951850934, - 48.21581151445441, - 48.8341738271005, - 48.96589894643734, - 49.14849751376411, - 49.29670436638265, - 49.33671521294648, - 49.85093651270256, - 49.87934414589377, - 49.857059600665806, - 49.71619175807141, - 49.86645394562918, - 49.90369055664021, - 49.85041110323886, - 49.95569502030414, - 50.078240420652314, - 50.00286466905623, - 49.88892567847176, - 50.30890719744652, - 50.61793289147639, - 50.726525556136416, - 51.107306876901966, - 51.25330458745603, - 51.158101300394435, - 51.309010293312035, - 51.43298146439347, - 51.76215758519753, - 52.120720871328885, - 51.99945607918535, - 52.09106794087152, - 52.01185242028414, - 51.95571927478935 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=lower_ci
replications=%{x}
value=%{y}", - "legendgroup": "lower_ci", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "lower_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50 - ], - "xaxis": "x", - "y": [ - null, - 44.82952980823701, - 49.075345752234426, - 47.50154139555324, - 46.47287157316492, - 42.6239386966234, - 43.461036473080895, - 43.8979491956498, - 44.33990286035744, - 45.36133327371767, - 46.24092400613056, - 45.29307245587066, - 45.197077539910225, - 45.06481819033541, - 45.75666846800609, - 45.8975107448092, - 45.64131775138991, - 45.93189225382797, - 45.11592958132439, - 44.89926173551309, - 45.43583690969251, - 45.72398046297012, - 46.03616470234551, - 46.30859624123202, - 46.47602404720858, - 46.9109071628804, - 47.05520288898672, - 47.14016138031387, - 47.08316788336251, - 47.30813142746699, - 47.43167813515013, - 47.45766018510719, - 47.6296115834672, - 47.8105395336712, - 47.798038280084505, - 47.73601037495089, - 48.05030030909724, - 48.33411693347069, - 48.49316819482629, - 48.799985228531995, - 48.98548173310083, - 48.938270953705825, - 49.121679713233895, - 49.28282780899037, - 49.55943211647076, - 49.849868285567496, - 49.765402314539806, - 49.89755103181367, - 49.85884893297667, - 49.84431143912996 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=upper_ci
replications=%{x}
value=%{y}", - "legendgroup": "upper_ci", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "upper_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50 - ], - "xaxis": "x", - "y": [ - null, - 57.039643225963786, - 53.719764444011545, - 53.5522344106843, - 52.82844736245704, - 53.06931664348886, - 51.90284262321495, - 55.19265403614526, - 54.15168073766709, - 54.54979168850662, - 54.816207217528934, - 53.97282823304478, - 53.283809709068265, - 52.664013897076025, - 53.60067184242589, - 53.208870585264755, - 52.674526207164895, - 52.539454663427605, - 51.97884232237748, - 51.532361293395724, - 52.23251074450849, - 52.207817429904566, - 52.26083032518272, - 52.28481249153328, - 52.19740637868438, - 52.79096586252472, - 52.703485402800816, - 52.57395782101774, - 52.34921563278031, - 52.424776463791375, - 52.375702978130285, - 52.24316202137054, - 52.28177845714108, - 52.34594130763343, - 52.207691058027955, - 52.04184098199263, - 52.56751408579581, - 52.9017488494821, - 52.95988291744654, - 53.41462852527194, - 53.521127441811224, - 53.377931647083045, - 53.496340873390174, - 53.58313511979657, - 53.9648830539243, - 54.391573457090274, - 54.233509843830895, - 54.28458484992937, - 54.164855907591615, - 54.067127110448745 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 31, - "x1": 31, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Number of replications" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "adj_mean_q_time_nurse" - } - } - } - } + "image/svg+xml": [ + "10203040504244464850525456variablecumulative_meanlower_ciupper_ciNumber of replicationsMean wait time for nurse" + ] }, "metadata": {}, "output_type": "display_data" @@ -9164,16 +1329,18 @@ ], "source": [ "confidence_interval_method(\n", + " file='choose_param_conf_int_2.png',\n", " replications=50,\n", " metric='mean_q_time_nurse',\n", " desired_precision=0.05,\n", + " yaxis_title='Mean wait time for nurse',\n", " min_rep=31\n", ")" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -9448,1061 +1615,9 @@ }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "variable=cumulative_mean
replications=%{x}
value=%{y}", - "legendgroup": "cumulative_mean", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "cumulative_mean", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - 49.96386466177992, - 50.08145949752793, - 49.99196310572998, - 49.94948466237189, - 49.89699447400792, - 49.79589927930783, - 49.87300297633526, - 49.931989330602605, - 50.037223792844244, - 50.03321924615158, - 50.119630129686705, - 50.02235556480079, - 50.04700281148129, - 49.96689243523709, - 50.056635426565414, - 50.05911439346754, - 49.97737082046852, - 49.95312089199468, - 49.84701756881236, - 49.81231247446213 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=lower_ci
replications=%{x}
value=%{y}", - "legendgroup": "lower_ci", - "line": { - "color": "#EF553B", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "lower_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - null, - 48.587275438566635, - 49.50862524233853, - 49.662817470526655, - 49.654573981970024, - 49.477908406885305, - 49.555135666249576, - 49.63161717576598, - 49.682784952539144, - 49.72209549587158, - 49.78213317706881, - 49.65025412140204, - 49.703938191996585, - 49.60754330690671, - 49.67276821439324, - 49.70223325079497, - 49.6016115296511, - 49.5968450336042, - 49.44414447850286, - 49.424683530191686 - ], - "yaxis": "y" - }, - { - "hovertemplate": "variable=upper_ci
replications=%{x}
value=%{y}", - "legendgroup": "upper_ci", - "line": { - "color": "#00cc96", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "upper_ci", - "orientation": "v", - "showlegend": true, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20 - ], - "xaxis": "x", - "y": [ - null, - 51.575643556489226, - 50.47530096912143, - 50.23615185421712, - 50.13941496604581, - 50.11389015173036, - 50.19087028642094, - 50.23236148543923, - 50.391662633149345, - 50.344342996431585, - 50.4571270823046, - 50.39445700819954, - 50.390067430966, - 50.32624156356747, - 50.44050263873759, - 50.41599553614011, - 50.35313011128594, - 50.30939675038516, - 50.24989065912187, - 50.19994141873258 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "title": { - "text": "variable" - }, - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "shapes": [ - { - "line": { - "color": "red", - "dash": "dash" - }, - "type": "line", - "x0": 3, - "x1": 3, - "xref": "x", - "y0": 0, - "y1": 1, - "yref": "y domain" - } - ], - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Number of replications" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "adj_mean_nurse_utilisation" - } - } - } - } + "image/svg+xml": [ + "510152048.54949.55050.55151.5variablecumulative_meanlower_ciupper_ciNumber of replicationsMean nurse utilisation" + ] }, "metadata": {}, "output_type": "display_data" @@ -10510,9 +1625,11 @@ ], "source": [ "confidence_interval_method(\n", + " file='choose_param_conf_int_3.png',\n", " replications=20,\n", " metric='mean_nurse_utilisation',\n", " desired_precision=0.05,\n", + " yaxis_title='Mean nurse utilisation',\n", " min_rep=3\n", ")" ] @@ -10521,920 +1638,44 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Run time with varying number of CPU cores" + "## Run time with varying number of CPU cores\n", + "\n", + "These are rounded to the nearest .5 seconds, as we will see minor differences in run time between re-runs of this notebook on the same machine, so rounding prevents the figure from changing with every run!" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "Running with cores: 1.\n", + "Running with cores: 2.\n", + "Running with cores: 3.\n", + "Running with cores: 4.\n", + "Running with cores: 5.\n", + "Running with cores: 6.\n", + "Running with cores: 7.\n", + "Running with cores: 8.\n", " cores run_time\n", - "0 1 4.431\n", - "1 2 3.058\n", - "2 3 2.194\n", - "3 4 1.973\n", - "4 5 1.768\n", - "5 6 1.680\n", - "6 7 1.559\n", - "7 8 0.955\n" + "0 1 5.0\n", + "1 2 3.5\n", + "2 3 2.5\n", + "3 4 2.0\n", + "4 5 2.0\n", + "5 6 2.0\n", + "6 7 2.0\n", + "7 8 1.0\n" ] }, { "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hovertemplate": "cores=%{x}
run_time=%{y}", - "legendgroup": "", - "line": { - "color": "#636efa", - "dash": "solid" - }, - "marker": { - "symbol": "circle" - }, - "mode": "lines", - "name": "", - "orientation": "v", - "showlegend": false, - "type": "scatter", - "x": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8 - ], - "xaxis": "x", - "y": [ - 4.431, - 3.058, - 2.194, - 1.973, - 1.768, - 1.68, - 1.559, - 0.955 - ], - "yaxis": "y" - } - ], - "layout": { - "legend": { - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Number of cores" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "Run time (seconds)" - } - } - } - } + "image/svg+xml": [ + "1234567811.522.533.544.55Number of coresRun time (rounded to nearest .5 seconds)" + ] }, "metadata": {}, "output_type": "display_data" @@ -11444,25 +1685,32 @@ "# Run with 1 to 8 cores\n", "speed = []\n", "for i in range(1, 9):\n", + " print(f'Running with cores: {i}.')\n", " start_time = time.time()\n", "\n", " param = Defaults()\n", " param.cores = i\n", - " my_trial = Trial(param)\n", - " my_trial.run_trial()\n", + " experiment = Runner(param)\n", + " experiment.run_reps()\n", "\n", - " run_time = round((time.time() - start_time), 3)\n", + " # Round time to nearest .5 seconds\n", + " run_time = round((time.time() - start_time)*2)/2\n", " speed.append({'cores': i, 'run_time': run_time})\n", "\n", - "# Display and plot time by number of cores\n", + "# Plot time by number of cores\n", "timing_results = pd.DataFrame(speed)\n", "print(timing_results)\n", "fig = px.line(timing_results, x='cores', y='run_time')\n", "fig.update_layout(\n", " xaxis_title='Number of cores',\n", - " yaxis_title='Run time (seconds)'\n", + " yaxis_title='Run time (rounded to nearest .5 seconds)',\n", + " template='plotly_white'\n", ")\n", - "fig.show()" + "\n", + "# Display and save figure\n", + "fig.show()\n", + "fig.write_image(os.path.join(output_dir, 'choose_param_cores.png'),\n", + " width=800, height=600)" ] }, { @@ -11474,14 +1722,14 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Notebook run time: 0m 22s\n" + "Notebook run time: 0m 25s\n" ] } ], diff --git a/notebooks/generate_exp_results.ipynb b/notebooks/generate_exp_results.ipynb index 1cf2832..1ae6846 100644 --- a/notebooks/generate_exp_results.ipynb +++ b/notebooks/generate_exp_results.ipynb @@ -67,7 +67,7 @@ "outputs": [], "source": [ "# Import required packages\n", - "from simulation.model import Defaults, Trial\n", + "from simulation.model import Defaults, Runner\n", "import os\n", "import time" ] @@ -131,9 +131,9 @@ "param.scenario_name = 0\n", "param.cores = 1\n", "\n", - "# Run the trial\n", - "trial = Trial(param)\n", - "trial.run_trial()" + "# Run the replications\n", + "experiment = Runner(param)\n", + "experiment.run_reps()" ] }, { @@ -286,8 +286,8 @@ ], "source": [ "# Patient-level results\n", - "display(trial.patient_results_df)\n", - "trial.patient_results_df.to_csv(\n", + "display(experiment.patient_results_df)\n", + "experiment.patient_results_df.to_csv(\n", " os.path.join(tests, 'patient.csv'), index=False)" ] }, @@ -323,6 +323,8 @@ " mean_q_time_nurse\n", " mean_time_with_nurse\n", " mean_nurse_utilisation\n", + " mean_nurse_utilisation_tw\n", + " mean_nurse_q_length\n", " \n", " \n", " \n", @@ -334,6 +336,8 @@ " 2.065396\n", " 9.622971\n", " 0.643006\n", + " 0.643006\n", + " 0.554903\n", " \n", " \n", " 1\n", @@ -343,6 +347,8 @@ " 1.396755\n", " 10.186235\n", " 0.645640\n", + " 0.647690\n", + " 0.355707\n", " \n", " \n", " 2\n", @@ -352,6 +358,8 @@ " 3.484284\n", " 10.733822\n", " 0.660790\n", + " 0.668319\n", + " 0.858219\n", " \n", " \n", " 3\n", @@ -361,6 +369,8 @@ " 2.050522\n", " 10.511447\n", " 0.634541\n", + " 0.638407\n", + " 0.502188\n", " \n", " \n", " 4\n", @@ -370,6 +380,8 @@ " 1.836706\n", " 9.742127\n", " 0.597097\n", + " 0.601461\n", + " 0.451830\n", " \n", " \n", "\n", @@ -383,12 +395,12 @@ "3 3 0 367 2.050522 10.511447 \n", "4 4 0 369 1.836706 9.742127 \n", "\n", - " mean_nurse_utilisation \n", - "0 0.643006 \n", - "1 0.645640 \n", - "2 0.660790 \n", - "3 0.634541 \n", - "4 0.597097 " + " mean_nurse_utilisation mean_nurse_utilisation_tw mean_nurse_q_length \n", + "0 0.643006 0.643006 0.554903 \n", + "1 0.645640 0.647690 0.355707 \n", + "2 0.660790 0.668319 0.858219 \n", + "3 0.634541 0.638407 0.502188 \n", + "4 0.597097 0.601461 0.451830 " ] }, "metadata": {}, @@ -396,10 +408,10 @@ } ], "source": [ - "# Trial-level results\n", - "display(trial.trial_results_df)\n", - "trial.trial_results_df.to_csv(\n", - " os.path.join(tests, 'trial.csv'), index=False)" + "# Run results\n", + "display(experiment.run_results_df)\n", + "experiment.run_results_df.to_csv(\n", + " os.path.join(tests, 'run.csv'), index=False)" ] }, { @@ -577,8 +589,8 @@ ], "source": [ "# Interval audit results\n", - "display(trial.interval_audit_df)\n", - "trial.interval_audit_df.to_csv(\n", + "display(experiment.interval_audit_df)\n", + "experiment.interval_audit_df.to_csv(\n", " os.path.join(tests, 'interval.csv'), index=False)" ] }, @@ -612,6 +624,8 @@ " mean_q_time_nurse\n", " mean_time_with_nurse\n", " mean_nurse_utilisation\n", + " mean_nurse_utilisation_tw\n", + " mean_nurse_q_length\n", " \n", " \n", " \n", @@ -621,6 +635,8 @@ " 2.166733\n", " 10.159320\n", " 0.636215\n", + " 0.639776\n", + " 0.544569\n", " \n", " \n", " std_dev\n", @@ -628,6 +644,8 @@ " 0.784458\n", " 0.478668\n", " 0.023832\n", + " 0.024278\n", + " 0.190098\n", " \n", " \n", " lower_95_ci\n", @@ -635,6 +653,8 @@ " 1.192699\n", " 9.564976\n", " 0.606623\n", + " 0.609631\n", + " 0.308532\n", " \n", " \n", " upper_95_ci\n", @@ -642,6 +662,8 @@ " 3.140766\n", " 10.753665\n", " 0.665806\n", + " 0.669921\n", + " 0.780607\n", " \n", " \n", "\n", @@ -654,11 +676,17 @@ "lower_95_ci 359.128341 1.192699 9.564976 \n", "upper_95_ci 396.871659 3.140766 10.753665 \n", "\n", - " mean_nurse_utilisation \n", - "mean 0.636215 \n", - "std_dev 0.023832 \n", - "lower_95_ci 0.606623 \n", - "upper_95_ci 0.665806 " + " mean_nurse_utilisation mean_nurse_utilisation_tw \\\n", + "mean 0.636215 0.639776 \n", + "std_dev 0.023832 0.024278 \n", + "lower_95_ci 0.606623 0.609631 \n", + "upper_95_ci 0.665806 0.669921 \n", + "\n", + " mean_nurse_q_length \n", + "mean 0.544569 \n", + "std_dev 0.190098 \n", + "lower_95_ci 0.308532 \n", + "upper_95_ci 0.780607 " ] }, "metadata": {}, @@ -667,8 +695,8 @@ ], "source": [ "# Overall results\n", - "display(trial.overall_results_df)\n", - "trial.overall_results_df.to_csv(\n", + "display(experiment.overall_results_df)\n", + "experiment.overall_results_df.to_csv(\n", " os.path.join(tests, 'overall.csv'), index=True)" ] }, diff --git a/outputs/choose_param_conf_int_1.png b/outputs/choose_param_conf_int_1.png new file mode 100644 index 0000000..1df7b26 Binary files /dev/null and b/outputs/choose_param_conf_int_1.png differ diff --git a/outputs/choose_param_conf_int_2.png b/outputs/choose_param_conf_int_2.png new file mode 100644 index 0000000..1aae52e Binary files /dev/null and b/outputs/choose_param_conf_int_2.png differ diff --git a/outputs/choose_param_conf_int_3.png b/outputs/choose_param_conf_int_3.png new file mode 100644 index 0000000..26c64e3 Binary files /dev/null and b/outputs/choose_param_conf_int_3.png differ diff --git a/outputs/choose_param_cores.png b/outputs/choose_param_cores.png new file mode 100644 index 0000000..5693345 Binary files /dev/null and b/outputs/choose_param_cores.png differ diff --git a/outputs/choose_param_time_series_1.png b/outputs/choose_param_time_series_1.png new file mode 100644 index 0000000..cae4d17 Binary files /dev/null and b/outputs/choose_param_time_series_1.png differ diff --git a/outputs/choose_param_time_series_2.png b/outputs/choose_param_time_series_2.png new file mode 100644 index 0000000..8eba128 Binary files /dev/null and b/outputs/choose_param_time_series_2.png differ diff --git a/outputs/example_overall.csv b/outputs/example_overall.csv index 3a0741e..8deedfd 100644 --- a/outputs/example_overall.csv +++ b/outputs/example_overall.csv @@ -1,5 +1,5 @@ -arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation -10776.741935483871,0.499036905566402,9.978456743390534,0.49767035119563796 -115.80327218806197,0.06739346957542013,0.11513823236530764,0.007524465631261531 -10734.264952313013,0.47431678135150124,9.936223698796068,0.4949103549196282 -10819.21891865473,0.5237570297813028,10.020689787985,0.5004303474716477 +arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation,mean_nurse_utilisation_tw,mean_nurse_q_length +10776.741935483871,0.499036905566402,9.978456743390534,0.49767035119563796,0.497804034286856,0.12459850290556283 +115.80327218806197,0.06739346957542013,0.11513823236530764,0.007524465631261531,0.0075405891452702024,0.017212719807337778 +10734.264952313013,0.47431678135150124,9.936223698796068,0.4949103549196282,0.4950381238581607,0.11828482630760263 +10819.21891865473,0.5237570297813028,10.020689787985,0.5004303474716477,0.5005699447155513,0.13091217950352302 diff --git a/outputs/example_trial.csv b/outputs/example_run.csv similarity index 58% rename from outputs/example_trial.csv rename to outputs/example_run.csv index f5dd427..cdec45f 100644 --- a/outputs/example_trial.csv +++ b/outputs/example_run.csv @@ -1,32 +1,32 @@ -run_number,scenario,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation -0,0,10972,0.504541081338615,9.84226781662332,0.4996386466177992 -1,0,10784,0.514150649003393,10.060480983450425,0.5019905433327594 -2,0,10854,0.5232349226016817,9.925024519746302,0.4981297032213408 -3,0,10831,0.4791488631810612,9.9370571543943,0.49822049332297624 -4,0,10720,0.46145745726579823,10.015904147971671,0.4968703372055205 -5,0,10772,0.3882646868128185,9.884995942861282,0.492904233058074 -6,0,10831,0.4669381081669874,10.041799654744745,0.503356251584998 -7,0,10781,0.625888360901447,10.086979128063648,0.5034489381047406 -8,0,10772,0.4684971326393017,10.202270228377186,0.508790994907774 -9,0,10705,0.5634349862001105,10.09260227901333,0.49997178325917613 -10,0,10927,0.562585969190057,10.083553615426284,0.5098373896503802 -11,0,10688,0.39781182403365434,9.893334037740962,0.4895233535105571 -12,0,11092,0.44530362984867583,9.810905063859671,0.5034276977164731 -13,0,10640,0.4397605749351992,9.933879963761742,0.48925457544062534 -14,0,10904,0.6107822771635987,10.167683587926042,0.513130373051619 -15,0,10849,0.47670998312351787,9.975581276412813,0.5009629889699926 -16,0,10719,0.428336230071242,9.809804967118032,0.4866947365248423 -17,0,10713,0.505574486075843,9.989154604862323,0.4954087210793937 -18,0,10568,0.3615821082986753,9.800182515281657,0.4793715775153063 -19,0,10707,0.4191589720392036,9.9193906381964,0.4915291568180775 -20,0,10845,0.6120142008002236,9.813774247048583,0.49261944375555833 -21,0,10726,0.5173212645251098,9.858186468091487,0.48940978932654106 -22,0,10618,0.5316566599495316,9.969891296475984,0.4892835610032433 -23,0,10914,0.5270546197660896,9.925291785145637,0.5013818263178943 -24,0,10660,0.5029697553047842,9.96454608027881,0.49160360886911897 -25,0,10685,0.6270646900660448,10.236338445072258,0.5060501169430693 -26,0,10806,0.5061794260886525,10.039653295082593,0.5022615440123254 -27,0,10748,0.4925537687951073,10.050997027592315,0.4999546777219452 -28,0,10589,0.4577189216542841,10.044180668559221,0.4923573694687436 -29,0,10863,0.5422405738480466,10.034383892923174,0.5046064549261675 -30,0,10796,0.5102078888697092,9.922063713004379,0.49578999982774674 +run_number,scenario,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation,mean_nurse_utilisation_tw,mean_nurse_q_length +0,0,10972,0.504541081338615,9.84226781662332,0.4996386466177992,0.4997404525127849,0.12814409130665008 +1,0,10784,0.514150649003393,10.060480983450425,0.5019905433327594,0.502069010098797,0.1283472360845507 +2,0,10854,0.5232349226016817,9.925024519746302,0.4981297032213408,0.4982604514269931,0.1326692082859329 +3,0,10831,0.4791488631810612,9.9370571543943,0.49822049332297624,0.4982689502894135,0.12013104947023319 +4,0,10720,0.46145745726579823,10.015904147971671,0.4968703372055205,0.4971055007588973,0.11450981346966105 +5,0,10772,0.3882646868128185,9.884995942861282,0.492904233058074,0.4930559758823053,0.09681451866545558 +6,0,10831,0.4669381081669874,10.041799654744745,0.503356251584998,0.5034005361957391,0.11706959836936667 +7,0,10781,0.625888360901447,10.086979128063648,0.5034489381047406,0.5037422085180931,0.15619681525181714 +8,0,10772,0.4684971326393017,10.202270228377186,0.508790994907774,0.5089130015618383,0.11682062761089254 +9,0,10705,0.5634349862001105,10.09260227901333,0.49997178325917613,0.5002278075946729,0.1399966447950717 +10,0,10927,0.562585969190057,10.083553615426284,0.5098373896503802,0.5099889270180503,0.14230039086434612 +11,0,10688,0.39781182403365434,9.893334037740962,0.4895233535105571,0.48962710728052056,0.09842159202017818 +12,0,11092,0.44530362984867583,9.810905063859671,0.5034276977164731,0.5034590643983867,0.11437196007956935 +13,0,10640,0.4397605749351992,9.933879963761742,0.48925457544062534,0.4892677288083271,0.10831140086366944 +14,0,10904,0.6107822771635987,10.167683587926042,0.513130373051619,0.5135294499218972,0.1541659710692565 +15,0,10849,0.47670998312351787,9.975581276412813,0.5009629889699926,0.5010455334069686,0.11971820849321864 +16,0,10719,0.428336230071242,9.809804967118032,0.4866947365248423,0.4868274499224406,0.10628092708642692 +17,0,10713,0.505574486075843,9.989154604862323,0.4954087210793937,0.4957697619501451,0.1253754506789469 +18,0,10568,0.3615821082986753,9.800182515281657,0.4793715775153063,0.4795652084277097,0.08845369723380557 +19,0,10707,0.4191589720392036,9.9193906381964,0.4915291568180775,0.4917635127186296,0.10388738688943873 +20,0,10845,0.6120142008002236,9.813774247048583,0.49261944375555833,0.49267201493881163,0.15364106499255614 +21,0,10726,0.5173212645251098,9.858186468091487,0.48940978932654106,0.4895612849605359,0.1284441639651928 +22,0,10618,0.5316566599495316,9.969891296475984,0.4892835610032433,0.4893719186906082,0.13067431517000294 +23,0,10914,0.5270546197660896,9.925291785145637,0.5013818263178943,0.501433800156172,0.1331544935214607 +24,0,10660,0.5029697553047842,9.96454608027881,0.49160360886911897,0.49162164437257694,0.12411244424881943 +25,0,10685,0.6270646900660448,10.236338445072258,0.5060501169430693,0.5061407672693311,0.15515572552368928 +26,0,10806,0.5061794260886525,10.039653295082593,0.5022615440123254,0.5023039700989318,0.126615159220231 +27,0,10748,0.4925537687951073,10.050997027592315,0.4999546777219452,0.5001183558252156,0.12254555340300495 +28,0,10589,0.4577189216542841,10.044180668559221,0.4923573694687436,0.4923672645089264,0.11219411253234293 +29,0,10863,0.5422405738480466,10.034383892923174,0.5046064549261675,0.5047331518468727,0.13635091096554006 +30,0,10796,0.5102078888697092,9.922063713004379,0.49578999982774674,0.49597325153194355,0.12767905794112022 diff --git a/outputs/scenario_nurse_util.png b/outputs/scenario_nurse_util.png index 5f4ec00..cc3822e 100644 Binary files a/outputs/scenario_nurse_util.png and b/outputs/scenario_nurse_util.png differ diff --git a/outputs/scenario_nurse_wait.png b/outputs/scenario_nurse_wait.png index 7bea20b..f768431 100644 Binary files a/outputs/scenario_nurse_wait.png and b/outputs/scenario_nurse_wait.png differ diff --git a/outputs/sensitivity_consult_time.png b/outputs/sensitivity_consult_time.png index cc102e2..241803b 100644 Binary files a/outputs/sensitivity_consult_time.png and b/outputs/sensitivity_consult_time.png differ diff --git a/outputs/spread_arrivals.png b/outputs/spread_arrivals.png index c310678..4e08329 100644 Binary files a/outputs/spread_arrivals.png and b/outputs/spread_arrivals.png differ diff --git a/outputs/spread_nurse_time.png b/outputs/spread_nurse_time.png index 88b8860..bc6a988 100644 Binary files a/outputs/spread_nurse_time.png and b/outputs/spread_nurse_time.png differ diff --git a/outputs/spread_nurse_util.png b/outputs/spread_nurse_util.png index a0b7f03..2b9cd72 100644 Binary files a/outputs/spread_nurse_util.png and b/outputs/spread_nurse_util.png differ diff --git a/outputs/spread_nurse_wait.png b/outputs/spread_nurse_wait.png index 5080c0a..d864b5f 100644 Binary files a/outputs/spread_nurse_wait.png and b/outputs/spread_nurse_wait.png differ diff --git a/requirements.txt b/requirements.txt index 5a312ed..2a6123d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,8 @@ pip==24.3.1 plotly_express==0.4.1 pycodestyle==2.12.1 pycodestyle_magic==0.5 +pylint==3.3.3 pytest==8.3.4 +pytest-xdist==3.6.1 simpy==4.1.1 -e .[dev] \ No newline at end of file diff --git a/simulation/logging.py b/simulation/logging.py index e7744aa..1549a91 100644 --- a/simulation/logging.py +++ b/simulation/logging.py @@ -7,7 +7,7 @@ > This code is adapted from NHS Digital (2024) RAP repository template (https://github.com/NHSDigital/rap-package-template) (MIT Licence). -License: +Licence: This project is licensed under the MIT Licence. See the LICENSE file for more details. diff --git a/simulation/model.py b/simulation/model.py index 49bfbd0..2a37de8 100644 --- a/simulation/model.py +++ b/simulation/model.py @@ -9,33 +9,40 @@ > This code is adapted from Sammi Rosser and Dan Chalk (2024) HSMA - the little book of DES (https://github.com/hsma-programme/hsma6_des_book) (MIT Licence). - > The distribution class is copied from Tom Monks (2021) sim-tools: + > The Exponential class is based on Tom Monks (2021) sim-tools: fundamental tools to support the simulation process in python (https://github.com/TomMonks/sim-tools) (MIT Licence). For other distributions (bernoulli, lognormal, normal, uniform, triangular, fixed, combination, continuous empirical, erlang, weibull, gamma, beta, discrete, truncated, raw empirical, pearsonV, pearsonVI, erlangK, poisson), check out the sim-tools package. + > The MonitoredResource class is based on Tom Monks, Alison Harper and Amy + Heather (2025) An introduction to Discrete-Event Simulation (DES) using + Free and Open Source Software + (https://github.com/pythonhealthdatascience/intro-open-sim/tree/main) + (MIT Licence). They based it on the method described in Law. Simulation + Modeling and Analysis 4th Ed. Pages 14 - 17. Licence: This project is licensed under the MIT Licence. See the LICENSE file for more details. Typical usage example: - trial = Trial(param=Defaults()) - trial.run_trial() - print(trial.trial_results_df) + experiment = Runner(param=Defaults()) + experiment.run_reps() + print(experiment.run_results_df) """ +import itertools from joblib import Parallel, delayed -from simulation.logging import SimLogger import numpy as np import pandas as pd import scipy.stats as st import simpy +from simulation.logging import SimLogger -class Defaults(): +class Defaults: """ Default parameters for simulation. @@ -91,12 +98,25 @@ def __setattr__(self, name, value): """ Prevent addition of new attributes. - Only allow modification of existing attributes, and not the addition - of new attributes. This helps avoid an error where a parameter appears - to have been changed, but remains the same as the attribute name - used was incorrect. + This method overrides the default `__setattr__` behavior to restrict + the addition of new attributes to the instance. It allows modification + of existing attributes but raises an `AttributeError` if an attempt is + made to create a new attribute. This ensures that accidental typos in + attribute names do not silently create new attributes. + + Arguments: + name (str): + The name of the attribute to set. + value (Any): + The value to assign to the attribute. + + Raises: + AttributeError: + If `name` is not an existing attribute and an attempt is made + to add it to the instance. """ # Skip the check if the object is still initialising + # pylint: disable=maybe-no-member if hasattr(self, '_initialising') and self._initialising: super().__setattr__(name, value) else: @@ -116,6 +136,7 @@ def summary_stats(data): Arguments: data (pd.Series): Data to use in calculation. + Returns: tuple: (mean, standard deviation, CI lower, CI upper). """ @@ -168,6 +189,118 @@ def __init__(self, patient_id): self.time_with_nurse = np.nan +class MonitoredResource(simpy.Resource): + """ + Subclass of simpy.Resource used to monitor resource usage during the run. + + Calculates resource utilisation and the queue length during the model run. + As it is a subclass, it inherits the attributes and methods from + simpy.Resource, which is referred to as the superclass or parent class. + + Attributes: + time_last_event (float): + Time of last resource request or release. + area_n_in_queue (float): + Total time that patients have spent queueing for the resource + (i.e. sum of the times each patient spent waiting). Used to + calculate the average queue length. + area_resource_busy (float): + Total time that resources have been in use during the simulation + (i.e. sum of the times each individual resource was busy). Used + to calculated utilisation. + """ + def __init__(self, *args, **kwargs): + """ + Initialises a MonitoredResource - which involves initialising a SimPy + resource and resetting monitoring attributes. + + Arguments: + *args: + Positional arguments to be passed to the parent class. + **kwargs: + Keyword arguments to be passed to the parent class. + """ + # Initialise a SimPy Resource + super().__init__(*args, **kwargs) + # Run the init_results() method + self.init_results() + + def init_results(self): + """ + Resets monitoring attributes to initial values. + """ + self.time_last_event = self._env.now + self.area_n_in_queue = 0.0 + self.area_resource_busy = 0.0 + + def request(self, *args, **kwargs): + """ + Requests a resource, but updates time-weighted statistics BEFORE + making the request. + + Arguments: + *args: + Positional arguments to be passed to the parent class. + **kwargs: + Keyword arguments to be passed to the parent class. + + Returns: + simpy.events.Event: Event representing the request. + """ + # Update time-weighted statistics + self.update_time_weighted_stats() + # Request a resource + return super().request(*args, **kwargs) + + def release(self, *args, **kwargs): + """ + Releases a resource, but updates time-weighted statistics BEFORE + releasing it. + + Arguments: + *args: + Positional arguments to be passed to the parent class. + **kwargs: + Keyword arguments to be passed to the parent class.# + + Returns: + simpy.events.Event: Event representing the request. + """ + # Update time-weighted statistics + self.update_time_weighted_stats() + # Release a resource + return super().release(*args, **kwargs) + + def update_time_weighted_stats(self): + """ + Update the time-weighted statistics for resource usage. + + Between every request or release of the resource, it calculates the + relevant statistics - e.g.: + - Total queue time (number of requests in queue * time) + - Total resource use (number of resources in use * time) + These are summed to return the totals from across the whole simulation. + In Runner.run_single(), these are then used to calculate utilisation. + + Further details: + - These sums can be referred to as "the area under the curve". + - They are called "time-weighted" statistics as they account for how + long certain events or states (such as resource use or queue length) + persist over time. + """ + # Calculate time since last event + time_since_last_event = self._env.now - self.time_last_event + + # Update self.time_last_event to current time + self.time_last_event = self._env.now + + # Update the statistics + # len(self.queue) is the number of requests queued + self.area_n_in_queue += len(self.queue) * time_since_last_event + # self.count is the number of resources in use + self.area_resource_busy += self.count * time_since_last_event + + class Exponential: """ Generate samples from an exponential distribution. @@ -175,11 +308,8 @@ class Exponential: Attributes: mean (float): Mean of the exponential distribution. - random_seed (int|None): - Random seed to reproduce samples. - size (int|None): - Number of samples to return. If set to none, then returns a single - sample. + rand (numpy.random.Generator): + Random number generator for producing samples. """ def __init__(self, mean, random_seed): """ @@ -202,6 +332,11 @@ def sample(self, size=None): size (int|None): Number of samples to return. If set to none, then returns a single sample. + + Returns: + float or numpy.ndarray: + A single sample if size is None, or an array of samples if + size is specified. """ return self.rand.exponential(self.mean, size=size) @@ -220,8 +355,9 @@ class Model: Run number for random seed generation. env (simpy.Environment): The SimPy environment for the simulation. - nurse (simpy.Resource): - SimPy resource representing nurses. + nurse (MonitoredResource): + Subclass of SimPy resource representing nurses (whilst monitoring + the resource during the simulation run). patients (list): List containing the generated patient objects. nurse_time_used (float): @@ -259,8 +395,8 @@ def __init__(self, param, run_number): # Create simpy environment and resource self.env = simpy.Environment() - self.nurse = simpy.Resource(self.env, - capacity=self.param.number_of_nurses) + self.nurse = MonitoredResource(self.env, + capacity=self.param.number_of_nurses) # Initialise attributes to store results self.patients = [] @@ -317,14 +453,10 @@ def generate_patient_arrivals(self): p = Patient(len(self.patients) + 1) p.arrival_time = self.env.now - # If the warm-up period has passed, add the patient to the list. + # Add the patient to the list. # The list stores a reference to the patient object, so any updates # to the patient attributes will be reflected in the list as well - if self.env.now >= self.param.warm_up_period: - self.patients.append(p) - # If still during warm-up, amend ID (so not set to 1) - else: - p.patient_id = 'X (warm-up)' + self.patients.append(p) # Log arrival time self.param.logger.log( @@ -371,16 +503,15 @@ def attend_clinic(self, patient): f'{patient.time_with_nurse:.3f} minutes.' ) - # If warm-up period has passed, update the total nurse time used. + # Update the total nurse time used. # This is used to calculate utilisation. To avoid overestimation, # if the consultation would overrun the simulation, just record # time to end of the simulation. - if self.env.now >= self.param.warm_up_period: - remaining_time = ( - self.param.warm_up_period + - self.param.data_collection_period) - self.env.now - self.nurse_time_used += min( - patient.time_with_nurse, remaining_time) + remaining_time = ( + self.param.warm_up_period + + self.param.data_collection_period) - self.env.now + self.nurse_time_used += min( + patient.time_with_nurse, remaining_time) # Pass time spent with nurse yield self.env.timeout(patient.time_with_nurse) @@ -399,59 +530,103 @@ def interval_audit(self, interval): Time between audits in minutes. """ while True: - # Only save results if the warm-up period has passed - if self.env.now >= self.param.warm_up_period: - self.audit_list.append({ - 'resource_name': 'nurse', - 'simulation_time': self.env.now, - 'utilisation': self.nurse.count / self.nurse.capacity, - 'queue_length': len(self.nurse.queue), - 'running_mean_wait_time': self.running_mean_nurse_wait - }) + self.audit_list.append({ + 'resource_name': 'nurse', + 'simulation_time': self.env.now, + 'utilisation': self.nurse.count / self.nurse.capacity, + 'queue_length': len(self.nurse.queue), + 'running_mean_wait_time': self.running_mean_nurse_wait + }) # Trigger next audit after desired interval has passed yield self.env.timeout(interval) + def init_results_variables(self): + """ + Resets all results collection variables to their initial values. + """ + self.patients = [] + self.nurse_time_used = 0 + self.audit_list = [] + self.nurse.init_results() + + def warm_up_complete(self): + """ + Resets all results collection variables once warm-up period has passed. + """ + # Delay process until warm-up period has completed + yield self.env.timeout(self.param.warm_up_period) + + # Reset results collection variables + self.init_results_variables() + + # If there was a warm-up period, log that this time has passed so we + # can distinguish between patients before and after warm-up in logs + if self.param.warm_up_period > 0: + self.param.logger.log('─' * 10) + self.param.logger.log(f'{self.env.now:.2f}: Warm up complete.') + self.param.logger.log('─' * 10) + def run(self): """ Runs the simulation for the specified duration. """ - # Start patient generator + # Calculate the total run length + run_length = (self.param.warm_up_period + + self.param.data_collection_period) + + # Schedule process which will reset results when warm-up period ends + self.env.process(self.warm_up_complete()) + + # Schedule patient generator to run during simulation self.env.process(self.generate_patient_arrivals()) - # Start interval auditor + # Schedule interval auditor to run during simulation self.env.process( self.interval_audit(interval=self.param.audit_interval)) - # Run for specified duration (which is the warm-up period + the - # data collection period) - self.env.run(until=self.param.data_collection_period + - self.param.warm_up_period) + # Run the simulation + self.env.run(until=run_length) + + # If the simulation ends while resources are still in use or requests + # are still in the queue, the time between the last recorded event and + # the simulation end will not have been accounted for. Hence, we call + # update_time_weighted_stats() to run for last event --> end. + self.nurse.update_time_weighted_stats() + + # Error handling - if there was no data collection period, the + # simulation ends before it has a chance to reset the results, + # so we do so manually + if self.param.data_collection_period == 0: + self.init_results_variables() # Convert list of patient objects into a list that just contains the # attributes of each of those patients as dictionaries self.results_list = [x.__dict__ for x in self.patients] -class Trial: +class Runner: """ - Manages multiple simulation runs. + Run the simulation. + + Manages simulation runs, either running the model once or multiple times + (replications). Attributes: param (Defaults): Simulation parameters. patient_results_df (pandas.DataFrame): Dataframe to store patient-level results. - trial_results_df (pandas.DataFrame): - Dataframe to store trial-level results. + run_results_df (pandas.DataFrame): + Dataframe to store results from each run. interval_audit_df (pandas.DataFrame): Dataframe to store interval audit results. overall_results_df (pandas.DataFrame): - Dataframe to store average results from runs of the trial. + Dataframe to store average results from across the runs. """ def __init__(self, param): ''' - Initialise a new instance of the trial class. + Initialise a new instance of the Runner class. Arguments: param (Defaults): @@ -461,7 +636,7 @@ def __init__(self, param): self.param = param # Initialise empty dataframes to store results self.patient_results_df = pd.DataFrame() - self.trial_results_df = pd.DataFrame() + self.run_results_df = pd.DataFrame() self.interval_audit_df = pd.DataFrame() self.overall_results_df = pd.DataFrame() @@ -475,8 +650,8 @@ def run_single(self, run): Returns: dict: - A dictionary containing the patient-level results, trial-level - results, and interval audit results. + A dictionary containing the patient-level results, results + from each run, and interval audit results. """ # Run model model = Model(param=self.param, run_number=run) @@ -486,8 +661,9 @@ def run_single(self, run): patient_results = pd.DataFrame(model.results_list) patient_results['run'] = run - # Create dictionary recording the trial-level results - trial_results = { + # Create dictionary recording the run results + # Currently has two alternative methods of measuring utilisation + run_results = { 'run_number': run, 'scenario': self.param.scenario_name, 'arrivals': len(patient_results), @@ -495,7 +671,12 @@ def run_single(self, run): 'mean_time_with_nurse': patient_results['time_with_nurse'].mean(), 'mean_nurse_utilisation': (model.nurse_time_used / (self.param.number_of_nurses * - self.param.data_collection_period)) + self.param.data_collection_period)), + 'mean_nurse_utilisation_tw': (model.nurse.area_resource_busy / + (self.param.number_of_nurses * + self.param.data_collection_period)), + 'mean_nurse_q_length': (model.nurse.area_n_in_queue / + self.param.data_collection_period) } # Convert interval audit results to a dataframe and add run column @@ -504,16 +685,15 @@ def run_single(self, run): return { 'patient': patient_results, - 'trial': trial_results, + 'run': run_results, 'interval_audit': interval_audit_df } - def run_trial(self): + def run_reps(self): """ Execute a single model configuration for multiple runs/replications. - This is known as a trial, experiment, batch or scenario. These can be - run sequentially or in parallel. + These can be run sequentially or in parallel. """ # Sequential execution if self.param.cores == 1: @@ -528,28 +708,70 @@ def run_trial(self): # Seperate results from each run into appropriate lists patient_results_list = [ result['patient'] for result in all_results] - trial_results_list = [ - result['trial'] for result in all_results] + run_results_list = [ + result['run'] for result in all_results] interval_audit_list = [ result['interval_audit'] for result in all_results] # Convert lists into dataframes self.patient_results_df = pd.concat(patient_results_list, ignore_index=True) - self.trial_results_df = pd.DataFrame(trial_results_list) + self.run_results_df = pd.DataFrame(run_results_list) self.interval_audit_df = pd.concat(interval_audit_list, ignore_index=True) - # Calculate average results and uncertainty from across all trials + # Calculate average results and uncertainty from across all runs uncertainty_metrics = {} - trial_col = self.trial_results_df.columns + run_col = self.run_results_df.columns - # Loop through the trial-level performance measure columns + # Loop through the run performance measure columns # Calculate mean, standard deviation and 95% confidence interval - for col in trial_col[~trial_col.isin(['run_number', 'scenario'])]: + for col in run_col[~run_col.isin(['run_number', 'scenario'])]: uncertainty_metrics[col] = dict(zip( ['mean', 'std_dev', 'lower_95_ci', 'upper_95_ci'], - summary_stats(self.trial_results_df[col]) + summary_stats(self.run_results_df[col]) )) # Convert to dataframe self.overall_results_df = pd.DataFrame(uncertainty_metrics) + + +def run_scenarios(scenarios): + """ + Execute a set of scenarios and return the results from each run. + + Arguments: + scenarios (dict): + Dictionary where key is name of parameter and value is a list + with different values to run in scenarios. + + Returns: + pandas.dataframe: + Dataframe with results from each run of each scenario. + """ + # Find every possible permutation of the scenarios + all_scenarios_tuples = list(itertools.product(*scenarios.values())) + # Convert back into dictionaries + all_scenarios_dicts = [ + dict(zip(scenarios.keys(), p)) for p in all_scenarios_tuples] + # Preview some of the scenarios + print(f'There are {len(all_scenarios_dicts)} scenarios. Running:') + + # Run the scenarios... + results = [] + for index, scenario_to_run in enumerate(all_scenarios_dicts): + print(scenario_to_run) + + # Overwrite defaults from the passed dictionary + param = Defaults() + param.scenario_name = index + for key in scenario_to_run: + setattr(param, key, scenario_to_run[key]) + + # Perform replications and keep results from each run, adding the + # scenario values to the results dataframe + scenario_exp = Runner(param) + scenario_exp.run_reps() + for key in scenario_to_run: + scenario_exp.run_results_df[key] = scenario_to_run[key] + results.append(scenario_exp.run_results_df) + return pd.concat(results) diff --git a/tests/exp_results/overall.csv b/tests/exp_results/overall.csv index db7bde0..dbf57c7 100644 --- a/tests/exp_results/overall.csv +++ b/tests/exp_results/overall.csv @@ -1,5 +1,5 @@ -,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation -mean,378.0,2.1667325673589564,10.159320371752361,0.6362147508884318 -std_dev,15.198684153570664,0.7844583147114635,0.4786676748781607,0.02383218108751965 -lower_95_ci,359.12834106644124,1.192698919890132,9.564975952752244,0.606623189633386 -upper_95_ci,396.87165893355876,3.1407662148277806,10.75366479075248,0.6658063121434776 +,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation,mean_nurse_utilisation_tw,mean_nurse_q_length +mean,378.0,2.1667325673589564,10.159320371752361,0.6362147508884318,0.6397764054245421,0.5445692746656905 +std_dev,15.198684153570664,0.7844583147114635,0.4786676748781607,0.02383218108751965,0.024277980144559095,0.19009766156834382 +lower_95_ci,359.12834106644124,1.192698919890132,9.564975952752244,0.606623189633386,0.6096313115299372,0.3085318521535542 +upper_95_ci,396.87165893355876,3.1407662148277806,10.75366479075248,0.6658063121434776,0.6699214993191469,0.7806066971778267 diff --git a/tests/exp_results/run.csv b/tests/exp_results/run.csv new file mode 100644 index 0000000..b7c840d --- /dev/null +++ b/tests/exp_results/run.csv @@ -0,0 +1,6 @@ +run_number,scenario,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation,mean_nurse_utilisation_tw,mean_nurse_q_length +0,0,403,2.065395937787463,9.622970542788952,0.6430060048077357,0.6430060048077361,0.5549030419522317 +1,0,382,1.3967545762785822,10.18623477209793,0.6456396558371599,0.6476900423541169,0.35570683209227894 +2,0,369,3.4842840540548505,10.733822459914006,0.6607899582685668,0.6683185188812463,0.8582185938875108 +3,0,367,2.0505219928782124,10.511446608041043,0.6345411517895263,0.6384068134475295,0.5021881615506957 +4,0,369,1.8367062757956718,9.742127475919874,0.5970969837391709,0.6014606476320816,0.45182974384573527 diff --git a/tests/exp_results/trial.csv b/tests/exp_results/trial.csv deleted file mode 100644 index b443878..0000000 --- a/tests/exp_results/trial.csv +++ /dev/null @@ -1,6 +0,0 @@ -run_number,scenario,arrivals,mean_q_time_nurse,mean_time_with_nurse,mean_nurse_utilisation -0,0,403,2.065395937787463,9.622970542788952,0.6430060048077357 -1,0,382,1.3967545762785822,10.18623477209793,0.6456396558371599 -2,0,369,3.4842840540548505,10.733822459914006,0.6607899582685668 -3,0,367,2.0505219928782124,10.511446608041043,0.6345411517895263 -4,0,369,1.8367062757956718,9.742127475919874,0.5970969837391709 diff --git a/tests/test_backtest.py b/tests/test_backtest.py index 3bcdf4b..61d97f9 100644 --- a/tests/test_backtest.py +++ b/tests/test_backtest.py @@ -2,7 +2,7 @@ These check that the model code produces results consistent with prior code. -License: +Licence: This project is licensed under the MIT Licence. See the LICENSE file for more details. @@ -12,9 +12,9 @@ """ -from simulation.model import Defaults, Trial -import pandas as pd from pathlib import Path +import pandas as pd +from simulation.model import Defaults, Runner def test_reproduction(): @@ -34,26 +34,26 @@ def test_reproduction(): param.scenario_name = 0 param.cores = 1 - # Run the trial - trial = Trial(param) - trial.run_trial() + # Run the replications + experiment = Runner(param) + experiment.run_reps() # Compare patient-level results exp_patient = pd.read_csv( Path(__file__).parent.joinpath('exp_results/patient.csv')) - pd.testing.assert_frame_equal(trial.patient_results_df, exp_patient) + pd.testing.assert_frame_equal(experiment.patient_results_df, exp_patient) - # Compare trial-level results - exp_trial = pd.read_csv( - Path(__file__).parent.joinpath('exp_results/trial.csv')) - pd.testing.assert_frame_equal(trial.trial_results_df, exp_trial) + # Compare run results + exp_run = pd.read_csv( + Path(__file__).parent.joinpath('exp_results/run.csv')) + pd.testing.assert_frame_equal(experiment.run_results_df, exp_run) # Compare interval audit results exp_interval = pd.read_csv( Path(__file__).parent.joinpath('exp_results/interval.csv')) - pd.testing.assert_frame_equal(trial.interval_audit_df, exp_interval) + pd.testing.assert_frame_equal(experiment.interval_audit_df, exp_interval) # Compare overall results exp_overall = pd.read_csv( Path(__file__).parent.joinpath('exp_results/overall.csv'), index_col=0) - pd.testing.assert_frame_equal(trial.overall_results_df, exp_overall) + pd.testing.assert_frame_equal(experiment.overall_results_df, exp_overall) diff --git a/tests/test_unittest_logger.py b/tests/test_unittest_logger.py index 98c70cf..ef447c5 100644 --- a/tests/test_unittest_logger.py +++ b/tests/test_unittest_logger.py @@ -3,7 +3,7 @@ These check specific parts of the simulation and code, ensuring they work correctly and as expected. -License: +Licence: This project is licensed under the MIT Licence. See the LICENSE file for more details. @@ -15,9 +15,9 @@ from io import StringIO import logging import os +from unittest.mock import patch, MagicMock import pytest from simulation.logging import SimLogger -from unittest.mock import patch, MagicMock def test_log_to_console(): diff --git a/tests/test_unittest_model.py b/tests/test_unittest_model.py index 733c1ee..3e64e51 100644 --- a/tests/test_unittest_model.py +++ b/tests/test_unittest_model.py @@ -3,7 +3,7 @@ These check specific parts of the simulation and code, ensuring they work correctly and as expected. -License: +Licence: This project is licensed under the MIT Licence. See the LICENSE file for more details. @@ -12,10 +12,12 @@ pytest """ -from simulation.model import Defaults, Exponential, Model, Trial import numpy as np import pandas as pd import pytest +import simpy +from simulation.model import ( + Defaults, Exponential, Model, Runner, MonitoredResource) def test_new_attribute(): @@ -57,7 +59,7 @@ def test_negative_inputs(param_name, value, rule): # Construct the expected error message if rule == 'positive': expected_message = f'Parameter "{param_name}" must be greater than 0.' - elif rule == 'non_negative': + else: expected_message = (f'Parameter "{param_name}" must be greater than ' + 'or equal to 0.') @@ -101,18 +103,18 @@ def test_high_demand(): param = Defaults() param.number_of_nurses = 1 param.patient_inter = 0.1 - trial = Trial(param) - results = trial.run_single(run=0) + experiment = Runner(param) + results = experiment.run_single(run=0) # Check that the utilisation as calculated from total_nurse_time_used # does not exceed 1 or drop below 0 - util = results['trial']['mean_nurse_utilisation'] + util = results['run']['mean_nurse_utilisation'] assert util <= 1, ( - 'The trial `mean_nurse_utilisation` should not exceed 1, but ' + + 'The run `mean_nurse_utilisation` should not exceed 1, but ' + f'found utilisation of {util}.' ) assert util >= 0, ( - 'The trial `mean_nurse_utilisation` should not drop below 0, but ' + + 'The run `mean_nurse_utilisation` should not drop below 0, but ' + f'found utilisation of {util}.' ) @@ -186,8 +188,8 @@ def helper_warmup(warm_up_period): param.patient_inter = 1 param.warm_up_period = warm_up_period param.data_collection_period = 1500 - trial = Trial(param) - return trial.run_single(run=0) + experiment = Runner(param) + return experiment.run_single(run=0) # Run model with and without warm-up period results_warmup = helper_warmup(warm_up_period=500) @@ -201,18 +203,14 @@ def helper_warmup(warm_up_period): # and queue time greater than 0 assert first_warmup['arrival_time'] > 500, ( 'Expect first patient to arrive after time 500 when model is run ' + - f'with warm-up, but got {first_warmup["arrival_time"]}.' + f'with warm-up (length 500), but got {first_warmup["arrival_time"]}.' ) assert first_warmup['q_time_nurse'] > 0, ( 'Expect first patient to need to queue in model with warm-up and ' + f'high arrival rate, but got {first_warmup["q_time_nurse"]}.' ) - # Check that model without warm-up has arrival and queue time of 0 - assert first_none['arrival_time'] == 0, ( - 'Expect first patient to arrive at time 0 when model is run ' + - f'without warm-up, but got {first_none["arrival_time"]}.' - ) + # Check that, in model without warm-up, first patient has 0 queue time assert first_none['q_time_nurse'] == 0, ( 'Expect first patient to have no wait time in model without warm-up ' + f'but got {first_none["q_time_nurse"]}.' @@ -221,19 +219,22 @@ def helper_warmup(warm_up_period): def test_arrivals(): """ - Check that trial-level count of arrivals is consistent with the number of + Check that count of arrivals in each run is consistent with the number of patients recorded in the patient-level results. """ - trial = Trial(Defaults()) - trial.run_trial() + experiment = Runner(Defaults()) + experiment.run_reps() - # Get count of patients from patient-level and trial-level results - patient_n = trial.patient_results_df.groupby('run')['patient_id'].count() - trial_n = trial.trial_results_df['arrivals'] + # Get count of patients from patient-level and run results + patient_n = (experiment + .patient_results_df + .groupby('run')['patient_id'] + .count()) + run_n = experiment.run_results_df['arrivals'] # Compare the counts from each run - assert all(patient_n == trial_n), ( - 'The number of arrivals in the trial-level results should be ' + + assert all(patient_n == run_n), ( + 'The number of arrivals in the results from each run should be ' + 'consistent with the number of patients in the patient-level results.' ) @@ -283,9 +284,9 @@ def helper_param(param_name, value): # Modify chosen parameter for the test setattr(param, param_name, value) - # Run the trial and return the mean queue time for nurses - trial = Trial(param) - return trial.run_single(run=0)['trial'] + # Run replications and return the mean queue time for nurses + experiment = Runner(param) + return experiment.run_single(run=0)['run'] # Run model with initial and adjusted values initial_results = helper_param(param_name, initial_value) @@ -321,14 +322,14 @@ def test_arrivals_decrease(param_name, initial_value, adjusted_value): # Run model with initial value param = Defaults() setattr(param, param_name, initial_value) - trial = Trial(param) - initial_arrivals = trial.run_single(run=0)['trial']['arrivals'] + experiment = Runner(param) + initial_arrivals = experiment.run_single(run=0)['run']['arrivals'] # Run model with adjusted value param = Defaults() setattr(param, param_name, adjusted_value) - trial = Trial(param) - adjusted_arrivals = trial.run_single(run=0)['trial']['arrivals'] + experiment = Runner(param) + adjusted_arrivals = experiment.run_single(run=0)['run']['arrivals'] # Check that arrivals from adjusted model are less assert initial_arrivals > adjusted_arrivals, ( @@ -342,11 +343,11 @@ def test_seed_stability(): """ Check that two runs using the same random seed return the same results. """ - # Run trial twice, with same run number (and therefore same seed) each time - trial1 = Trial(param=Defaults()) - result1 = trial1.run_single(run=33) - trial2 = Trial(param=Defaults()) - result2 = trial2.run_single(run=33) + # Run model twice, with same run number (and therefore same seed) each time + experiment1 = Runner(param=Defaults()) + result1 = experiment1.run_single(run=33) + experiment2 = Runner(param=Defaults()) + result2 = experiment2.run_single(run=33) # Check that dataframes with patient-level results are equal pd.testing.assert_frame_equal(result1['patient'], result2['patient']) @@ -356,10 +357,10 @@ def test_interval_audit_time(): """ Check that length of interval audit is less than the length of simulation. """ - # Run single trial with default parameters and get max time from audit + # Run model once with default parameters and get max time from audit param = Defaults() - trial = Trial(param) - results = trial.run_single(run=0) + experiment = Runner(param) + results = experiment.run_single(run=0) max_time = max(results['interval_audit']['simulation_time']) # Check that max time in audit is less than simulation length @@ -378,7 +379,7 @@ def test_exponentional(): d = Exponential(mean=10, random_seed=42) # Check that sample is a float - assert type(d.sample()) == float, ( + assert isinstance(d.sample(), float), ( f'Expected sample() to return a float - instead: {type(d.sample())}' ) @@ -417,12 +418,90 @@ def test_parallel(): for mode, cores in [('seq', 1), ('par', -1)]: param = Defaults() param.cores = cores - trial = Trial(param) - results[mode] = trial.run_single(run=0) + experiment = Runner(param) + results[mode] = experiment.run_single(run=0) # Verify results are identical pd.testing.assert_frame_equal( results['seq']['patient'], results['par']['patient']) pd.testing.assert_frame_equal( results['seq']['interval_audit'], results['par']['interval_audit']) - assert results['seq']['trial'] == results['par']['trial'] + assert results['seq']['run'] == results['par']['run'] + + +def test_consistent_metrics(): + """ + Presently, the simulation code includes a few different methods to + calculate the same metrics. We would expect each to return similar results + (with a little tolerance, as expect some deviation due to methodological + differences). + """ + # Run default model + experiment = Runner(Defaults()) + experiment.run_reps() + + # Absolute tolerance (atol) = +- 0.001 + + # Check nurse utilisation + pd.testing.assert_series_equal( + experiment.run_results_df['mean_nurse_utilisation'], + experiment.run_results_df['mean_nurse_utilisation_tw'], + atol=0.001, + check_names=False) + + +def test_monitoredresource_cleanup(): + """ + Run simple example and check that the monitored resource calculations + are as expected (e.g. clean-up was performed appropriately at end of + simulation). + """ + # Simulation setup + env = simpy.Environment() + resource = MonitoredResource(env, capacity=1) + + def process_task(env, resource, duration): + """Simulate a task that requests the resource.""" + with resource.request() as req: + yield req + yield env.timeout(duration) + + # Set run length + run_length = 12 + + # Schedule tasks to occur during the simulation + env.process(process_task(env, resource, duration=5)) # Task A + env.process(process_task(env, resource, duration=10)) # Task B + env.process(process_task(env, resource, duration=15)) # Task C + + # Run the simulation + env.run(until=run_length) + + # If the simulation ends while resources are still in use or requests are + # still in the queue, the time between the last recorded event and the + # simulation end will not have been accounted for. Hence, we call + # update_time_weighted_stats() to run for time between last event and end. + resource.update_time_weighted_stats() + + # Assertions + # At time=12: + # - Task A is done (0-5) + # - Task B is still using the resource (5-15) + # - Task C is still waiting in the queue (15-30) + # Hence... + + # Expected queue time: 17, as task B (5) + task C (12) + expected_queue_time = 17.0 + + # Expected busy time: 12, as one resource busy for the whole simulation + expected_busy_time = 12.0 + + # Run assertions + assert resource.area_n_in_queue == expected_queue_time, ( + f'Expected queue time {expected_queue_time} but ' + + f'observed {resource.area_n_in_queue}.' + ) + assert resource.area_resource_busy == expected_busy_time, ( + f'Expected queue time {expected_busy_time} but ' + + f'observed {resource.area_resource_busy}.' + )