Repository: getzlab/AnnoMate (language: python)

Issue:
Update README



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/deploy_ghcr_docker.yml b/.github/workflows/deploy_ghcr_docker.yml
index c6dc6d7..efe07cb 100644
--- a/.github/workflows/deploy_ghcr_docker.yml
+++ b/.github/workflows/deploy_ghcr_docker.yml
@@ -13,3 +13,5 @@ jobs:
           docker login --username cchu70 --password ${{ secrets.GHCR_LOGIN_TOKEN }} ghcr.io
           docker build . --tag ghcr.io/getzlab/annomate:latest
           docker push ghcr.io/getzlab/annomate:latest
+
+
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..7551bdf
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,14 @@
+FROM gcr.io/broad-getzlab-workflows/base_image:v0.0.6 
+# python 3.8
+
+WORKDIR /build
+
+RUN pip install --upgrade pip
+RUN pip install AnnoMate==1.0.1
+
+# Install repository to get tutorial notebooks and example data
+RUN git clone https://github.com/getzlab/AnnoMate.git
+
+# install simulated data for example notebooks for prebuilt reviewers
+RUN git clone https://github.com/getzlab/SimulatedTumorData
+RUN pip install -e SimulatedTumorData/.
diff --git a/README.md b/README.md
index 6e09fcb..445cbc1 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,11 @@
 
 A package for using and creating interactive dashboards for manual review.
 
-![Purity AnnoMate Reviewer](https://github.com/getzlab/AnnoMate/blob/master/images/ezgif.com-gif-maker.gif)
+## Quick Start
 
-# Quick Start
+You can run the Intro_to_AnoMate_Reviewers.ipynb notebook on Google Colab: [Google Colab Intro_to_AnnoMate_Reviewers.ipynb](https://colab.research.google.com/drive/1h2XFkFZycMvRbErUBNUngSwqcY12Ryd1?usp=sharing)
+- Open the link, which gives Viewer access.
+- Next to the title of notebook it will say `Changes will not be saved`. Click the link to make a copy that is saved to your google drive.
 
 ## Install
 
@@ -12,20 +14,7 @@ A package for using and creating interactive dashboards for manual review.
 
 This is _highly_ recommended to manage different dependencies required by different reviewers.
 
-1. Install conda
-
-    Credit to Raymond Chu this article: https://medium.com/google-cloud/set-up-anaconda-under-google-cloud-vm-on-windows-f71fc1064bd7
-
-    ```
-    sudo apt-get update
-    sudo apt-get install bzip2 libxml2-dev
-
-    wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
-    bash Miniconda3-latest-Linux-x86_64.sh
-    rm Miniconda3-latest-Linux-x86_64.sh
-    source .bashrc
-    conda install scikit-learn pandas jupyter ipython
-    ```
+1. Install conda if you do not have it already<sup>1</sup>
 
 2. Create a conda environment
 
@@ -34,33 +23,28 @@ This is _highly_ recommended to manage different dependencies required by differ
     ```
     conda create --name <your_env> python==<py_version>
     ```
+    
+    `<your_env>` is the name of your environment (ie purity_review_env). Check the corresponding reviewer's `setup.py` file to get the proper python version for `py_version`. Reviewers have been tested on `3.8` and `3.9`.
+   
+4. Activate your conda environment
+   ```
+   conda activate <your_env>
+   ```
+   **You'll want your environment activated when you install AnnoMate in any of the below mentioned ways** 
 
-    `<your_env>` is the name of your environment (ie purity_review_env). Check the corresponding reviewer's `setup.py` file to get the proper python version for `py_version`.
-
-3. Add conda environment to ipykernel 
-
-    Credit to Nihal Sangeeth from StackOverflow: https://stackoverflow.com/questions/53004311/how-to-add-conda-environment-to-jupyter-lab.
-
-    ```
-    conda activate <your_env>
-    conda install ipykernel
-    ipython kernel install --user --name=<your_env>
-    conda deactivate
-    ```
+5. Add conda environment to ipykernel<sup>2</sup>
 
     When you open a jupyter notebook, you can change the environment the notebook cells are run in to `<your_env>`
-
-
-### Install AnnoMate with pip
+    
+#### Option 1: Install AnnoMate with pip
 
 If you are developing a brand new reviewer, you can install from PyPi
 
 ```
-conda activate <your_env>
 pip install AnnoMate
 ```
 
-### Install with Git
+#### Option 2: Install with Git
 
 AnnoMate and most prebuilt reviewers can be downloaded with git. 
 
@@ -70,13 +54,54 @@ cd AnnoMate
 pip install -e .
 ```
 
-### Tutorials and Documentation
+#### Option 3: Install with Conda
 
-See a more detailed tutorial in `tutorial_notebooks/Intro_to_Reviewers.ipynb`.
+Assuming you already have a conda environment and it is activated:
+```
+conda env update --name <your_env> --file annomate_conda_environment.yml
+```
+
+If you have not made a new conda environment:
+```
+conda env create --file annomate_conda_environment.yml --name <your_env>
+conda activate <your_env>
+```
+Make sure to add conda environment to ipykernel (see **4. Add conda environment to ipykernel**)
 
-View the catalog of existing reviewers at [catalog/ReviewerCatalog.ipynb](https://github.com/getzlab/AnnoMate/blob/master/catalog/ReviewerCatalog.ipynb).
+### Run with a Docker container
 
-For developers, see `tutorial_notebooks/Developer_Jupyter_Reviewer_Tutorial.ipynb`.
+Below are the commands needed to run the tutorial notebooks in a docker container. You need to open at least 2 ports if you are using Mac or Windows:
+1. A port to open jupyter lab (in this case, `<jupyter_port>`, i.e. 8890. We recommend to NOT use port 8888, and make sure to not use other ports in use)
+2. A port to open the dash app (`<dash_port>`)
+```
+docker run -it -p <jupyter_port>:<jupyter_port> -p <dash_port>:<dash_port> ghcr.io/getzlab/annomate:latest
+cd AnnoMate/tutorial_notebooks
+jupyter lab --ip 0.0.0.0 --port <jupyter_port> --no-browser --allow-root
+```
+Copy the provided link to a browser to open and run the jupyter notebooks. In the notebooks, you can set the port to open the Dash app in `reviewer.run(port=<dash_port>, ...)`.
+
+If you are running on Linux, you can open all ports.
+```
+docker run -it --network host ghcr.io/getzlab/annomate:latest
+cd AnnoMate/tutorial_notebooks
+jupyter lab --ip 0.0.0.0 --port <jupyter_port> --no-browser --allow-root
+```
+Make sure to try both available links. In the past we have been able to open the notebook using the `http://127.0.0.1` link.
+
+## Tutorials and Documentation
+
+To run tutorial notebooks, clone the repository if you have not already. If you are running from the docker container, the repo has already been cloned.
+
+```
+git clone git@github.com:getzlab/AnnoMate.git
+cd AnnoMate/tutorial_notebooks
+```
+
+Make sure to set the notebook kernels to the environment with the `AnnoMate` package.
+
+- See a more detailed tutorial in `tutorial_notebooks/Intro_to_Reviewers.ipynb`. 
+- View the catalog of existing reviewers at [catalog/ReviewerCatalog.ipynb](https://github.com/getzlab/AnnoMate/blob/master/catalog/ReviewerCatalog.ipynb).
+- For developers, see `tutorial_notebooks/Developer_Jupyter_Reviewer_Tutorial.ipynb`.
 
 ## Why AnnoMate
 ### Why and how we review data
@@ -128,3 +153,27 @@ For AnnoMate:
 - Patch: up to 5 bug fixes within 6 months
 
 Github continuous integration: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
+
+# Supplements 
+
+1. Credit to Raymond Chu this article: https://medium.com/google-cloud/set-up-anaconda-under-google-cloud-vm-on-windows-f71fc1064bd7
+
+    ```
+    sudo apt-get update
+    sudo apt-get install bzip2 libxml2-dev
+
+    wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
+    bash Miniconda3-latest-Linux-x86_64.sh
+    rm Miniconda3-latest-Linux-x86_64.sh
+    source .bashrc
+    conda install scikit-learn pandas jupyter ipython
+    ```
+    
+
+2. Credit to Nihal Sangeeth from StackOverflow: https://stackoverflow.com/questions/53004311/how-to-add-conda-environment-to-jupyter-lab.
+
+    ```
+    conda install ipykernel
+    ipython kernel install --user --name=<your_env>
+    conda deactivate
+    ```
diff --git a/annomate_conda_environment.yml b/annomate_conda_environment.yml
new file mode 100644
index 0000000..59e495d
--- /dev/null
+++ b/annomate_conda_environment.yml
@@ -0,0 +1,195 @@
+name: clean_annomate_env
+channels:
+  - defaults
+dependencies:
+  - backcall=0.2.0=pyhd3eb1b0_0
+  - ca-certificates=2023.05.30=hecd8cb5_0
+  - decorator=5.1.1=pyhd3eb1b0_0
+  - importlib_metadata=6.0.0=hd3eb1b0_0
+  - jupyter_client=8.1.0=py38hecd8cb5_0
+  - jupyter_core=5.3.0=py38hecd8cb5_0
+  - libcxx=14.0.6=h9765a3e_0
+  - libedit=3.1.20221030=h6c40b1e_0
+  - libffi=3.2.1=h0a44026_1007
+  - libsodium=1.0.18=h1de35cc_0
+  - matplotlib-inline=0.1.6=py38hecd8cb5_0
+  - ncurses=6.4=hcec6c5f_0
+  - nest-asyncio=1.5.6=py38hecd8cb5_0
+  - openssl=1.1.1u=hca72f7f_0
+  - parso=0.8.3=pyhd3eb1b0_0
+  - pexpect=4.8.0=pyhd3eb1b0_3
+  - pickleshare=0.7.5=pyhd3eb1b0_1003
+  - pip=23.1.2=py38hecd8cb5_0
+  - ptyprocess=0.7.0=pyhd3eb1b0_2
+  - pure_eval=0.2.2=pyhd3eb1b0_0
+  - pygments=2.15.1=py38hecd8cb5_1
+  - python=3.8.0=h359304d_2
+  - python-dateutil=2.8.2=pyhd3eb1b0_0
+  - pyzmq=25.1.0=py38hcec6c5f_0
+  - readline=7.0=h1de35cc_5
+  - setuptools=67.8.0=py38hecd8cb5_0
+  - six=1.16.0=pyhd3eb1b0_1
+  - sqlite=3.33.0=hffcf06c_0
+  - stack_data=0.2.0=pyhd3eb1b0_0
+  - tk=8.6.12=h5d9f67b_0
+  - typing_extensions=4.6.3=py38hecd8cb5_0
+  - wheel=0.38.4=py38hecd8cb5_0
+  - xz=5.4.2=h6c40b1e_0
+  - zeromq=4.3.4=h23ab428_0
+  - zlib=1.2.13=h4dc903c_0
+  - pip:
+    - aiohttp==3.8.4
+    - aiosignal==1.3.1
+    - annomate==1.0.0
+    - ansi2html==1.8.0
+    - anyio==3.7.0
+    - appnope==0.1.3
+    - argon2-cffi==21.3.0
+    - argon2-cffi-bindings==21.2.0
+    - arrow==1.2.3
+    - asttokens==2.2.1
+    - async-lru==2.0.2
+    - async-timeout==4.0.2
+    - attrs==23.1.0
+    - babel==2.12.1
+    - beautifulsoup4==4.12.2
+    - bleach==6.0.0
+    - blinker==1.8.2
+    - cachetools==5.3.1
+    - certifi==2023.5.7
+    - cffi==1.15.1
+    - charset-normalizer==3.1.0
+    - click==8.1.3
+    - cnv-suite==0.1.2
+    - comm==0.1.3
+    - cycler==0.11.0
+    - dash==2.17.0
+    - dash-bootstrap-components==1.4.1
+    - dash-core-components==2.0.0
+    - dash-cytoscape==0.3.0
+    - dash-daq==0.5.0
+    - dash-html-components==2.0.0
+    - dash-table==5.0.0
+    - debugpy==1.6.7
+    - defusedxml==0.7.1
+    - dill==0.3.6
+    - docutils==0.20.1
+    - exceptiongroup==1.1.1
+    - executing==1.2.0
+    - fastjsonschema==2.17.1
+    - flask==3.0.3
+    - fonttools==4.40.0
+    - fqdn==1.5.1
+    - frozendict==2.3.8
+    - frozenlist==1.3.3
+    - fsspec==2023.6.0
+    - gcsfs==2023.6.0
+    - google-api-core==2.11.1
+    - google-auth==2.21.0
+    - google-auth-oauthlib==1.0.0
+    - google-cloud-core==2.3.2
+    - google-cloud-storage==2.9.0
+    - google-crc32c==1.5.0
+    - google-resumable-media==2.5.0
+    - googleapis-common-protos==1.59.1
+    - hound==1.0.1
+    - idna==3.4
+    - importlib-metadata==6.7.0
+    - importlib-resources==5.12.0
+    - iniconfig==2.0.0
+    - intervaltree==3.1.0
+    - ipykernel==6.23.3
+    - ipython==8.12.2
+    - isoduration==20.11.0
+    - itsdangerous==2.1.2
+    - jaraco-classes==3.2.3
+    - jedi==0.18.2
+    - jinja2==3.1.2
+    - json5==0.9.14
+    - jsonpointer==2.4
+    - jsonschema==4.17.3
+    - jupyter-client==8.3.0
+    - jupyter-core==5.3.1
+    - jupyter-events==0.6.3
+    - jupyter-lsp==2.2.0
+    - jupyter-server==2.6.0
+    - jupyter-server-terminals==0.4.4
+    - jupyterlab==4.0.2
+    - jupyterlab-pygments==0.2.2
+    - jupyterlab-server==2.23.0
+    - kaleido==0.2.1
+    - keyring==24.2.0
+    - kiwisolver==1.4.4
+    - markdown-it-py==3.0.0
+    - markupsafe==2.1.3
+    - matplotlib==3.5.3
+    - mdurl==0.1.2
+    - mistune==3.0.1
+    - more-itertools==9.1.0
+    - multidict==6.0.4
+    - natsort==8.4.0
+    - nbclient==0.8.0
+    - nbconvert==7.6.0
+    - nbformat==5.9.0
+    - notebook-shim==0.2.3
+    - numpy==1.22.4
+    - oauthlib==3.2.2
+    - overrides==7.3.1
+    - packaging==23.1
+    - pandarallel==1.6.5
+    - pandas==1.5.3
+    - pandocfilters==1.5.0
+    - pillow==9.5.0
+    - pkginfo==1.9.6
+    - pkgutil-resolve-name==1.3.10
+    - platformdirs==3.8.0
+    - plotly==5.15.0
+    - pluggy==1.5.0
+    - prometheus-client==0.17.0
+    - prompt-toolkit==3.0.38
+    - protobuf==4.23.3
+    - psutil==5.9.5
+    - pyasn1==0.5.0
+    - pyasn1-modules==0.3.0
+    - pycparser==2.21
+    - pyparsing==3.1.0
+    - pyrsistent==0.19.3
+    - pytest==8.2.1
+    - python-json-logger==2.0.7
+    - pytz==2023.3
+    - pyyaml==6.0
+    - readme-renderer==40.0
+    - requests==2.31.0
+    - requests-oauthlib==1.3.1
+    - requests-toolbelt==1.0.0
+    - retrying==1.3.4
+    - rfc3339-validator==0.1.4
+    - rfc3986==2.0.0
+    - rfc3986-validator==0.1.1
+    - rich==13.4.2
+    - rsa==4.9
+    - scipy==1.8.1
+    - send2trash==1.8.2
+    - sniffio==1.3.0
+    - sortedcontainers==2.4.0
+    - soupsieve==2.4.1
+    - stack-data==0.6.2
+    - tabulate==0.9.0
+    - tenacity==8.2.2
+    - terminado==0.17.1
+    - tinycss2==1.2.1
+    - tomli==2.0.1
+    - tornado==6.3.2
+    - tqdm==4.65.0
+    - traitlets==5.9.0
+    - twine==4.0.2
+    - uri-template==1.3.0
+    - urllib3==1.26.16
+    - wcwidth==0.2.6
+    - webcolors==1.13
+    - webencodings==0.5.1
+    - websocket-client==1.6.1
+    - werkzeug==3.0.3
+    - yarl==1.9.2
+    - zipp==3.15.0
+prefix: /Users/cchu/opt/anaconda3/envs/clean_annomate_env
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..4d03473
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# method name
+METHOD_NAME="annomate"
+
+# docker build parameters (most likely, the defaults are OK)
+EXTRA_DOCKER_BUILD_ARGS=""
+DOCKER_BUILD_PATH="."
+
+#
+# DO NOT EDIT PAST THIS POINT UNLESS YOU HAVE VERY GOOD REASON TO DO SO
+#
+
+# automatically create method version number
+NCOMMIT=$(git rev-list --count HEAD)
+BRANCH=$(git rev-parse --abbrev-ref HEAD)
+
+if [[ $BRANCH == "master" ]]; then
+	BRANCH=""
+else
+	BRANCH+="_"
+fi
+VERSION=${BRANCH}v${NCOMMIT}
+
+# build method docker
+docker build -t getzlab/$METHOD_NAME:${VERSION} ${EXTRA_DOCKER_BUILD_ARGS} ${DOCKER_BUILD_PATH}
+
+# push method docker
+docker tag getzlab/$METHOD_NAME:${VERSION} gcr.io/broad-getzlab-workflows/$METHOD_NAME:${VERSION}
+docker push gcr.io/broad-getzlab-workflows/$METHOD_NAME:${VERSION}
diff --git a/setup.py b/setup.py
index 7eef355..0696ccd 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
 
 setuptools.setup(
     name="AnnoMate",
-    version="1.0.0",
+    version="1.0.1",
     author="Claudia Chu",
     author_email="cchu@broadinstitute.org",
     description="A general tool to create dashboards for manual review",
@@ -23,7 +23,8 @@
     package_dir={"": "."},
     packages=setuptools.find_packages(where=".", exclude=['zeption.examples', '']),
     python_requires=">=3.8", # last tested version: 3.9
-    install_requires = ['cnv-suite',
+    install_requires = ['setuptools<60.0', # https://numpy.org/doc/stable/reference/distutils_status_migration.html. Install before numpy
+                        'cnv-suite>=0.2.0',
                         'dash>=2.11.0',
                         'dash-bootstrap-components',
                         'dash-cytoscape',
@@ -43,7 +44,6 @@
                         'pip',
                         'plotly>=5.15.0',
                         'scipy',
-                        'setuptools',
                         'frozendict',
                         # fixes jupyter-dash bug when repeat calls to run_server hangs
                         'flask>=3.0.3',
diff --git a/tutorial_notebooks/Developer_AnnoMate_Tutorial.ipynb b/tutorial_notebooks/Developer_AnnoMate_Tutorial.ipynb
index d0e305f..e2983bc 100644
--- a/tutorial_notebooks/Developer_AnnoMate_Tutorial.ipynb
+++ b/tutorial_notebooks/Developer_AnnoMate_Tutorial.ipynb
@@ -7,9 +7,21 @@
    "source": [
     "# Developer AnnoMate Tutorial\n",
     "\n",
-    "This tutorial is for developers who want to make a Reviewer object from scratch.\n",
+    "This tutorial is for developers who want to make a Reviewer object from scratch. \n",
     "\n",
-    "If you are looking to use a pre-made Reviewer, refer to the README.md file.\n"
+    "- If you just want to get a reviewer running and get familiar with the major built-in features of AnnoMate, see `Quick_Example_AnnoMate_Reviewer.ipynb`\n",
+    "- If you want to know more details on what AnnoMate reviewers are and extensive documentation of its features, see `Intro_to_AnnoMate_Reviewers.ipynb`\n",
+    "- We recommend using pre-built reviewers if **one already exists** for a task you want to perform and/or **you consider yourself less technically experienced.** See the [AnnnoMate Reviewer Catalog](https://github.com/getzlab/AnnoMate/blob/master/catalog/README.md) for existing reviewers.\n",
+    "\n",
+    "## Prerequistes:\n",
+    "- User is familiar with executing cells in jupyter notebooks and consider themselves **intermediate - advanced level python**\n",
+    "- User wants to create a new reviewer from scratch, or make substantion additions (i.e. adding interactive components) to existing pre-built reviewers\n",
+    "\n",
+    "## Outcomes:\n",
+    "- Learn the architecture of pre-built AnnoMate reviewers\n",
+    "- Learn how to add annotations\n",
+    "- Learn how to add custom interactive components in a new or pre-built reviewer\n",
+    "- Learn how to submit a custom reviewer to the catalog"
    ]
   },
   {
@@ -854,7 +866,7 @@
     "    print('making new directory')\n",
     "    os.mkdir(data_dir)\n",
     "\n",
-    "data_pkl_fn = f'{data_dir}/Prebuilt_reviewer.Dev_Reviewer.pkl'"
+    "data_path = f'{data_dir}/Prebuilt_reviewer'"
    ]
   },
   {
@@ -884,7 +896,7 @@
    "source": [
     "test_reviewer = PrebuiltReviewer()\n",
     "test_reviewer.set_review_data(\n",
-    "    data_pkl_fn = data_pkl_fn, \n",
+    "    data_path = data_path, \n",
     "    description='testing', \n",
     "    df = df,\n",
     "    index=df.index, \n",
@@ -1174,10 +1186,10 @@
    ],
    "source": [
     "# User can reuse the app\n",
-    "second_data_pkl_fn = f'{data_dir}/Prebuilt_reviewer.Dev_Reviewer_2.pkl'\n",
+    "second_data_path = f'{data_dir}/Prebuilt_reviewer_2'\n",
     "another_reviewer = PrebuiltReviewer()\n",
     "another_reviewer.set_review_data(\n",
-    "    data_pkl_fn = second_data_pkl_fn, \n",
+    "    data_path = second_data_path, \n",
     "    description='testing copy annotations', \n",
     "    df=test_reviewer.get_data_attribute('df'),\n",
     "    index=test_reviewer.get_data_attribute('df').index, \n",
diff --git a/tutorial_notebooks/Intro_to_AnnoMate_Reviewers.ipynb b/tutorial_notebooks/Intro_to_AnnoMate_Reviewers.ipynb
index 9bb74af..4cf8dd9 100644
--- a/tutorial_notebooks/Intro_to_AnnoMate_Reviewers.ipynb
+++ b/tutorial_notebooks/Intro_to_AnnoMate_Reviewers.ipynb
@@ -9,11 +9,20 @@
    "source": [
     "# Intro to AnnoMate Reviewers\n",
     "\n",
-    "All `Reviewer` types in this package follow the same general framework for setting up the dashboard. \n",
+    "All `Reviewer` types in this package follow the same general framework for setting up the dashboard. This notebook will walk you through how to interact with a basic reviewer, which extends to other `Reviewer` types.\n",
     "\n",
-    "This notebook will walk you through how to interact with a basic reviewer, which extends to other `Reviewer` types.\n",
+    "- If you want to know how to **create** your own custom reviewer, see `Developer_AnnoMate_Tutorial.ipynb`\n",
+    "- If you just want to get a reviewer running and get familiar with the major built-in features of AnnoMate, see `Quick_Example_AnnoMate_Reviewer.ipynb`\n",
+    "- We recommend using pre-built reviewers if **one already exists** for a task you want to perform and/or **you consider yourself less technically experienced.** See the [AnnnoMate Reviewer Catalog](https://github.com/getzlab/AnnoMate/blob/master/catalog/README.md) for existing reviewers.\n",
     "\n",
-    "If you want to know how to **create** your own custom reviewer, see `Developer_AnnoMate_Tutorial`"
+    "## Prerequistes:\n",
+    "- User is familiar with executing cells in jupyter notebooks and consider themselves **beginner - intermeidate level python**\n",
+    "- User wants to learn **all** of the built-in functionality of customizing pre-built Annomate Reviewers and details.\n",
+    "\n",
+    "## Outcomes:\n",
+    "- Get a basic AnnoMate reviewer running\n",
+    "- Learn how one can reuse previous annotations to create a new reviewer\n",
+    "- Learn **all** the built in features to update the dashboard in the notebook directly"
    ]
   },
   {
@@ -50,6 +59,21 @@
     "1. Install package: `pip install -e .`"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "e637c8ae-2ca2-487a-9522-de96383ae80f",
+   "metadata": {},
+   "source": [
+    "Running from docker container: You need to open at least 2 ports if you are using Mac or Windows:\n",
+    "1. A port to open jupyter lab (in this case, `<jupyter_port>`)\n",
+    "2. A port to open the dash app (`<dash_port>`)\n",
+    "```\n",
+    "docker run -it -p <jupyter_port>:<jupyter_port> -p <dash_port>:<dash_port> gcr.io/broad-getzlab-workflows/annomate:dev_branch_v385\n",
+    "cd AnnoMate/tutorial_notebooks\n",
+    "jupyter lab --ip 0.0.0.0 --port <jupyter_port> --no-browser --allow-root\n",
+    "```"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "6429e242-eb91-4419-ba41-3b63e6f1ae6d",
@@ -204,7 +228,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 53,
+   "execution_count": 4,
    "id": "8933f1a7",
    "metadata": {},
    "outputs": [],
@@ -474,10 +498,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 7,
    "id": "f7fd1f9d-d9f1-44c4-b9f9-d20d667a3d7e",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataInterface.py:41: UserWarning: Loading existing data pkl file\n",
+      "  warnings.warn(f\"Loading existing data pkl file\")\n"
+     ]
+    }
+   ],
    "source": [
     "output_pkl_path = './example_reviewer_data'\n",
     "my_reviewer.set_review_data(data_path=output_pkl_path, \n",
@@ -509,7 +542,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 8,
    "id": "32ab23ca-c27d-4c0d-9149-08c24b244d26",
    "metadata": {},
    "outputs": [
@@ -519,7 +552,7 @@
        "dict_keys(['index', 'description', 'annot_col_config_dict', 'annot_df', 'history_df', 'df'])"
       ]
      },
-     "execution_count": 17,
+     "execution_count": 8,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -530,7 +563,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 9,
    "id": "161965c4",
    "metadata": {},
    "outputs": [
@@ -656,7 +689,7 @@
        "sample_4   Testing preprocessing  "
       ]
      },
-     "execution_count": 18,
+     "execution_count": 9,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -679,7 +712,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 10,
    "id": "cdc0779a",
    "metadata": {},
    "outputs": [],
@@ -700,7 +733,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 11,
    "id": "2875d634",
    "metadata": {},
    "outputs": [],
@@ -711,20 +744,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 12,
    "id": "6f611126-58d6-48b7-a056-01737bc2b263",
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
-      "\n",
-      "Data is not frozen. Annotations will not be saved. Please freeze data in the dashboard to save annotations.\n",
-      "\n"
-     ]
-    },
     {
      "data": {
       "text/html": [
@@ -754,42 +777,42 @@
        "    <tr>\n",
        "      <th>sample_0</th>\n",
        "      <td></td>\n",
-       "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_1</th>\n",
        "      <td></td>\n",
-       "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_2</th>\n",
-       "      <td></td>\n",
-       "      <td></td>\n",
+       "      <td>Nothing to say</td>\n",
+       "      <td>Keep</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_3</th>\n",
        "      <td></td>\n",
-       "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_4</th>\n",
-       "      <td></td>\n",
-       "      <td></td>\n",
+       "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "text/plain": [
-       "         Notes Flag\n",
-       "sample_0           \n",
-       "sample_1           \n",
-       "sample_2           \n",
-       "sample_3           \n",
-       "sample_4           "
+       "                   Notes    Flag\n",
+       "sample_0                  Remove\n",
+       "sample_1                  Remove\n",
+       "sample_2  Nothing to say    Keep\n",
+       "sample_3                  Remove\n",
+       "sample_4        Not good  Remove"
       ]
      },
-     "execution_count": 21,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -800,20 +823,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 13,
    "id": "2be96b08-e7c6-477a-812b-a3a7c39d9128",
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:485: UserWarning:\n",
-      "\n",
-      "Data is not frozen. History will not be saved. Please freeze data in the dashboard to save history.\n",
-      "\n"
-     ]
-    },
     {
      "data": {
       "text/html": [
@@ -843,17 +856,67 @@
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_0</td>\n",
+       "      <td>2024-05-29 11:21:53.051037</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_1</td>\n",
+       "      <td>2024-05-29 11:21:56.466574</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_2</td>\n",
+       "      <td>2024-05-29 11:22:02.213915</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td>Nothing to say</td>\n",
+       "      <td>Keep</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_3</td>\n",
+       "      <td>2024-05-29 11:22:05.466076</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_4</td>\n",
+       "      <td>2024-05-29 11:22:12.998607</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
+       "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "text/plain": [
-       "Empty DataFrame\n",
-       "Columns: [index, timestamp, source_data_fn, Notes, Flag]\n",
-       "Index: []"
+       "      index                  timestamp                    source_data_fn  \\\n",
+       "0  sample_0 2024-05-29 11:21:53.051037  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_1 2024-05-29 11:21:56.466574  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_2 2024-05-29 11:22:02.213915  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_3 2024-05-29 11:22:05.466076  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_4 2024-05-29 11:22:12.998607  ./example_reviewer_data/data.pkl   \n",
+       "\n",
+       "            Notes    Flag  \n",
+       "0                  Remove  \n",
+       "0                  Remove  \n",
+       "0  Nothing to say    Keep  \n",
+       "0                  Remove  \n",
+       "0        Not good  Remove  "
       ]
      },
-     "execution_count": 22,
+     "execution_count": 13,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -876,7 +939,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 14,
    "id": "b00fd0cf",
    "metadata": {},
    "outputs": [
@@ -889,16 +952,6 @@
       "Dash app running on http://0.0.0.0:8055/\n"
      ]
     },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
-      "\n",
-      "You are in test mode. Your data will not be saved.\n",
-      "\n"
-     ]
-    },
     {
      "data": {
       "application/javascript": [
@@ -923,7 +976,12 @@
    "source": [
     "> **If you are using a VM:** Make sure to open a ssh tunnel to the specified port number\n",
     "> - `~C` to open the ssh prompt (will look like `ssh>`)\n",
-    "> - Type and enter `-L <port number>:localhost:<port number>`"
+    "> - Type and enter `-L <port number>:localhost:<port number>`\n",
+    "\n",
+    "> **If you are running from a docker container:** Make sure to open the port for accessing the dash app (`reviewer.run(port=<new_port_number>, ...)`) when you open the container\n",
+    "> - `docker run -it -p <jupyter_port>:<jupyter_port> -p <dash_port>:<dash_port> gcr.io/broad-getzlab-workflows/annomate:dev_branch_v385`\n",
+    "> - You can add more ports by adding more `-p <port_number>:<port_number>` arguments\n",
+    "> - If you are on Linux, you can replace `-p` arguments with `--network host`"
    ]
   },
   {
@@ -949,20 +1007,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 15,
    "id": "8bff62a2",
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
-      "\n",
-      "Data is not frozen. Annotations will not be saved. Please freeze data in the dashboard to save annotations.\n",
-      "\n"
-     ]
-    },
     {
      "data": {
       "text/html": [
@@ -1027,7 +1075,7 @@
        "sample_4        Not good  Remove"
       ]
      },
-     "execution_count": 24,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1039,20 +1087,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 16,
    "id": "852bf6fa-9016-493a-89e9-cfa29e37d9c1",
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:485: UserWarning:\n",
-      "\n",
-      "Data is not frozen. History will not be saved. Please freeze data in the dashboard to save history.\n",
-      "\n"
-     ]
-    },
     {
      "data": {
       "text/html": [
@@ -1142,7 +1180,7 @@
        "0        Not good  Remove  "
       ]
      },
-     "execution_count": 25,
+     "execution_count": 16,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1191,7 +1229,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 17,
    "id": "725efe31",
    "metadata": {},
    "outputs": [
@@ -1199,17 +1237,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Export directory will be data/example_reviewer_data/2024-05-29. Nothing exported yet.\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:513: UserWarning:\n",
-      "\n",
-      "Directory data/example_reviewer_data/2024-05-29 already exists\n",
-      "\n"
+      "Making new directory data/example_reviewer_data/2024-06-03\n",
+      "Export directory will be data/example_reviewer_data/2024-06-03. Nothing exported yet.\n"
      ]
     }
    ],
@@ -1223,7 +1252,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 18,
    "id": "e26441c4-57df-4d06-b8cb-915f97dc9c56",
    "metadata": {},
    "outputs": [
@@ -1234,10 +1263,20 @@
       "index is not a dataframe. Not exporting.\n",
       "description is not a dataframe. Not exporting.\n",
       "annot_col_config_dict is not a dataframe. Not exporting.\n",
-      "Saving annot_df to data/example_reviewer_data/2024-05-29/annot_df.tsv\n",
-      "Saving history_df to data/example_reviewer_data/2024-05-29/history_df.tsv\n",
-      "Saving df to data/example_reviewer_data/2024-05-29/df.tsv\n",
-      "Exported to data/example_reviewer_data/2024-05-29\n"
+      "Saving annot_df to data/example_reviewer_data/2024-06-03/annot_df.tsv\n",
+      "Saving history_df to data/example_reviewer_data/2024-06-03/history_df.tsv\n",
+      "Saving df to data/example_reviewer_data/2024-06-03/df.tsv\n",
+      "Exported to data/example_reviewer_data/2024-06-03\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewerTemplate.py:513: UserWarning:\n",
+      "\n",
+      "Directory data/example_reviewer_data/2024-06-03 already exists\n",
+      "\n"
      ]
     }
    ],
@@ -1270,7 +1309,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 19,
    "id": "cec30f2c",
    "metadata": {},
    "outputs": [],
@@ -1290,7 +1329,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 20,
    "id": "1cf5f2b7",
    "metadata": {},
    "outputs": [
@@ -1339,7 +1378,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 21,
    "id": "bcaac9d1",
    "metadata": {},
    "outputs": [
@@ -1365,7 +1404,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 22,
    "id": "386d24d6-311c-4678-9832-503aadd8e058",
    "metadata": {},
    "outputs": [
@@ -1373,7 +1412,7 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
       "\n",
       "Data is not frozen. Annotations will not be saved. Please freeze data in the dashboard to save annotations.\n",
       "\n"
@@ -1400,44 +1439,44 @@
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
-       "      <th>Flag</th>\n",
        "      <th>Notes</th>\n",
+       "      <th>Flag</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>sample_0</th>\n",
-       "      <td>Remove</td>\n",
        "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_1</th>\n",
-       "      <td>Remove</td>\n",
        "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_3</th>\n",
-       "      <td>Remove</td>\n",
        "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_4</th>\n",
-       "      <td>Remove</td>\n",
        "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "text/plain": [
-       "            Flag     Notes\n",
-       "sample_0  Remove          \n",
-       "sample_1  Remove          \n",
-       "sample_3  Remove          \n",
-       "sample_4  Remove  Not good"
+       "             Notes    Flag\n",
+       "sample_0            Remove\n",
+       "sample_1            Remove\n",
+       "sample_3            Remove\n",
+       "sample_4  Not good  Remove"
       ]
      },
-     "execution_count": 32,
+     "execution_count": 22,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1462,7 +1501,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 23,
    "id": "1e23f569",
    "metadata": {},
    "outputs": [],
@@ -1485,7 +1524,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 24,
    "id": "f44d22bb",
    "metadata": {},
    "outputs": [
@@ -1545,7 +1584,7 @@
        "2  Anthracycline  remission       203"
       ]
      },
-     "execution_count": 34,
+     "execution_count": 24,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1556,7 +1595,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 25,
    "id": "9fd80758",
    "metadata": {},
    "outputs": [],
@@ -1575,7 +1614,7 @@
    "id": "852f94ae",
    "metadata": {},
    "source": [
-    "## 5. Set up settings\n",
+    "### 5. Set up settings\n",
     "\n",
     "Above, we just used default settings already implemented for us. This included what annotations to record and how they are displayed in the app. \n",
     "\n",
@@ -1596,7 +1635,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 26,
    "id": "b89c3fea-2afd-4075-a473-e8a85fcc7f5c",
    "metadata": {},
    "outputs": [],
@@ -1608,7 +1647,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 27,
    "id": "6153a01e-65d4-4300-a06e-b005ef474990",
    "metadata": {},
    "outputs": [],
@@ -1618,7 +1657,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 28,
    "id": "9849c027-aa61-45e5-a70d-76abe4142cd9",
    "metadata": {},
    "outputs": [],
@@ -1666,7 +1705,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": 29,
    "id": "3f91079d-0084-4abf-a4b0-ecb292e65d7f",
    "metadata": {},
    "outputs": [],
@@ -1744,7 +1783,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 30,
    "id": "7d013fe3-fd80-49de-818f-29a2748722b7",
    "metadata": {},
    "outputs": [
@@ -1754,7 +1793,7 @@
        "True"
       ]
      },
-     "execution_count": 40,
+     "execution_count": 30,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1775,7 +1814,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 31,
    "id": "f1e83bc2-f597-4e80-82f4-558265058096",
    "metadata": {},
    "outputs": [
@@ -1785,7 +1824,7 @@
        "False"
       ]
      },
-     "execution_count": 41,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1808,7 +1847,7 @@
    "id": "7a4f78c5",
    "metadata": {},
    "source": [
-    "### 5.1 Autofill\n",
+    "#### 5.1 Autofill\n",
     "\n",
     "Sometimes there are parts of the dashboard that can calculate annotations on the fly. In this case, say we want to record what color the histogram plot was last plotted with. It would be tedious and error prone for a reviewer to have to keep copying data into the correpsonding input. \n",
     "\n",
@@ -1826,7 +1865,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 42,
+   "execution_count": 32,
    "id": "67cb42cd",
    "metadata": {},
    "outputs": [],
@@ -1849,7 +1888,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 33,
    "id": "7871969b",
    "metadata": {},
    "outputs": [
@@ -1858,7 +1897,6 @@
      "output_type": "stream",
      "text": [
       "Setting auto_export_path to ./example_reviewer_data_removed/data.auto_export\n",
-      "Making directory ./example_reviewer_data_removed/data.auto_export for auto exporting.\n",
       "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n",
       "Dash app running on http://0.0.0.0:8052/\n"
      ]
@@ -1867,7 +1905,7 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
       "\n",
       "You are in test mode. Your data will not be saved.\n",
       "\n"
@@ -1908,7 +1946,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 52,
+   "execution_count": 34,
    "id": "b7630df3-40b5-4e8a-9638-cdf4cd59022b",
    "metadata": {},
    "outputs": [
@@ -1917,26 +1955,20 @@
      "output_type": "stream",
      "text": [
       "Setting auto_export_path to ./example_reviewer_data_removed/data.auto_export\n",
-      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n"
+      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n",
+      "Dash app running on http://0.0.0.0:8052/\n"
      ]
     },
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
       "\n",
       "You are in test mode. Your data will not be saved.\n",
       "\n"
      ]
     },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Dash app running on http://0.0.0.0:8052/\n"
-     ]
-    },
     {
      "data": {
       "application/javascript": [
@@ -1961,7 +1993,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 44,
+   "execution_count": 35,
    "id": "83dee02a-8415-4a1c-9b85-b2598883a0c7",
    "metadata": {},
    "outputs": [
@@ -1969,7 +2001,7 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewerTemplate.py:477: UserWarning:\n",
       "\n",
       "Data is not frozen. Annotations will not be saved. Please freeze data in the dashboard to save annotations.\n",
       "\n"
@@ -1996,8 +2028,8 @@
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
-       "      <th>Flag</th>\n",
        "      <th>Notes</th>\n",
+       "      <th>Flag</th>\n",
        "      <th>Histogram color</th>\n",
        "      <th>A Number</th>\n",
        "      <th>A radioitem</th>\n",
@@ -2010,44 +2042,44 @@
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>sample_0</th>\n",
-       "      <td>Report</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "      <td></td>\n",
        "      <td></td>\n",
        "      <td></td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>Option b</td>\n",
-       "      <td>[Option 1, Option 3]</td>\n",
        "      <td></td>\n",
-       "      <td>[Option y, Option z]</td>\n",
        "      <td>NaN</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_1</th>\n",
+       "      <td></td>\n",
        "      <td>Remove</td>\n",
        "      <td></td>\n",
-       "      <td>red</td>\n",
-       "      <td>10.0</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
        "      <td></td>\n",
-       "      <td>[Option 1]</td>\n",
-       "      <td>Option C</td>\n",
-       "      <td>[Option x]</td>\n",
        "      <td>NaN</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_3</th>\n",
-       "      <td>Keep</td>\n",
        "      <td></td>\n",
+       "      <td>Remove</td>\n",
        "      <td></td>\n",
        "      <td>NaN</td>\n",
-       "      <td>Option a</td>\n",
-       "      <td>[Option 1]</td>\n",
-       "      <td>Option B</td>\n",
-       "      <td>[]</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
        "      <td>NaN</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>sample_4</th>\n",
-       "      <td>Remove</td>\n",
        "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
        "      <td></td>\n",
        "      <td>NaN</td>\n",
        "      <td></td>\n",
@@ -2061,17 +2093,17 @@
        "</div>"
       ],
       "text/plain": [
-       "            Flag     Notes Histogram color  A Number A radioitem  \\\n",
-       "sample_0  Report                                 1.0    Option b   \n",
-       "sample_1  Remove                       red      10.0               \n",
-       "sample_3    Keep                                 NaN    Option a   \n",
-       "sample_4  Remove  Not good                       NaN               \n",
+       "             Notes    Flag Histogram color  A Number A radioitem A checklist  \\\n",
+       "sample_0            Remove                       NaN                           \n",
+       "sample_1            Remove                       NaN                           \n",
+       "sample_3            Remove                       NaN                           \n",
+       "sample_4  Not good  Remove                       NaN                           \n",
        "\n",
-       "                   A checklist A dropdown menu A multi-select dropdown menu  \\\n",
-       "sample_0  [Option 1, Option 3]                         [Option y, Option z]   \n",
-       "sample_1            [Option 1]        Option C                   [Option x]   \n",
-       "sample_3            [Option 1]        Option B                           []   \n",
-       "sample_4                                                                      \n",
+       "         A dropdown menu A multi-select dropdown menu  \\\n",
+       "sample_0                                                \n",
+       "sample_1                                                \n",
+       "sample_3                                                \n",
+       "sample_4                                                \n",
        "\n",
        "          Test removing annotation  \n",
        "sample_0                       NaN  \n",
@@ -2080,7 +2112,7 @@
        "sample_4                       NaN  "
       ]
      },
-     "execution_count": 44,
+     "execution_count": 35,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2117,7 +2149,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
+   "execution_count": 36,
    "id": "d05f523a-a3d6-4ae0-8279-c9d115a2ecf8",
    "metadata": {},
    "outputs": [
@@ -2126,25 +2158,19 @@
      "output_type": "stream",
      "text": [
       "Setting auto_export_path to ./example_reviewer_data_removed/data.auto_export\n",
-      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n"
+      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n",
+      "Dash app running on http://0.0.0.0:8052/\n"
      ]
     },
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
       "\n",
       "You are in test mode. Your data will not be saved.\n",
       "\n"
      ]
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Dash app running on http://0.0.0.0:8052/\n"
-     ]
     }
    ],
    "source": [
@@ -2174,7 +2200,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 46,
+   "execution_count": 37,
    "id": "8e272002-5cb0-4017-9189-385ba1fe47e4",
    "metadata": {},
    "outputs": [
@@ -2184,7 +2210,7 @@
        "odict_keys(['sample-info-component', 'Maf file', 'Mut vafs', 'Treatment file'])"
       ]
      },
-     "execution_count": 46,
+     "execution_count": 37,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2203,7 +2229,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 51,
+   "execution_count": 38,
    "id": "068c61f2-ecd0-467c-a9e9-6894fbf16730",
    "metadata": {},
    "outputs": [
@@ -2212,19 +2238,25 @@
      "output_type": "stream",
      "text": [
       "Setting auto_export_path to ./example_reviewer_data_removed/data.auto_export\n",
-      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n",
-      "Dash app running on http://0.0.0.0:8052/\n"
+      "Using ./example_reviewer_data_removed/data.auto_export for auto exporting.\n"
      ]
     },
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/cchu/Desktop/Methods/AnnoMate/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataApp.py:738: UserWarning:\n",
       "\n",
       "You are in test mode. Your data will not be saved.\n",
       "\n"
      ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Dash app running on http://0.0.0.0:8052/\n"
+     ]
     }
    ],
    "source": [
@@ -2241,7 +2273,7 @@
    "source": [
     "**NOTE**: Some reviewers may have components that listen to each other, so if you keep one but not the other, some of the predefined interactivity may lead to error messages. You may run into similar errors for autofill buttons which may be pulling data from components that are excluded. \n",
     "\n",
-    "Also, the data needed to rendered excluded components will still be required when setting the review data (`reviewer.set_review_data(...)`)."
+    "Also, the data needed to render excluded components will still be required when setting the review data (`reviewer.set_review_data(...)`)."
    ]
   },
   {
@@ -2262,9 +2294,9 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python [conda env:test_annomate_install_env]",
+   "display_name": "Python [conda env:test]",
    "language": "python",
-   "name": "conda-env-test_annomate_install_env-py"
+   "name": "conda-env-test-py"
   },
   "language_info": {
    "codemirror_mode": {
diff --git a/tutorial_notebooks/Quick_Example_AnnoMate_Reviewer.ipynb b/tutorial_notebooks/Quick_Example_AnnoMate_Reviewer.ipynb
new file mode 100644
index 0000000..324e044
--- /dev/null
+++ b/tutorial_notebooks/Quick_Example_AnnoMate_Reviewer.ipynb
@@ -0,0 +1,817 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "d2aedd2d-b1d5-4d2d-8e95-61ff06292438",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "# Quick Example AnnoMate Reviewer\n",
+    "\n",
+    "This notebook demonstrates how to run an example reviewer built on AnnoMate. \n",
+    "\n",
+    "- If you want to know more details on what AnnoMate reviewers are and extensive documentation of its features, see `Intro_to_AnnoMate_Reviewers.ipynb`\n",
+    "- If you want to know how to **create** your own custom reviewer, see `Developer_AnnoMate_Tutorial.ipynb`\n",
+    "- We recommend using pre-built reviewers if **one already exists** for a task you want to perform and/or **you consider yourself less technically experienced.** See the [AnnnoMate Reviewer Catalog](https://github.com/getzlab/AnnoMate/blob/master/catalog/README.md) for existing reviewers.\n",
+    "\n",
+    "## Prerequistes:\n",
+    "- User is familiar with executing cells in jupyter notebooks and consider themselves **beginner - intermeidate level python**\n",
+    "- User wants to learn some of the basic built-in functionality of customizing pre-built Annomate Reviewers\n",
+    "\n",
+    "## Outcomes:\n",
+    "- Get a basic AnnoMate reviewer running\n",
+    "- Learn some of the features to update the dashboard in the notebook directly"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "670b8f2a-af59-4f15-8551-fa038ea8849e",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "## Installation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9e1078a8-0e56-4642-9b6f-3610ddf1377f",
+   "metadata": {},
+   "source": [
+    "Option 1: Using pypi (recommended)\n",
+    "1. Create an environment: `conda create --name <my-env> --file requirements.txt python==3.8`\n",
+    "1. Activate environment: `conda activate <my-env>`\n",
+    "1. Install AnnoMate: `pip install AnnoMate`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "49d4fe42-17fe-4ea6-aaa7-85b7c0718788",
+   "metadata": {},
+   "source": [
+    "Option 2: Using git\n",
+    "1. Download the repository: `git clone git@github.com:getzlab/AnnoMate.git` \n",
+    "1. `cd AnnoMate`\n",
+    "1. Create an environment: `conda create --name <my-env> --file requirements.txt python==3.8`\n",
+    "1. Activate environment: `conda activate <my-env>`\n",
+    "1. Install package: `pip install -e .`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e637c8ae-2ca2-487a-9522-de96383ae80f",
+   "metadata": {},
+   "source": [
+    "Option 3: Running from docker container. You need to open at least 2 ports if you are using Mac or Windows:\n",
+    "1. A port to open jupyter lab (in this case, `<jupyter_port>`)\n",
+    "2. A port to open the dash app (`<dash_port>`)\n",
+    "```\n",
+    "docker run -it -p <jupyter_port>:<jupyter_port> -p <dash_port>:<dash_port> ghcr.io/getzlab/annomate:latest\n",
+    "cd AnnoMate/tutorial_notebooks\n",
+    "jupyter lab --ip 0.0.0.0 --port <jupyter_port> --no-browser --allow-root\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6429e242-eb91-4419-ba41-3b63e6f1ae6d",
+   "metadata": {},
+   "source": [
+    "## Running this notebook\n",
+    "\n",
+    "Make sure to update your kernel to the conda environment `<my-env>` you just created.\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "31fae173",
+   "metadata": {},
+   "source": [
+    "## Run an Example Reviewer\n",
+    "\n",
+    "Here we are setting up a basic reviewer that displays fake sample data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "a9657940",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "%load_ext autoreload\n",
+    "%autoreload 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "ef37cc47",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pandas as pd\n",
+    "import os\n",
+    "from AnnoMate.Reviewers.ExampleReviewer import ExampleReviewer"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "b0aaeb3b-a736-41d5-9d3b-5cd00fa6d40d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# get data\n",
+    "fn = 'example_data/AnnoMate_Tutorial/data_to_review_example.tsv'\n",
+    "df = pd.read_csv(fn, sep='\\t')\n",
+    "df = df.set_index('sample_id')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "04a55062-3ae8-4ecb-b4eb-de3a65ba220e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Setting auto_export_path to ./example_reviewer_data/data.auto_export\n",
+      "Using ./example_reviewer_data/data.auto_export for auto exporting.\n",
+      "Dash app running on http://0.0.0.0:8056/\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/cchu/opt/anaconda3/envs/test/lib/python3.8/site-packages/AnnoMate/ReviewDataInterface.py:41: UserWarning:\n",
+      "\n",
+      "Loading existing data pkl file\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "window.open('http://0.0.0.0:8056/')"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# set up and run reviewer\n",
+    "my_reviewer = ExampleReviewer()\n",
+    "output_pkl_path = './example_reviewer_data'\n",
+    "\n",
+    "my_reviewer.set_review_data(data_path=output_pkl_path, \n",
+    "                            description='Example reviewer description',\n",
+    "                            sample_df=df,\n",
+    "                            preprocessing_str='Testing preprocessing')\n",
+    "\n",
+    "my_reviewer.set_review_app(mut_file_col='mutations_file', \n",
+    "                           sample_cols=['gender', 'age', 'tissue_origin'])\n",
+    "\n",
+    "my_reviewer.set_default_review_data_annotations_configuration()\n",
+    "my_reviewer.set_default_autofill()\n",
+    "my_reviewer.run(collapsable=True, port=8056, mode='tab')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2a06283e-b1cb-452a-8d8d-46e2ebf538ea",
+   "metadata": {},
+   "source": [
+    "Accessing the Dash App:\n",
+    "> **If you are using a VM:** Make sure to open a ssh tunnel to the specified port number\n",
+    "> - `~C` to open the ssh prompt (will look like `ssh>`)\n",
+    "> - Type and enter `-L <port number>:localhost:<port number>`\n",
+    "\n",
+    "> **If you are running from a docker container:** Make sure to open the port for accessing the dash app (`reviewer.run(port=<new_port_number>, ...)`) when you open the container\n",
+    "> - `docker run -it -p <jupyter_port>:<jupyter_port> -p <dash_port>:<dash_port> gcr.io/broad-getzlab-workflows/annomate:dev_branch_v385`\n",
+    "> - You can add more ports by adding more `-p <port_number>:<port_number>` arguments\n",
+    "> - If you are on Linux, you can replace `-p` arguments with `--network host`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8476f28b-85f4-48b5-8a99-ccd6503dfa67",
+   "metadata": {},
+   "source": [
+    "### Use a table to navigate between samples rather than dropdown\n",
+    "\n",
+    "The table will also include the annotations in addition to the columns included in the dataframe passed to `review_data_table_df`. This table in the dashboard has native sorting and filtering, which can help the user find or prioritize samples to review."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "8158587c-270a-45f0-a769-52f6dbab95ae",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Setting auto_export_path to ./example_reviewer_data/data.auto_export\n",
+      "Using ./example_reviewer_data/data.auto_export for auto exporting.\n",
+      "Dash app running on http://0.0.0.0:8056/\n"
+     ]
+    },
+    {
+     "data": {
+      "application/javascript": [
+       "window.open('http://0.0.0.0:8056/')"
+      ],
+      "text/plain": [
+       "<IPython.core.display.Javascript object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "my_reviewer.run(\n",
+    "    review_data_table_df=df[['gender', 'age', 'tissue_origin']], \n",
+    "    review_data_table_page_size=7,\n",
+    "    port=8056,\n",
+    "    mode='tab'\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cc355478-4b2f-4dea-b8f4-f2743a3737d2",
+   "metadata": {},
+   "source": [
+    "### Disable test mode"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8da6a3c8-18eb-4382-9aab-4031be0ad167",
+   "metadata": {},
+   "source": [
+    "On initial load, you'll notice a `Freeze data` button. Once you are happy with your input data and are ready to start reviewing your data, press this button to disable test mode and freeze your data. Note that once this button is pressed, you will not be able to unfreeze your data / revert back to test mode."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a015ccb4",
+   "metadata": {},
+   "source": [
+    "### Retrieving annotations made in the dashbaord\n",
+    "After submitting annotations in the dashboard, you can view your progress by accessing the annotation table or history table:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "8bff62a2",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>Notes</th>\n",
+       "      <th>Flag</th>\n",
+       "      <th>Histogram color</th>\n",
+       "      <th>A dropdown menu</th>\n",
+       "      <th>Test removing annotation</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>sample_0</th>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_1</th>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_2</th>\n",
+       "      <td>Nothing to say</td>\n",
+       "      <td>Keep</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_3</th>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>sample_4</th>\n",
+       "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
+       "      <td></td>\n",
+       "      <td></td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                   Notes    Flag Histogram color A dropdown menu  \\\n",
+       "sample_0                  Remove                                   \n",
+       "sample_1                  Remove                                   \n",
+       "sample_2  Nothing to say    Keep                                   \n",
+       "sample_3                  Remove                                   \n",
+       "sample_4        Not good  Remove                                   \n",
+       "\n",
+       "          Test removing annotation  \n",
+       "sample_0                       NaN  \n",
+       "sample_1                       NaN  \n",
+       "sample_2                       NaN  \n",
+       "sample_3                       NaN  \n",
+       "sample_4                       NaN  "
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "my_reviewer.get_annot().head()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "id": "852bf6fa-9016-493a-89e9-cfa29e37d9c1",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>index</th>\n",
+       "      <th>timestamp</th>\n",
+       "      <th>source_data_fn</th>\n",
+       "      <th>Notes</th>\n",
+       "      <th>Flag</th>\n",
+       "      <th>Histogram color</th>\n",
+       "      <th>A dropdown menu</th>\n",
+       "      <th>Test removing annotation</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_0</td>\n",
+       "      <td>2024-05-29 11:21:53.051037</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_1</td>\n",
+       "      <td>2024-05-29 11:21:56.466574</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_2</td>\n",
+       "      <td>2024-05-29 11:22:02.213915</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td>Nothing to say</td>\n",
+       "      <td>Keep</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_3</td>\n",
+       "      <td>2024-05-29 11:22:05.466076</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td></td>\n",
+       "      <td>Remove</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>sample_4</td>\n",
+       "      <td>2024-05-29 11:22:12.998607</td>\n",
+       "      <td>./example_reviewer_data/data.pkl</td>\n",
+       "      <td>Not good</td>\n",
+       "      <td>Remove</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "      <td>NaN</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "      index                  timestamp                    source_data_fn  \\\n",
+       "0  sample_0 2024-05-29 11:21:53.051037  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_1 2024-05-29 11:21:56.466574  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_2 2024-05-29 11:22:02.213915  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_3 2024-05-29 11:22:05.466076  ./example_reviewer_data/data.pkl   \n",
+       "0  sample_4 2024-05-29 11:22:12.998607  ./example_reviewer_data/data.pkl   \n",
+       "\n",
+       "            Notes    Flag  Histogram color  A dropdown menu  \\\n",
+       "0                  Remove              NaN              NaN   \n",
+       "0                  Remove              NaN              NaN   \n",
+       "0  Nothing to say    Keep              NaN              NaN   \n",
+       "0                  Remove              NaN              NaN   \n",
+       "0        Not good  Remove              NaN              NaN   \n",
+       "\n",
+       "   Test removing annotation  \n",
+       "0                       NaN  \n",
+       "0                       NaN  \n",
+       "0                       NaN  \n",
+       "0                       NaN  \n",
+       "0                       NaN  "
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "my_reviewer.get_history()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7fea16ef",
+   "metadata": {},
+   "source": [
+    "Now you can export this table to a file that you can then share, upload to Terra, or use for further analysis."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "defbae62-fe6d-4e0d-b0a3-7f3ac522fc23",
+   "metadata": {},
+   "source": [
+    "## Make modifications to the Dashboard in the notebook"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "id": "34d7128c-36bd-4da3-92c0-8962770dc0a9",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from AnnoMate.Data import DataAnnotation\n",
+    "import AnnoMate.AnnotationDisplayComponent as adc\n",
+    "import numpy as np"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ada89ed7-0ffd-4fe1-993d-ddc9f5e2b2b8",
+   "metadata": {},
+   "source": [
+    "### Add another table component\n",
+    "\n",
+    "AnnoMate includes a helper function to quickly add in a table using a tsv file provided for each sample. In this case, we display the file in column `Treatmet file` in `df` corresponding to the selected sample for review.\n",
+    "\n",
+    "See `Developer_AnnoMate_Tutorial` for more details on how to make a fully custom interactive component."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "id": "9fd80758",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "my_reviewer.app.add_table_from_path(\n",
+    "    data_table_source='df', # reference which table in the Data object to use.\n",
+    "    table_title='Treatment file',\n",
+    "    component_id='treatment-component-id',\n",
+    "    table_fn_col='treatments_file', \n",
+    "    table_cols=['treatment_name', 'response', 'tx_start']\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "4dfb58a3-b5a8-4dff-a5a8-1a4ae4ff5184",
+   "metadata": {},
+   "source": [
+    "### Update existing annotation options and display\n",
+    "\n",
+    "By default, the `ExampleReviewer` `Flag` annotation had only two options: Keep and Remove. Here, we update the viable options for annotations, and set a default value."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "53cb2bf6-a874-425c-bc6c-0afff25a05a1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "my_reviewer.add_review_data_annotation(\n",
+    "    annot_name='Flag', \n",
+    "    review_data_annotation=DataAnnotation(\n",
+    "        annot_value_type='string', \n",
+    "        options=['Keep', 'Remove', 'Report'], \n",
+    "    )\n",
+    ")\n",
+    "my_reviewer.add_annotation_display_component(\n",
+    "    annot_name='Flag', \n",
+    "    annot_display_component=adc.RadioitemAnnotationDisplay(default_display_value='Keep')\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0d62cad4-2508-4528-a456-f0c45e83d05f",
+   "metadata": {},
+   "source": [
+    "### Add more annotations\n",
+    "\n",
+    "Here we add a dropdown menu to track another annotation that is not included in the pre-built ExampleReviewer class"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "id": "85edf720-e28f-40c2-8ef2-4ee0917d065d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Dropdown/Select\n",
+    "my_reviewer.add_review_data_annotation(\n",
+    "    annot_name='A dropdown menu', \n",
+    "    review_data_annotation=DataAnnotation(\n",
+    "        annot_value_type='string', \n",
+    "        options=['Option A', 'Option B', 'Option C']\n",
+    "    )\n",
+    ")\n",
+    "my_reviewer.add_annotation_display_component(\n",
+    "    annot_name='A dropdown menu', \n",
+    "    annot_display_component=adc.SelectAnnotationDisplay())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "936bd35f-0920-4c71-9b2e-31db813541aa",
+   "metadata": {},
+   "source": [
+    "### Remove annotation from display\n",
+    "\n",
+    "Note this will only remove the annotation input from the dashboard. It will not delete the column in the annotation table (`reviewer.get_annot()`)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "f5d59a4c-e5c5-482b-bcc3-544b909a4fa6",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# adding an annotation\n",
+    "my_reviewer.add_review_data_annotation(\n",
+    "    annot_name='Test removing annotation', \n",
+    "    review_data_annotation=DataAnnotation(\n",
+    "        annot_value_type='float', \n",
+    "    )\n",
+    ")\n",
+    "my_reviewer.add_annotation_display_component(\n",
+    "    annot_name='Test removing annotation', \n",
+    "    annot_display_component=adc.NumberAnnotationDisplay())\n",
+    "\n",
+    "'Test removing annotation' in my_reviewer.annot_app_display_types_dict.keys()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "id": "95ff8056-3b62-489e-8bf6-8809bcdfedeb",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "False"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# removing an annotation from display\n",
+    "removed_annot_display_component = my_reviewer.remove_annotation_display_component('Test removing annotation')\n",
+    "'Test removing annotation' in my_reviewer.annot_app_display_types_dict.keys()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "10700832-b886-4568-a0ae-d582e367d0a5",
+   "metadata": {},
+   "source": [
+    "### Add annotation autofill button\n",
+    "\n",
+    "To expedite recording annotations, the user can create a button that will fill the annotation inputs. Here, when the button `Mut vafs` is clicked, the `Histogram color` annotation will be filled with whatever the current state of the radioitem `mut-figure-color-radioitem` is.\n",
+    "\n",
+    "Users can also prefill with a fixed value (i.e. a string, number)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "id": "eff8b6fe-f965-4a78-8097-6aa19fc3a2cc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from dash.dependencies import State\n",
+    "my_reviewer.add_autofill(\n",
+    "    autofill_button_name='Mut vafs',\n",
+    "    fill_value=State('mut-figure-color-radioitem', 'value'),\n",
+    "    annot_name='Histogram color'\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e5ebf97b-fb62-4768-bbb3-af4516ab5c16",
+   "metadata": {},
+   "source": [
+    "### Change which components and the order the components are displayed"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "id": "ad199e40-f8ef-4528-b6f3-f2335d9c9a06",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "odict_keys(['sample-info-component', 'Maf file', 'Mut vafs', 'Treatment file'])"
+      ]
+     },
+     "execution_count": 50,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# View available components\n",
+    "my_reviewer.app.more_components.keys()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "id": "71659b78-7085-4e07-8fca-85efbc9bfc31",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Setting auto_export_path to ./example_reviewer_data/data.auto_export\n",
+      "Using ./example_reviewer_data/data.auto_export for auto exporting.\n",
+      "Dash app running on http://0.0.0.0:8056/\n"
+     ]
+    }
+   ],
+   "source": [
+    "my_reviewer.run(\n",
+    "    port=8056,\n",
+    "    components_name_order=['sample-info-component', 'Treatment file', 'Mut vafs']\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fe4762ca-2cb4-41f2-a486-74d4cfd4c08e",
+   "metadata": {},
+   "source": [
+    "**NOTE**: Some reviewers may have components that listen to each other, so if you keep one but not the other, some of the predefined interactivity may lead to error messages. You may run into similar errors for autofill buttons which may be pulling data from components that are excluded. \n",
+    "\n",
+    "Also, the data needed to render excluded components will still be required when setting the review data (`reviewer.set_review_data(...)`)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e07c9eca",
+   "metadata": {},
+   "source": [
+    "# Final words\n",
+    "\n",
+    "You can always go back and change the parameters of setting the app and annotation configurations, adding or editing the components of the app, etc.\n",
+    "\n",
+    "The one thing that will NOT change after disabling test mode is `set_review_data()`. This review data can only be frozen once per `data_path`. You may re-set your review data as much as you'd like in test mode, but once you click the 'Freeze data' button, disabling test mode, no more changes to the input data can be made (annotaions can still be made and components can still be added). If you wish to start over, you must manually delete the data path. Else, reference a new path.\n",
+    "\n",
+    "This feature allows you to make these changes to the app on the fly, and you can restart the notebook and it will not change the annotations you have already made.\n",
+    "\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python [conda env:test]",
+   "language": "python",
+   "name": "conda-env-test-py"
+  },
+  "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.8.0"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}


Test patch:
diff --git a/tests/test_example_reviewer.py b/tests/test_example_reviewer.py
index 3af375a..8711889 100644
--- a/tests/test_example_reviewer.py
+++ b/tests/test_example_reviewer.py
@@ -2,7 +2,7 @@
 from AnnoMate.Reviewers.ExampleReviewer import ExampleReviewer
 
 def test_reviewer():
-    fn = '../tutorial_notebooks/example_data/AnnoMate_Tutorial/data_to_review_example.tsv'
+    fn = 'tutorial_notebooks/example_data/AnnoMate_Tutorial/data_to_review_example.tsv'
     df = pd.read_csv(fn, sep='\t')
     df = df.set_index('sample_id')
     assert df.shape[0] > 0