{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p align=\"center\">\n",
    "    <img src=\"https://github.com/GeostatsGuy/GeostatsPy/blob/master/TCG_color_logo.png?raw=true\" width=\"220\" height=\"240\" />\n",
    "\n",
    "</p>\n",
    "\n",
    "## Interactive Bayesian Updating\n",
    "\n",
    "#### Michael Pyrcz, Professor, The University of Texas at Austin \n",
    "\n",
    "##### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1) | [GeostatsPy](https://github.com/GeostatsGuy/GeostatsPy)\n",
    "\n",
    "### Bayesian Updating\n",
    "\n",
    "Here are three interactive workflows, all demonstrations of Bayesian updating that should help you efficient learn Bayesian updating, central for Bayesian probability calculations.\n",
    "\n",
    "I have recorded a walk-through of this interactive dashboard in my [Data Science Interactive Python Demonstrations](https://www.youtube.com/playlist?list=PLG19vXLQHvSDy26fM3hDLg3VCU7U5BGZl) series on my [YouTube](https://www.youtube.com/@GeostatsGuyLectures) channel.\n",
    "\n",
    "* Join me for walk-through of this dashboard [02 Data Science Interactive: Bayesian Updating](https://www.youtube.com/watch?v=FSf_zYiU5Yw). I'm stoked to guide you and share observations and things to try out!   \n",
    "\n",
    "* I have a lecture on [Bayesian Probability](https://www.youtube.com/watch?v=Ppwfr8H177M&list=PLG19vXLQHvSB-D4XKYieEku9GQMQyAzjJ&index=6) as part of my [Data Analytics and Geostatistics](https://www.youtube.com/playlist?list=PLG19vXLQHvSB-D4XKYieEku9GQMQyAzjJ). Note, for all my recorded lecture the interactive and well-documented workflow demononstrations are available on my GitHub repository [GeostatsGuy's Python Numerical Demos](https://github.com/GeostatsGuy/PythonNumericalDemos).\n",
    "\n",
    "* Also, I have another interactive [Sivia's Bayesian Coin Example](https://github.com/GeostatsGuy/PythonNumericalDemos/blob/master/Interactive_Sivia_Coin_Toss.ipynb) for the Sivia (1996) Bayesian coin example and a [Walk-Through](https://www.youtube.com/watch?v=D1UKZGOYDOg&list=PLG19vXLQHvSB-D4XKYieEku9GQMQyAzjJ&index=8&t=14s) on my YouTube channel.\n",
    "\n",
    "#### Bayesian Updating\n",
    "\n",
    "Bayesian updating, the application of Bayes' Theorem:\n",
    "\n",
    "\\begin{equation}\n",
    "P(A|B) = \\frac{P(B|A) \\cdot P(A)}{P(B)}\n",
    "\\end{equation}\n",
    "\n",
    "where $P(A)$ is the prior probability, $P(B)$ is the evidence term to enforce closure, $P(B|A)$ is the likelihood function and $P(A|B)$ is the posterior probability.\n",
    "\n",
    "\\begin{equation}\n",
    "Posterior = \\frac{Likelihood \\cdot Prior}{Evidence}\n",
    "\\end{equation}\n",
    "\n",
    "#### Got a Positive Test, But is the Thing Happening?\n",
    "\n",
    "A common and illustrative example of Bayesian updating is the case of conducting a test, where we have a positive indicator vs. the event is happening. We could substitute into Bayes' theorem as:\n",
    "\n",
    "\\begin{equation}\n",
    "P(\\text{The Thing is Happening}|\\text{Positive Test}) = \\frac{P(\\text{Positive Test}|\\text{The Thing is Happening}) \\cdot P(\\text{The Thing is Happening})}{P(\\text{Positive Test})}\n",
    "\\end{equation}\n",
    "\n",
    "Bayes' theorem can be expanded to a form in that the evidence is more readily calculated, i.e., marginalization over both cases.\n",
    "\n",
    "\\begin{equation}\n",
    "P(A|B) = \\frac{P(B|A)P(A)}{P(B|A)P(A)+P(B|A^c)P(A^c)}\n",
    "\\end{equation}\n",
    "\n",
    "we can relate this back to the test example:\n",
    "\n",
    "\\begin{equation}\n",
    "P(\\text{Happening}|\\text{Positive Test}) = \\frac{P(\\text{Positive Test}|\\text{Happening}) \\cdot P(\\text{Happening})}{P(\\text{Positive Test}|\\text{Happening})P(\\text{Happening}) + P(\\text{Positive Test}|\\text{NOT Happening})P(\\text{NOT Happening})}\n",
    "\\end{equation}\n",
    "\n",
    "We will use the above case in an interactive demo to modify the likelihood and prior to calculate the posterior.  Below we will use even more concise notation where \"$H$\" is \"Happening\", \"$H^c$ is \"NOT Happening\", \"$+$\" is positive test, and \"$-$\" is a negative test (used to evaluate the case of a negative test result in the 2nd dashboard). \n",
    "\n",
    "\\begin{equation}\n",
    "P(H|+) = \\frac{P(+|H) \\cdot P(H)}{P(+|H)P(H) + P(+|H^c)P(H^c)}\n",
    "\\end{equation}\n",
    "\n",
    "Afterwards, we will work out updating with entire distributions under the Gaussian assumption.\n",
    "\n",
    "#### Updating Entire Distributions Under the Gaussian Assumption\n",
    "\n",
    "Sivia (1996) presents an analytical for for Bayesian updating with Gaussian distributions. \n",
    "\n",
    "Given a Gaussian prior, $N[\\mu_{prior},\\sigma^2_{prior}]$, and likelihood function, $N[\\mu_{like},\\sigma^2_{like}]$, the Gaussian posterior, $N[\\mu_{post},\\sigma^2_{post}]$, is calculated as:\n",
    "\n",
    "\\begin{equation}\n",
    "\\mu_{post}=\\frac{\\mu_{like} \\cdot \\sigma^2_{prior} + \\mu_{prior} \\cdot \\sigma^2_{like}}   \n",
    "                         {[1-\\sigma^2_{like}] [\\sigma^2_{prior} - 1] + 1}\n",
    "\\end{equation}\n",
    "\n",
    "\\begin{equation}\n",
    "\\sigma^2_{post}=\\frac{\\sigma^2_{prior} \\cdot \\sigma^2_{like}}   \n",
    "                         {[1-\\sigma^2_{like}] [\\sigma^2_{prior} - 1] + 1}\n",
    "\\end{equation}\n",
    "\n",
    "Let's demonstrate both below with 3 dashbaords.\n",
    "\n",
    "#### Getting Started\n",
    "\n",
    "Here's the steps to get setup in Python with the GeostatsPy package:\n",
    "\n",
    "1. Install Anaconda 3 on your machine (https://www.anaconda.com/download/). \n",
    "\n",
    "That's all!\n",
    "\n",
    "#### Load the Required Libraries\n",
    "\n",
    "The following code loads the required libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "supress_warnings = False\n",
    "from ipywidgets import interactive                        # widgets and interactivity\n",
    "from ipywidgets import widgets                            # widgets and interactivity\n",
    "import matplotlib; import matplotlib.pyplot as plt        # plotting\n",
    "from matplotlib.ticker import (MultipleLocator, AutoMinorLocator) # control of axes ticks\n",
    "import numpy as np                                        # working with arrays\n",
    "import scipy.stats as st                                  # for Gaussian distribution\n",
    "import math                                               # for square root\n",
    "from ipywidgets import interactive                        # widgets and interactivity\n",
    "from ipywidgets import widgets                            \n",
    "from ipywidgets import Layout\n",
    "from ipywidgets import Label\n",
    "from ipywidgets import VBox, HBox\n",
    "cmap = plt.cm.inferno                                     # default color bar, no bias and friendly for color vision defeciency\n",
    "plt.rc('axes', axisbelow=True)                            # grid behind plotting elements\n",
    "if supress_warnings == True:\n",
    "    import warnings                                       # supress any warnings for this demonstration\n",
    "    warnings.filterwarnings('ignore')                       "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you get a package import error, you may have to first install some of these packages. This can usually be accomplished by opening up a command window on Windows and then typing 'python -m pip install [package-name]'. More assistance is available with the respective package docs. \n",
    "\n",
    "#### Declare functions\n",
    "\n",
    "Here's a convenience function to add major and minor gridlines to our plots."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_grid():\n",
    "    plt.gca().grid(True, which='major',linewidth = 1.0); plt.gca().grid(True, which='minor',linewidth = 0.2) # add y grids\n",
    "    plt.gca().tick_params(which='major',length=7); plt.gca().tick_params(which='minor', length=4)\n",
    "    plt.gca().xaxis.set_minor_locator(AutoMinorLocator()); plt.gca().yaxis.set_minor_locator(AutoMinorLocator()) # turn on minor ticks   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Bayesian Updating\n",
    "\n",
    "Let's start with our illustrative example of Bayesian updating is the case of conducting a test, where we have a positive indicator vs. the event is happening:\n",
    "\n",
    "\\begin{equation}\n",
    "P(H|+) = \\frac{P(+|H)P(H)}{P(+|H)P(H) + P(+|H^c)P(H^c)}\n",
    "\\end{equation}\n",
    "\n",
    "we can observe that $P(+|H)P(H)$ is the probability of the event happening and a positive test, true positives, and $P(+|H^c)P(H^c)$ is the probability of the event NOT happening and a positive test, false positives. I calculate and label each below.\n",
    "\n",
    "Below we will calculate all of these, show the equations and plot the results.\n",
    "\n",
    "#### Demonstration \\#1, Bayesian Updating with a Test Result\n",
    "\n",
    "This dashboard accepts the probability of an event, probability of a positive test given the event is happening and probability of a positive test given the event is NOT happening.\n",
    "\n",
    "##### Build the Interactive Dashboard\n",
    "\n",
    "Here's the code to build the dashboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = widgets.Text(value='                                                      Bayesian Updating Demo, Michael Pyrcz, Professor, The University of Texas at Austin',\n",
    "        layout=Layout(width='900px', height='30px'))\n",
    "# P_happening_label = widgets.Text(value='Probability of Happening',layout=Layout(width='50px',height='30px',line-size='0 px'))\n",
    "P_happening = widgets.FloatSlider(min=0, max = 1, value=0.1, step = 0.01, description = r'\\(\\color{green} {' + 'P(H)'  + '}\\)',orientation='horizontal', \n",
    "        style = {'description_width':'initial','button_color':'green'},layout=Layout(width='300px',height='30px'),continuous_update=False,readout_format='.3f')\n",
    "P_happening.style.handle_color = 'green'\n",
    "P_positive_given_happening = widgets.FloatSlider(min=0, max = 1, value=0.9, step = 0.01, description = r'\\(\\color{blue} {' + 'P(+|H)'  + '}\\)',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='300px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "P_positive_given_happening.style.handle_color = 'blue'\n",
    "P_positive_given_not_happening = widgets.FloatSlider(min=0, max = 1, value=0.01, step = 0.01, description = r'$P(+|H^c)$',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='300px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "\n",
    "ui_summary = widgets.HBox([P_happening,P_positive_given_happening,P_positive_given_not_happening],)\n",
    "ui2_summary1 = widgets.VBox([l,ui_summary],)\n",
    "\n",
    "def run_plot_summary1(P_happening,P_positive_given_happening,P_positive_given_not_happening):\n",
    "    digits = 3\n",
    "    P_not_positive_given_happening = np.round((1 - P_positive_given_happening),digits)\n",
    "    P_not_positive_given_not_happening = np.round((1 - P_positive_given_not_happening),digits)\n",
    "    P_not_happening = np.round((1.0 - P_happening),digits)\n",
    "    \n",
    "    P_positive = np.round((P_positive_given_happening * P_happening + P_positive_given_not_happening * P_not_happening),digits)\n",
    "    P_not_positive = np.round((P_not_positive_given_happening * P_happening + P_not_positive_given_not_happening * P_not_happening),digits)\n",
    "    \n",
    "    P_happening_given_positive = np.round(((P_positive_given_happening * P_happening) / P_positive),digits)\n",
    "    P_not_happening_given_positive = np.round((P_positive_given_not_happening * P_not_happening) / P_positive,digits)\n",
    "    \n",
    "    P_happening_given_not_positive = np.round(((P_not_positive_given_happening * P_happening) / P_not_positive),digits)\n",
    "    P_not_happening_given_not_positive = np.round(((P_not_positive_given_not_happening * P_not_happening) / P_not_positive),digits)\n",
    "        \n",
    "    plt.subplot(111)\n",
    "    plt.plot()\n",
    "    vshift = -0.1\n",
    "    \n",
    "    # inputs\n",
    "    plt.annotate(r'$P(H) = $',xy=(0.10,0.83),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_happening,3)),xy=(0.15,0.83),fontsize = 12,weight='bold')\n",
    "    plt.annotate(r'$P(H^c) = 1 - P(H) = $',xy=(0.10,0.69),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_happening,3)),xy=(0.23,0.69),fontsize = 12,color='red',)\n",
    "    \n",
    "    plt.annotate(r'$P(+|H) = $',xy=(0.4,0.83),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_positive_given_happening,3)),xy=(0.47,0.83),fontsize = 12,weight = 'bold')\n",
    "    plt.annotate(r'$P(-|H) = 1 - P(+|H) = $',xy=(0.4,0.69),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_positive_given_happening,3)),xy=(0.55,0.69),fontsize = 12,color='red')\n",
    "    \n",
    "    plt.annotate(r'$P(+|H^c) = $',xy=(0.7,0.83),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_positive_given_not_happening,3)),xy=(0.77,0.83),fontsize = 12,weight = 'bold')\n",
    "    plt.annotate(r'$P(-|H^c) = 1 - P(+|H^c) = $',xy=(0.7,0.69),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_positive_given_not_happening,3)),xy=(0.87,0.69),fontsize = 12,color='red')\n",
    "    \n",
    "    # P(H|+)\n",
    "    vo = -0.70; ho = -0.05\n",
    "    plt.annotate(r'$P(H|+) = \\frac{P(+|H) \\ P(H)}{P(+|H) \\ P(H) + P(+|H^c) \\ P(H^c)} =$',\n",
    "        xy=(0.1+ho,0.5+vo),fontsize = 20)\n",
    "    plt.annotate('Probability True Positive',xy=(0.32+ho,1.0+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability True Positive',xy=(0.24+ho,0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability False Positive',xy=(0.40+ho,0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_happening*P_happening,3),xy=(0.32+ho,0.8+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_happening*P_happening,3),xy=(0.26+ho,0.2+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_not_happening*P_not_happening,3),xy=(0.38+ho,0.2+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_happening_given_positive,3),xy=(0.47+ho,0.5+vo),fontsize = 15,color='red',ha='left')\n",
    "    \n",
    "    # P(H|+)\n",
    "    ho = 0.6; vo = -0.50\n",
    "    plt.annotate(r'$P(H|+)$: Probability Happening Given Positive Test',xy=(0.15+ho,0.98+vo),fontsize = 12,ha='center'); plt.annotate(r'$0.0$',xy=(0.0+ho,-0.25+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(r'$0.5$',xy=(0.15+ho,-0.25+vo),fontsize = 10,ha='center'); plt.annotate(r'$1.0$',xy=(0.3+ho,-0.25+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability',xy=(0.15+ho,-0.4+vo),fontsize = 10,ha='center'); plt.plot([0.0+ho,0.3+ho],[-0.1+vo,-0.1+vo],c='black',lw=2)\n",
    "    for p in np.arange(0.0,1.1,0.1):\n",
    "        plt.plot([p*0.3+ho,p*0.3+ho],[-0.1+vo,-0.12+vo],c='black')\n",
    "    plt.plot([P_happening*0.3+ho,P_happening*0.3+ho],[-0.1+vo,0.45+vo],c='green',lw=2,ls='--')\n",
    "    plt.annotate(r'Prior: $P(H)$',xy=(P_happening*0.3-0.01+ho,0.0+vo),fontsize = 11,ha='center',rotation=90.0,c = 'green')\n",
    "    plt.plot([P_positive_given_happening*0.3+ho,P_positive_given_happening*0.3+ho],[-0.1+vo,0.45+vo],c='blue',lw=2,ls='--')\n",
    "    plt.annotate(r'Likelihood: $P(+|H)$',xy=(P_positive_given_happening*0.3-0.01+ho,0.0+vo),fontsize = 11,ha='center',rotation=90.0, c='blue')\n",
    "    plt.plot([P_happening_given_positive*0.3+ho,P_happening_given_positive*0.3+ho],[-0.1+vo,0.55+vo],c='black',lw=2,)\n",
    "    plt.annotate(r'Posterior: $P(H|+)$',xy=(P_happening_given_positive*0.3-0.01+ho,0.0+vo),fontsize = 11,ha='center',rotation=90.0)\n",
    "    \n",
    "    plt.xlim([0,1.01]); plt.ylim([-1.0,1.0])\n",
    "    plt.tick_params(left = False, right = False, labelleft = False, labelbottom = False, bottom = False)\n",
    "    \n",
    "    plt.subplots_adjust(left=0.0, bottom=0.0, right=2., top=0.7, wspace=0.2, hspace=0.1); plt.show()\n",
    "    \n",
    "interactive_plot_summary1 = widgets.interactive_output(run_plot_summary1, {'P_happening':P_happening,\n",
    "    'P_positive_given_happening':P_positive_given_happening,             \n",
    "    'P_positive_given_not_happening':P_positive_given_not_happening,})\n",
    "interactive_plot_summary1.clear_output(wait = True)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interactive Bayesian Updating Demonstration\n",
    "\n",
    "* Select the probability of the event, $P(H)$, probability of a positive test if the event is happening, $P(+|H)$, and probability of a positive test given the event is not happening, $P(+|H^c)$ and observe the combinatorial of Bayesian updating.\n",
    "\n",
    "#### Michael J. Pyrcz, Professor, The University of Texas at Austin \n",
    "\n",
    "##### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1) | [GeostatsPy](https://github.com/GeostatsGuy/GeostatsPy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9f463f05380247aca636afc2264ae0a0",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(Text(value='                                                      Bayesian Updating Demo, Micha…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "70ad5e2b4fc24f499708c4b904c1dc3a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(ui2_summary1, interactive_plot_summary1)                           # display the interactive plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is very interesting to calculate the combinatorial of possible posteriors:  \n",
    "\n",
    "* $P(H|+)$: probability of the thing happening given a positive test\n",
    "* $P(H^c|+)$: probability of the thing NOT happening given a positive test\n",
    "* $P(H|-)$: probability of the thing happening given a negative test\n",
    "* $P(H^c|-)$: probability of the thing NOT happening given a negative test\n",
    "\n",
    "Below we will calculate all of these, show the equations and plot the results.\n",
    "\n",
    "#### Demonstration \\#2, Bayesian Updating with a Test Result for All Possible Posteriors\n",
    "\n",
    "This dashboard accepts the probability of an event, probability of a positive test given the event is happening and probability of a positive test given the event is NOT happening.\n",
    "\n",
    "##### Build the Interactive Dashboard\n",
    "\n",
    "Here's the code to build the dashboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = widgets.Text(value='                                                      Bayesian Updating Demo, Michael Pyrcz, Professor, The University of Texas at Austin',\n",
    "        layout=Layout(width='900px', height='30px'))\n",
    "# P_happening_label = widgets.Text(value='Probability of Happening',layout=Layout(width='50px',height='30px',line-size='0 px'))\n",
    "P_happening = widgets.FloatSlider(min=0, max = 1, value=0.1, step = 0.1, description = r'$P(H)$',orientation='horizontal', \n",
    "        style = {'description_width':'initial'},layout=Layout(width='300px',height='30px'),continuous_update=False,readout_format='.3f')\n",
    "P_positive_given_happening = widgets.FloatSlider(min=0, max = 1, value=0.9, step = 0.01, description = r'$P(+|H)$',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='300px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "P_positive_given_not_happening = widgets.FloatSlider(min=0, max = 1, value=0.01, step = 0.01, description = r'$P(+|H^c)$',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='300px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "\n",
    "ui_summary = widgets.HBox([P_happening,P_positive_given_happening,P_positive_given_not_happening],)\n",
    "ui2_summary = widgets.VBox([l,ui_summary],)\n",
    "\n",
    "def run_plot_summary(P_happening,P_positive_given_happening,P_positive_given_not_happening):\n",
    "    digits = 3\n",
    "    P_not_positive_given_happening = np.round((1 - P_positive_given_happening),digits)\n",
    "    P_not_positive_given_not_happening = np.round((1 - P_positive_given_not_happening),digits)\n",
    "    P_not_happening = np.round((1.0 - P_happening),digits)\n",
    "    \n",
    "    P_positive = np.round((P_positive_given_happening * P_happening + P_positive_given_not_happening * P_not_happening),digits)\n",
    "    P_not_positive = np.round((P_not_positive_given_happening * P_happening + P_not_positive_given_not_happening * P_not_happening),digits)\n",
    "    \n",
    "    P_happening_given_positive = np.round(((P_positive_given_happening * P_happening) / P_positive),digits)\n",
    "    P_not_happening_given_positive = np.round((P_positive_given_not_happening * P_not_happening) / P_positive,digits)\n",
    "    \n",
    "    P_happening_given_not_positive = np.round(((P_not_positive_given_happening * P_happening) / P_not_positive),digits)\n",
    "    P_not_happening_given_not_positive = np.round(((P_not_positive_given_not_happening * P_not_happening) / P_not_positive),digits)\n",
    "        \n",
    "    plt.subplot(211)\n",
    "    plt.plot()\n",
    "    vshift = -0.1\n",
    "    \n",
    "    # inputs\n",
    "    plt.annotate(r'$P(H) = $',xy=(0.10,0.88),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_happening,3)),xy=(0.15,0.88),fontsize = 12,weight='bold')\n",
    "    plt.annotate(r'$P(H^c) = 1 - P(H) = $',xy=(0.10,0.74),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_happening,3)),xy=(0.23,0.74),fontsize = 12,color='red',)\n",
    "    \n",
    "    plt.annotate(r'$P(+|H) = $',xy=(0.4,0.88),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_positive_given_happening,3)),xy=(0.47,0.88),fontsize = 12,weight = 'bold')\n",
    "    plt.annotate(r'$P(-|H) = 1 - P(+|H) = $',xy=(0.4,0.74),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_positive_given_happening,3)),xy=(0.55,0.74),fontsize = 12,color='red')\n",
    "    \n",
    "    plt.annotate(r'$P(+|H^c) = $',xy=(0.7,0.88),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_positive_given_not_happening,3)),xy=(0.77,0.88),fontsize = 12,weight = 'bold')\n",
    "    plt.annotate(r'$P(-|H^c) = 1 - P(+|H^c) = $',xy=(0.7,0.74),fontsize = 12,)\n",
    "    plt.annotate(str(np.round(P_not_positive_given_not_happening,3)),xy=(0.87,0.74),fontsize = 12,color='red')\n",
    "    \n",
    "    # P(H|+)\n",
    "    vo = -0.35; ho = -0.05\n",
    "    plt.annotate(r'$P(H|+) = \\frac{P(+|H)P(H)}{P(+|H)P(H) + P(+|H^c)P(H^c)} =$',\n",
    "        xy=(0.1+ho,0.5+vo),fontsize = 20)\n",
    "    plt.annotate('Probability True Positive',xy=(0.32+ho,0.81+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability True Positive',xy=(0.24+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability False Positive',xy=(0.40+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_happening*P_happening,3),xy=(0.32+ho,0.7+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_happening*P_happening,3),xy=(0.26+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_not_happening*P_not_happening,3),xy=(0.38+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_happening_given_positive,3),xy=(0.46+ho,0.5+vo),fontsize = 15,color='red',ha='left')\n",
    "    \n",
    "    # P(H^c|+)\n",
    "    vo = -1.15; ho = -0.05\n",
    "    plt.annotate(r'$P(H^c|+) = \\frac{P(+|H^c)P(H^c)}{P(+|H^c)P(H^c) + P(+|H)P(H)} =$',\n",
    "        xy=(0.1+ho,0.5+vo),fontsize = 20)\n",
    "    plt.annotate('Probability False Positive',xy=(0.32+ho,0.81+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability False Positive',xy=(0.24+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability True Positive',xy=(0.40+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_not_happening*P_not_happening,3),xy=(0.34+ho,0.7+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_not_happening*P_not_happening,3),xy=(0.28+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_positive_given_happening*P_happening,3),xy=(0.39+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_happening_given_positive,3),xy=(0.47+ho,0.5+vo),fontsize = 15,color='red',ha='left')\n",
    "    \n",
    "    # P(H|+^c)\n",
    "    vo = -0.35; ho = 0.45\n",
    "    plt.annotate(r'$P(H|-) = \\frac{P(-|H)P(H)}{P(-|H)P(H) + P(-|H^c)P(H^c)} =$',\n",
    "        xy=(0.1+ho,0.5+vo),fontsize = 20)\n",
    "    plt.annotate('Probability False Negative',xy=(0.34+ho,0.81+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability False Negative',xy=(0.26+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability True Negative',xy=(0.42+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_happening*P_happening,3),xy=(0.34+ho,0.7+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_happening*P_happening,3),xy=(0.28+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_not_happening*P_not_happening,3),xy=(0.39+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_happening_given_not_positive,3),xy=(0.46+ho,0.5+vo),fontsize = 15,color='red',ha='left')\n",
    "    \n",
    "    # P(H|+^c)\n",
    "    vo = -1.15; ho = 0.45\n",
    "    plt.annotate(r'$P(H^c|-) = \\frac{P(-|H^c)P(H^c)}{P(-|H^c)P(H^c) + P(-|H)P(H)} =$',\n",
    "        xy=(0.1+ho,0.5+vo),fontsize = 20)\n",
    "    plt.annotate('Probability True Negative',xy=(0.35+ho,0.81+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability True Negative',xy=(0.26+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability False Negative',xy=(0.43+ho,0.2+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_not_happening*P_not_happening,3),xy=(0.35+ho,0.7+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_not_happening*P_not_happening,3),xy=(0.28+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_positive_given_happening*P_happening,3),xy=(0.40+ho,0.3+vo),fontsize = 15,color='red',ha='center')\n",
    "    plt.annotate(np.round(P_not_happening_given_not_positive,3),xy=(0.47+ho,0.5+vo),fontsize = 15,color='red',ha='left')\n",
    "    \n",
    "    plt.xlim([0,1.01]); plt.ylim([-1.0,1.0])\n",
    "    \n",
    "    plt.tick_params(left = False, right = False, labelleft = False, labelbottom = False, bottom = False)\n",
    "    \n",
    "    plt.subplot(212)\n",
    "    \n",
    "    # P(H|+)\n",
    "    ho = 0.1; vo = 0.62\n",
    "    plt.annotate(r'$P(H|+)$: Probability Happening Given Positive Test',xy=(0.15+ho,0.31+vo),fontsize = 12,ha='center'); plt.annotate(r'$0.0$',xy=(0.0+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(r'$0.5$',xy=(0.15+ho,-0.05+vo),fontsize = 10,ha='center'); plt.annotate(r'$1.0$',xy=(0.3+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability',xy=(0.15+ho,-0.1+vo),fontsize = 10,ha='center'); plt.plot([0.0+ho,0.3+ho],[0.0+vo,0.0+vo],c='black',lw=2)\n",
    "    for p in np.arange(0.0,1.1,0.1):\n",
    "        plt.plot([p*0.3+ho,p*0.3+ho],[0.0+vo,-0.01+vo],c='black')\n",
    "    plt.plot([P_happening*0.3+ho,P_happening*0.3+ho],[0.0+vo,0.15+vo],c='green',lw=2,ls='--')\n",
    "    plt.annotate(r'Prior: $P(H)$',xy=(P_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0,c = 'green')\n",
    "    plt.plot([P_positive_given_happening*0.3+ho,P_positive_given_happening*0.3+ho],[0.0+vo,0.15+vo],c='red',lw=2,ls='--')\n",
    "    plt.annotate(r'Likelihood: $P(+|H)$',xy=(P_positive_given_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0, c='red')\n",
    "    plt.plot([P_happening_given_positive*0.3+ho,P_happening_given_positive*0.3+ho],[0.0+vo,0.2+vo],c='black',lw=2,)\n",
    "    plt.annotate(r'Posterior: $P(H|+)$',xy=(P_happening_given_positive*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0)\n",
    "    \n",
    "    # P(H^c|+)\n",
    "    ho = 0.1; vo = 0.12\n",
    "    plt.annotate(r'$P(H^c|+)$: Probability NOT Happening Given Positive Test',xy=(0.15+ho,0.31+vo),fontsize = 12,ha='center'); plt.annotate(r'$0.0$',xy=(0.0+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(r'$0.5$',xy=(0.15+ho,-0.05+vo),fontsize = 10,ha='center'); plt.annotate(r'$1.0$',xy=(0.3+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability',xy=(0.15+ho,-0.1+vo),fontsize = 10,ha='center'); plt.plot([0.0+ho,0.3+ho],[0.0+vo,0.0+vo],c='black',lw=2)\n",
    "    for p in np.arange(0.0,1.1,0.1):\n",
    "        plt.plot([p*0.3+ho,p*0.3+ho],[0.0+vo,-0.01+vo],c='black')\n",
    "    plt.plot([P_not_happening*0.3+ho,P_not_happening*0.3+ho],[0.0+vo,0.15+vo],c='green',lw=2,ls='--')\n",
    "    plt.annotate(r'Prior: $P(H^c)$',xy=(P_not_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0,c = 'green')\n",
    "    plt.plot([P_positive_given_not_happening*0.3+ho,P_positive_given_not_happening*0.3+ho],[0.0+vo,0.15+vo],c='red',lw=2,ls='--')\n",
    "    plt.annotate(r'Likelihood: $P(+|H^c)$',xy=(P_positive_given_not_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0, c='red')\n",
    "    plt.plot([P_not_happening_given_positive*0.3+ho,P_not_happening_given_positive*0.3+ho],[0.0+vo,0.2+vo],c='black',lw=2,)\n",
    "    plt.annotate(r'Posterior: $P(H^c|+)$',xy=(P_not_happening_given_positive*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0)\n",
    "    \n",
    "    # P(H|-)\n",
    "    ho = 0.6; vo = 0.62\n",
    "    plt.annotate(r'$P(H|-)$: Probability Happening Given Negative Test',xy=(0.15+ho,0.31+vo),fontsize = 12,ha='center'); plt.annotate(r'$0.0$',xy=(0.0+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(r'$0.5$',xy=(0.15+ho,-0.05+vo),fontsize = 10,ha='center'); plt.annotate(r'$1.0$',xy=(0.3+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability',xy=(0.15+ho,-0.1+vo),fontsize = 10,ha='center'); plt.plot([0.0+ho,0.3+ho],[0.0+vo,0.0+vo],c='black',lw=2)\n",
    "    for p in np.arange(0.0,1.1,0.1):\n",
    "        plt.plot([p*0.3+ho,p*0.3+ho],[0.0+vo,-0.01+vo],c='black')\n",
    "    plt.plot([P_happening*0.3+ho,P_happening*0.3+ho],[0.0+vo,0.15+vo],c='green',lw=2,ls='--')\n",
    "    plt.annotate(r'Prior: $P(H)$',xy=(P_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0,c = 'green')\n",
    "    plt.plot([P_not_positive_given_happening*0.3+ho,P_not_positive_given_happening*0.3+ho],[0.0+vo,0.15+vo],c='red',lw=2,ls='--')\n",
    "    plt.annotate(r'Likelihood: $P(-|H)$',xy=(P_not_positive_given_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0, c='red')\n",
    "    plt.plot([P_happening_given_not_positive*0.3+ho,P_happening_given_not_positive*0.3+ho],[0.0+vo,0.2+vo],c='black',lw=2,)\n",
    "    plt.annotate(r'Posterior: $P(H|-)$',xy=(P_happening_given_not_positive*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0)\n",
    "    \n",
    "    # P(H^c|-)\n",
    "    ho = 0.6; vo = 0.12\n",
    "    plt.annotate(r'$P(H^c|-)$: Probability NOT Happening Given Negative Test',xy=(0.15+ho,0.31+vo),fontsize = 12,ha='center'); plt.annotate(r'$0.0$',xy=(0.0+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate(r'$0.5$',xy=(0.15+ho,-0.05+vo),fontsize = 10,ha='center'); plt.annotate(r'$1.0$',xy=(0.3+ho,-0.05+vo),fontsize = 10,ha='center')\n",
    "    plt.annotate('Probability',xy=(0.15+ho,-0.1+vo),fontsize = 10,ha='center'); plt.plot([0.0+ho,0.3+ho],[0.0+vo,0.0+vo],c='black',lw=2)\n",
    "    for p in np.arange(0.0,1.1,0.1):\n",
    "        plt.plot([p*0.3+ho,p*0.3+ho],[0.0+vo,-0.01+vo],c='black')\n",
    "    plt.plot([P_not_happening*0.3+ho,P_not_happening*0.3+ho],[0.0+vo,0.15+vo],c='green',lw=2,ls='--')\n",
    "    plt.annotate(r'Prior: $P(H^c)$',xy=(P_not_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0,c = 'green')\n",
    "    plt.plot([P_not_positive_given_not_happening*0.3+ho,P_not_positive_given_not_happening*0.3+ho],[0.0+vo,0.15+vo],c='red',lw=2,ls='--')\n",
    "    plt.annotate(r'Likelihood: $P(-|H^c)$',xy=(P_not_positive_given_not_happening*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0, c='red')\n",
    "    plt.plot([P_not_happening_given_not_positive*0.3+ho,P_not_happening_given_not_positive*0.3+ho],[0.0+vo,0.2+vo],c='black',lw=2,)\n",
    "    plt.annotate(r'Posterior: $P(H^c|-)$',xy=(P_not_happening_given_not_positive*0.3-0.01+ho,0.03+vo),fontsize = 8,ha='center',rotation=90.0)\n",
    "    \n",
    "    plt.xlim([0,1]); plt.ylim([0,1])\n",
    "    plt.tick_params(left = False, right = False, labelleft = False, labelbottom = False, bottom = False)\n",
    "    \n",
    "    plt.subplots_adjust(left=0.0, bottom=0.0, right=2., top=2.0, wspace=0.2, hspace=0.1); plt.show()\n",
    "    \n",
    "interactive_plot_summary = widgets.interactive_output(run_plot_summary, {'P_happening':P_happening,\n",
    "    'P_positive_given_happening':P_positive_given_happening,             \n",
    "    'P_positive_given_not_happening':P_positive_given_not_happening,})\n",
    "interactive_plot_summary.clear_output(wait = True)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interactive Bayesian Updating Demonstration\n",
    "\n",
    "* Select the probability of the event, $P(H)$, probability of a positive test if the event is happening, $P(+|H)$, and probability of a positive test given the event is not happening, $P(+|H^c)$ and observe the combinatorial of Bayesian updating.\n",
    "\n",
    "#### Michael J. Pyrcz, Professor, The University of Texas at Austin \n",
    "\n",
    "##### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1) | [GeostatsPy](https://github.com/GeostatsGuy/GeostatsPy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "65fba05d2f634969b120b5c7d078538b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(Text(value='                                                      Bayesian Updating Demo, Micha…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6e48ff1254f1405b8ac2fbf7077f467f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(ui2_summary, interactive_plot_summary)                           # display the interactive plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Bayesian Updating Distributions with the Gaussian Assumption\n",
    "\n",
    "Now let's use Sivia's analytical form for Bayesian updating with Gaussian distributions. \n",
    "\n",
    "Given a Gaussian prior, $N[\\mu_{prior},\\sigma^2_{prior}]$, and likelihood function, $N[\\mu_{like},\\sigma^2_{like}]$, the Gaussian posterior, $N[\\mu_{post},\\sigma^2_{post}]$, is calculated as:\n",
    "\n",
    "\\begin{equation}\n",
    "\\mu_{post}=\\frac{\\mu_{like} \\cdot \\sigma^2_{prior} + \\mu_{prior} \\cdot \\sigma^2_{like}}   \n",
    "                         {[1-\\sigma^2_{like}] [\\sigma^2_{prior} - 1] + 1}\n",
    "\\end{equation}\n",
    "\n",
    "\\begin{equation}\n",
    "\\sigma^2_{post}=\\frac{\\sigma^2_{prior} \\cdot \\sigma^2_{like}}   \n",
    "                         {[1-\\sigma^2_{like}] [\\sigma^2_{prior} - 1] + 1}\n",
    "\\end{equation}\n",
    "\n",
    "Some comments on the Gaussian assumption. \n",
    "\n",
    "* the entire problem is parameterized by the prior mean and variance, $N[\\mu_{prior},\\sigma^2_{prior}]$, and likelihood function mean and variance, $N[\\mu_{like},\\sigma^2_{like}]$.\n",
    "\n",
    "* in Gaussian space, a niave distribution has mean of 0.0, $\\mu = 0.0$, and a variance of 1.0, $\\sigma^2 = 1.0$.\n",
    "\n",
    "#### Demonstration 2, Bayesian Updating with Gaussian Distributions\n",
    "\n",
    "This dashboard accepts theparameters for the Gaussian prior, $N[\\mu_{prior},\\sigma^2_{prior}]$, and likelihood function, $N[\\mu_{like},\\sigma^2_{like}]$.\n",
    "\n",
    "##### Build the Interactive Dashboard\n",
    "\n",
    "Here's the code to build the dashboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "l = widgets.Text(value='                                                      Bayesian Updating Demo, Michael Pyrcz, Professor, The University of Texas at Austin',\n",
    "        layout=Layout(width='900px', height='30px'))\n",
    "# P_happening_label = widgets.Text(value='Probability of Happening',layout=Layout(width='50px',height='30px',line-size='0 px'))\n",
    "mu_prior = widgets.FloatSlider(min=-3, max = 3, value=0.0, step = 0.1, description = r'$\\mu_{prior}$',orientation='horizontal', \n",
    "        style = {'description_width':'initial'},layout=Layout(width='400px',height='30px'),continuous_update=False,readout_format='.3f')\n",
    "sigma_prior = widgets.FloatSlider(min=0, max = 2, value=1.0, step = 0.02, description = r'$\\sigma_{prior}$',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='400px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "\n",
    "mu_like = widgets.FloatSlider(min=-3, max = 3, value=0.0, step = 0.1, description = r'$\\mu_{like}$',orientation='horizontal', \n",
    "        style = {'description_width':'initial'},layout=Layout(width='400px',height='30px'),continuous_update=False,readout_format='.3f')\n",
    "sigma_like = widgets.FloatSlider(min=0, max = 2, value=1.0, step = 0.02, description = r'$\\sigma_{like}$',orientation='horizontal', \n",
    "        style = {'description_width': 'initial'},layout=Layout(width='400px', height='30px'),continuous_update=False,readout_format='.3f')\n",
    "\n",
    "ui_prior = widgets.VBox([mu_prior,sigma_prior],)\n",
    "ui_like = widgets.VBox([mu_like,sigma_like],)\n",
    "\n",
    "ui_summary2 = widgets.HBox([ui_prior,ui_like,],)\n",
    "ui2_summary2 = widgets.VBox([l,ui_summary2],)\n",
    "\n",
    "def run_plot_summary2(mu_prior,sigma_prior,mu_like,sigma_like):\n",
    "    sigma2_prior = sigma_prior*sigma_prior; sigma2_like = sigma_like*sigma_like\n",
    "    mu_post = (mu_like * sigma2_prior + mu_prior * sigma2_like)/((1 - sigma2_like)*(sigma2_prior - 1) + 1)\n",
    "    sigma2_post = (sigma2_prior * sigma2_like)/((1 - sigma2_like)*(sigma2_prior - 1) + 1)\n",
    "    \n",
    "    values = np.linspace(-3,3,1000)\n",
    "    PDF_prior = st.norm.pdf(values,loc = mu_prior,scale = math.sqrt(sigma2_prior))\n",
    "    PDF_like = st.norm.pdf(values,loc = mu_like,scale = math.sqrt(sigma2_like))\n",
    "    PDF_post = st.norm.pdf(values,loc = mu_post,scale = math.sqrt(sigma2_post))\n",
    "    \n",
    "    pvalues = np.linspace(0.001,0.999,1000)                   # CDF\n",
    "    Perc_prior = st.norm.ppf(pvalues,loc = mu_prior,scale = math.sqrt(sigma2_prior))\n",
    "    Perc_like = st.norm.ppf(pvalues,loc = mu_like,scale = math.sqrt(sigma2_like))\n",
    "    Perc_post = st.norm.ppf(pvalues,loc = mu_post,scale = math.sqrt(sigma2_post))\n",
    "    \n",
    "    plt.subplot(121)\n",
    "    plt.plot(values,PDF_prior,c='green',label='Prior',zorder=10); plt.fill_between(values,PDF_prior,color='green',alpha=0.05,zorder=1)\n",
    "    plt.plot(values,PDF_like,c='red',label='Likelihood',zorder=10); plt.fill_between(values,PDF_like,color='red',alpha=0.05,zorder=1) \n",
    "    plt.plot(values,PDF_post,c='black',label='Posterior',zorder=10); plt.fill_between(values,PDF_post,color='black',alpha=0.05,zorder=1)\n",
    "    \n",
    "    plt.xlabel('Feature Value'); plt.ylabel('Density'); plt.title('Bayesian Updating Gaussian, PDFs')\n",
    "    plt.xlim([-3.,3]); plt.ylim(0,10); add_grid(); plt.legend(loc = 'upper left')\n",
    "    \n",
    "    plt.subplot(122)\n",
    "    plt.plot(Perc_prior,pvalues,c='green',label='Prior')\n",
    "    plt.plot(Perc_like,pvalues,c='red',label='Likelihood')\n",
    "    plt.plot(Perc_post,pvalues,c='black',label='Posterior')\n",
    "    \n",
    "    plt.xlabel('Feature Value'); plt.ylabel('Cumulative Probability'); plt.title('Bayesian Updating Gaussian, CDFs')\n",
    "    plt.xlim([-3.,3]); plt.ylim([0,1]); add_grid(); plt.legend(loc = 'lower right')\n",
    "    \n",
    "    plt.subplots_adjust(left=0.0, bottom=0.0, right=2., top=1.0, wspace=0.2, hspace=0.1); plt.show()\n",
    "        \n",
    "interactive_plot_summary2 = widgets.interactive_output(run_plot_summary2, \n",
    "    {'mu_prior':mu_prior,'sigma_prior':sigma_prior,'mu_like':mu_like,'sigma_like':sigma_like})\n",
    "interactive_plot_summary2.clear_output(wait = True) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interactive Bayesian Updating with Gaussian Distributions Demonstration\n",
    "\n",
    "* Select the Gaussian parameters of the prior distribution, $N[\\mu_{prior},\\sigma_{prior}]$, and the likelihood function, $N[\\mu_{like},\\sigma_{like}]$ and observed the prior, likelihood and posterior PDFs and CDFs.\n",
    "\n",
    "#### Michael J. Pyrcz, Professor, The University of Texas at Austin \n",
    "\n",
    "##### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1) | [GeostatsPy](https://github.com/GeostatsGuy/GeostatsPy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9a31e99091f84068a54e39d26bccbfca",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(Text(value='                                                      Bayesian Updating Demo, Micha…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "858e1eda25dd4a0a8f70c9cdf3032709",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output(outputs=({'output_type': 'display_data', 'data': {'text/plain': '<Figure size 640x480 with 2 Axes>', 'i…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(ui2_summary2, interactive_plot_summary2)                           # display the interactive plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Comments\n",
    "\n",
    "This was 2 interactive demonstrations of Bayesian updating with interactive plots in Jupyter Notebook Python with the ipywidgets and matplotlib packages. \n",
    "\n",
    "I have many other demonstrations on data analytics and machine learning, e.g. on the basics of working with DataFrames, ndarrays, univariate statistics, plotting data, declustering, data transformations, trend modeling and many other workflows available at https://github.com/GeostatsGuy/PythonNumericalDemos and https://github.com/GeostatsGuy/GeostatsPy. \n",
    "  \n",
    "I hope this was helpful,\n",
    "\n",
    "*Michael*\n",
    "\n",
    "#### The Author:\n",
    "\n",
    "### Michael J Pyrcz, Professor, The University of Texas at Austin \n",
    "*Novel Data Analytics, Geostatistics and Machine Learning Subsurface Solutions*\n",
    "\n",
    "With over 17 years of experience in subsurface consulting, research and development, Michael has returned to academia driven by his passion for teaching and enthusiasm for enhancing engineers' and geoscientists' impact in subsurface resource development. \n",
    "\n",
    "For more about Michael check out these links:\n",
    "\n",
    "#### [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1)\n",
    "\n",
    "#### Want to Work Together?\n",
    "\n",
    "I hope this content is helpful to those that want to learn more about subsurface modeling, data analytics and machine learning. Students and working professionals are welcome to participate.\n",
    "\n",
    "* Want to invite me to visit your company for training, mentoring, project review, workflow design and / or consulting? I'd be happy to drop by and work with you! \n",
    "\n",
    "* Interested in partnering, supporting my graduate student research or my Subsurface Data Analytics and Machine Learning consortium (co-PIs including Profs. Foster, Torres-Verdin and van Oort)? My research combines data analytics, stochastic modeling and machine learning theory with practice to develop novel methods and workflows to add value. We are solving challenging subsurface problems!\n",
    "\n",
    "* I can be reached at mpyrcz@austin.utexas.edu.\n",
    "\n",
    "I'm always happy to discuss,\n",
    "\n",
    "*Michael*\n",
    "\n",
    "#### Getting Started\n",
    "\n",
    "Michael Pyrcz, Ph.D., P.Eng. Professor, Cockrell School of Engineering and The Jackson School of Geosciences, The University of Texas at Austin\n",
    "\n",
    "#### More Resources Available at: [Twitter](https://twitter.com/geostatsguy) | [GitHub](https://github.com/GeostatsGuy) | [Website](http://michaelpyrcz.com) | [GoogleScholar](https://scholar.google.com/citations?user=QVZ20eQAAAAJ&hl=en&oi=ao) | [Book](https://www.amazon.com/Geostatistical-Reservoir-Modeling-Michael-Pyrcz/dp/0199731446) | [YouTube](https://www.youtube.com/channel/UCLqEr-xV-ceHdXXXrTId5ig)  | [LinkedIn](https://www.linkedin.com/in/michael-pyrcz-61a648a1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
