{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Graphs of COVID-19 growth and doubling time \n",
    "\n",
    "This notebook uses Pandas to retrieve JSON data files created by the [Johns Hopkins Coronavirus Resource Center](https://coronavirus.jhu.edu) (and stored at [The COVID Tracking Project](https://covidtracking.com/)) to make real-time tracking plots of the growth of the COVID-19 pandemic in the US and Michigan, as well as estimate the doubling time of the number of positive cases.  These data files are updated daily, so re-running the notebook will get the most current data.  It's easy to change the state that is plotted by changing the `my_state` variable.  There's also quite a bit more information in the data files!\n",
    "\n",
    "**Important note:**  The data file tracks the number of people who have _tested positive_ of COVID in the US and Michigan, not an estimate of the total number of positive cases in the US and Michigan.\n",
    "\n",
    "Notebook by [Brian O'Shea](https://web.pa.msu.edu/people/osheabr/), last revised 2020-04-12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Two-letter US state code.  Change to the state you're interested in!\n",
    "my_state = 'MI'\n",
    "\n",
    "# If you want a high-resolution copy of this plot, set the following to True\n",
    "save_plots = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gets the data from [covidtracking.com](https://covidtracking.com) - specifically, the page [https://covidtracking.com/api](https://covidtracking.com/api).  This page has historical data for the US as a whole, for states, and for counties.  The JSON files have a ton of data in addition to what we're showing.\n",
    "\n",
    "Note: the Pandas [`read_json`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_json.html) method is really powerful - it can read both local and remote JSON files!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "us = pd.read_json(\"https://covidtracking.com/api/us/daily\")\n",
    "all_states = pd.read_json(\"https://covidtracking.com/api/v1/states/daily.json\")\n",
    "\n",
    "# select out the state I care about\n",
    "state = all_states[all_states['state']==my_state]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "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>date</th>\n",
       "      <th>states</th>\n",
       "      <th>positive</th>\n",
       "      <th>negative</th>\n",
       "      <th>pending</th>\n",
       "      <th>hospitalizedCurrently</th>\n",
       "      <th>hospitalizedCumulative</th>\n",
       "      <th>inIcuCurrently</th>\n",
       "      <th>inIcuCumulative</th>\n",
       "      <th>onVentilatorCurrently</th>\n",
       "      <th>...</th>\n",
       "      <th>lastModified</th>\n",
       "      <th>total</th>\n",
       "      <th>totalTestResults</th>\n",
       "      <th>posNeg</th>\n",
       "      <th>deathIncrease</th>\n",
       "      <th>hospitalizedIncrease</th>\n",
       "      <th>negativeIncrease</th>\n",
       "      <th>positiveIncrease</th>\n",
       "      <th>totalTestResultsIncrease</th>\n",
       "      <th>hash</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20200727</td>\n",
       "      <td>56</td>\n",
       "      <td>4275188</td>\n",
       "      <td>47977146</td>\n",
       "      <td>3398.0</td>\n",
       "      <td>59023.0</td>\n",
       "      <td>294472.0</td>\n",
       "      <td>10328.0</td>\n",
       "      <td>13412.0</td>\n",
       "      <td>2720.0</td>\n",
       "      <td>...</td>\n",
       "      <td>2020-07-27T00:00:00Z</td>\n",
       "      <td>52255732</td>\n",
       "      <td>52252334</td>\n",
       "      <td>52252334</td>\n",
       "      <td>1059</td>\n",
       "      <td>1690</td>\n",
       "      <td>705706</td>\n",
       "      <td>55134</td>\n",
       "      <td>760840</td>\n",
       "      <td>021bea33ea5ddba5408c2a928ad900ae036a25dc</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20200726</td>\n",
       "      <td>56</td>\n",
       "      <td>4220054</td>\n",
       "      <td>47271440</td>\n",
       "      <td>3361.0</td>\n",
       "      <td>58614.0</td>\n",
       "      <td>292782.0</td>\n",
       "      <td>10353.0</td>\n",
       "      <td>13343.0</td>\n",
       "      <td>2723.0</td>\n",
       "      <td>...</td>\n",
       "      <td>2020-07-26T00:00:00Z</td>\n",
       "      <td>51494855</td>\n",
       "      <td>51491494</td>\n",
       "      <td>51491494</td>\n",
       "      <td>558</td>\n",
       "      <td>1435</td>\n",
       "      <td>794098</td>\n",
       "      <td>61713</td>\n",
       "      <td>855811</td>\n",
       "      <td>820426c4c5479c7a0f8974e68aa7016f2082a93e</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>20200725</td>\n",
       "      <td>56</td>\n",
       "      <td>4158341</td>\n",
       "      <td>46477342</td>\n",
       "      <td>3377.0</td>\n",
       "      <td>59227.0</td>\n",
       "      <td>291347.0</td>\n",
       "      <td>10380.0</td>\n",
       "      <td>13279.0</td>\n",
       "      <td>2729.0</td>\n",
       "      <td>...</td>\n",
       "      <td>2020-07-25T00:00:00Z</td>\n",
       "      <td>50639060</td>\n",
       "      <td>50635683</td>\n",
       "      <td>50635683</td>\n",
       "      <td>1037</td>\n",
       "      <td>1992</td>\n",
       "      <td>732176</td>\n",
       "      <td>65413</td>\n",
       "      <td>797589</td>\n",
       "      <td>ea28b353271e8d21ff5f3b189169c0d974de8b29</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20200724</td>\n",
       "      <td>56</td>\n",
       "      <td>4092928</td>\n",
       "      <td>45745166</td>\n",
       "      <td>3409.0</td>\n",
       "      <td>59670.0</td>\n",
       "      <td>289355.0</td>\n",
       "      <td>10405.0</td>\n",
       "      <td>13182.0</td>\n",
       "      <td>2712.0</td>\n",
       "      <td>...</td>\n",
       "      <td>2020-07-24T00:00:00Z</td>\n",
       "      <td>49841503</td>\n",
       "      <td>49838094</td>\n",
       "      <td>49838094</td>\n",
       "      <td>1178</td>\n",
       "      <td>3026</td>\n",
       "      <td>854645</td>\n",
       "      <td>75193</td>\n",
       "      <td>929838</td>\n",
       "      <td>5a28d1fb68592ad25bd4746557e1f68250423dea</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20200723</td>\n",
       "      <td>56</td>\n",
       "      <td>4017735</td>\n",
       "      <td>44890521</td>\n",
       "      <td>3179.0</td>\n",
       "      <td>59885.0</td>\n",
       "      <td>286329.0</td>\n",
       "      <td>10418.0</td>\n",
       "      <td>12933.0</td>\n",
       "      <td>2472.0</td>\n",
       "      <td>...</td>\n",
       "      <td>2020-07-23T00:00:00Z</td>\n",
       "      <td>48911435</td>\n",
       "      <td>48908256</td>\n",
       "      <td>48908256</td>\n",
       "      <td>1039</td>\n",
       "      <td>2500</td>\n",
       "      <td>753372</td>\n",
       "      <td>71027</td>\n",
       "      <td>824399</td>\n",
       "      <td>1d8eb95c208f9afdd53bc9946b37be590b17a635</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 25 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       date  states  positive  negative  pending  hospitalizedCurrently  \\\n",
       "0  20200727      56   4275188  47977146   3398.0                59023.0   \n",
       "1  20200726      56   4220054  47271440   3361.0                58614.0   \n",
       "2  20200725      56   4158341  46477342   3377.0                59227.0   \n",
       "3  20200724      56   4092928  45745166   3409.0                59670.0   \n",
       "4  20200723      56   4017735  44890521   3179.0                59885.0   \n",
       "\n",
       "   hospitalizedCumulative  inIcuCurrently  inIcuCumulative  \\\n",
       "0                294472.0         10328.0          13412.0   \n",
       "1                292782.0         10353.0          13343.0   \n",
       "2                291347.0         10380.0          13279.0   \n",
       "3                289355.0         10405.0          13182.0   \n",
       "4                286329.0         10418.0          12933.0   \n",
       "\n",
       "   onVentilatorCurrently  ...          lastModified     total  \\\n",
       "0                 2720.0  ...  2020-07-27T00:00:00Z  52255732   \n",
       "1                 2723.0  ...  2020-07-26T00:00:00Z  51494855   \n",
       "2                 2729.0  ...  2020-07-25T00:00:00Z  50639060   \n",
       "3                 2712.0  ...  2020-07-24T00:00:00Z  49841503   \n",
       "4                 2472.0  ...  2020-07-23T00:00:00Z  48911435   \n",
       "\n",
       "  totalTestResults    posNeg  deathIncrease hospitalizedIncrease  \\\n",
       "0         52252334  52252334           1059                 1690   \n",
       "1         51491494  51491494            558                 1435   \n",
       "2         50635683  50635683           1037                 1992   \n",
       "3         49838094  49838094           1178                 3026   \n",
       "4         48908256  48908256           1039                 2500   \n",
       "\n",
       "   negativeIncrease  positiveIncrease  totalTestResultsIncrease  \\\n",
       "0            705706             55134                    760840   \n",
       "1            794098             61713                    855811   \n",
       "2            732176             65413                    797589   \n",
       "3            854645             75193                    929838   \n",
       "4            753372             71027                    824399   \n",
       "\n",
       "                                       hash  \n",
       "0  021bea33ea5ddba5408c2a928ad900ae036a25dc  \n",
       "1  820426c4c5479c7a0f8974e68aa7016f2082a93e  \n",
       "2  ea28b353271e8d21ff5f3b189169c0d974de8b29  \n",
       "3  5a28d1fb68592ad25bd4746557e1f68250423dea  \n",
       "4  1d8eb95c208f9afdd53bc9946b37be590b17a635  \n",
       "\n",
       "[5 rows x 25 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "us.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "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>date</th>\n",
       "      <th>state</th>\n",
       "      <th>positive</th>\n",
       "      <th>negative</th>\n",
       "      <th>pending</th>\n",
       "      <th>hospitalizedCurrently</th>\n",
       "      <th>hospitalizedCumulative</th>\n",
       "      <th>inIcuCurrently</th>\n",
       "      <th>inIcuCumulative</th>\n",
       "      <th>onVentilatorCurrently</th>\n",
       "      <th>...</th>\n",
       "      <th>posNeg</th>\n",
       "      <th>deathIncrease</th>\n",
       "      <th>hospitalizedIncrease</th>\n",
       "      <th>hash</th>\n",
       "      <th>commercialScore</th>\n",
       "      <th>negativeRegularScore</th>\n",
       "      <th>negativeScore</th>\n",
       "      <th>positiveScore</th>\n",
       "      <th>score</th>\n",
       "      <th>grade</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20200727</td>\n",
       "      <td>AK</td>\n",
       "      <td>3206.0</td>\n",
       "      <td>204162.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>38.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>3.0</td>\n",
       "      <td>...</td>\n",
       "      <td>207368</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>de28ff6d7d2874c791219904c2fa81f83142a78f</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20200727</td>\n",
       "      <td>AL</td>\n",
       "      <td>81115.0</td>\n",
       "      <td>576844.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1599.0</td>\n",
       "      <td>9694.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1081.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>657959</td>\n",
       "      <td>18</td>\n",
       "      <td>537</td>\n",
       "      <td>906fddfa88864f88bdf0d2bcb19cf267a406f2e6</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>20200727</td>\n",
       "      <td>AR</td>\n",
       "      <td>39447.0</td>\n",
       "      <td>445444.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>489.0</td>\n",
       "      <td>2624.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>110.0</td>\n",
       "      <td>...</td>\n",
       "      <td>484891</td>\n",
       "      <td>7</td>\n",
       "      <td>82</td>\n",
       "      <td>819db85fb84f50809d492ae373ea4914e01077f0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20200727</td>\n",
       "      <td>AS</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1037.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>1037</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>e2900aeb060df366a3f3a70300dccec3b2e33ae8</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20200727</td>\n",
       "      <td>AZ</td>\n",
       "      <td>163827.0</td>\n",
       "      <td>714506.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2626.0</td>\n",
       "      <td>7751.0</td>\n",
       "      <td>820.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>567.0</td>\n",
       "      <td>...</td>\n",
       "      <td>878333</td>\n",
       "      <td>-1</td>\n",
       "      <td>45</td>\n",
       "      <td>11d6f676a2f3a2381d94968e48b3b0b447284a05</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td></td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 41 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       date state  positive  negative  pending  hospitalizedCurrently  \\\n",
       "0  20200727    AK    3206.0  204162.0      NaN                   38.0   \n",
       "1  20200727    AL   81115.0  576844.0      NaN                 1599.0   \n",
       "2  20200727    AR   39447.0  445444.0      NaN                  489.0   \n",
       "3  20200727    AS       0.0    1037.0      NaN                    NaN   \n",
       "4  20200727    AZ  163827.0  714506.0      NaN                 2626.0   \n",
       "\n",
       "   hospitalizedCumulative  inIcuCurrently  inIcuCumulative  \\\n",
       "0                     NaN             NaN              NaN   \n",
       "1                  9694.0             NaN           1081.0   \n",
       "2                  2624.0             NaN              NaN   \n",
       "3                     NaN             NaN              NaN   \n",
       "4                  7751.0           820.0              NaN   \n",
       "\n",
       "   onVentilatorCurrently  ...  posNeg  deathIncrease hospitalizedIncrease  \\\n",
       "0                    3.0  ...  207368              1                    0   \n",
       "1                    NaN  ...  657959             18                  537   \n",
       "2                  110.0  ...  484891              7                   82   \n",
       "3                    NaN  ...    1037              0                    0   \n",
       "4                  567.0  ...  878333             -1                   45   \n",
       "\n",
       "                                       hash commercialScore  \\\n",
       "0  de28ff6d7d2874c791219904c2fa81f83142a78f               0   \n",
       "1  906fddfa88864f88bdf0d2bcb19cf267a406f2e6               0   \n",
       "2  819db85fb84f50809d492ae373ea4914e01077f0               0   \n",
       "3  e2900aeb060df366a3f3a70300dccec3b2e33ae8               0   \n",
       "4  11d6f676a2f3a2381d94968e48b3b0b447284a05               0   \n",
       "\n",
       "  negativeRegularScore  negativeScore  positiveScore score  grade  \n",
       "0                    0              0              0     0         \n",
       "1                    0              0              0     0         \n",
       "2                    0              0              0     0         \n",
       "3                    0              0              0     0         \n",
       "4                    0              0              0     0         \n",
       "\n",
       "[5 rows x 41 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_states.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get two columns for plotting - first, get usable dates from Pandas.  The data files we retrieve use an integer YYYYMMDD code for dates, which we convert to something that matplotlib can work with more easily and store it in an array.  Also get an array of positive cases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# US\n",
    "fixed_US_dates = pd.to_datetime(us['date'], format='%Y%m%d')\n",
    "\n",
    "positive_US_cases = us['positive']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# State of choice\n",
    "fixed_state_dates = pd.to_datetime(state['date'], format='%Y%m%d')\n",
    "\n",
    "positive_state_cases = state['positive']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "US:     2020-07-27\n",
      "State:  2020-07-27\n"
     ]
    }
   ],
   "source": [
    "# get the date\n",
    "ts=fixed_US_dates[0]\n",
    "mydate = (str(ts)).split(' ')[0]\n",
    "print(\"US:    \", mydate)\n",
    "\n",
    "state_date=fixed_state_dates.iloc[0]\n",
    "my_state_date = (str(state_date)).split(' ')[0]\n",
    "print(\"State: \",my_state_date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "positive US cases: 4,275,188 on 2020-07-27\n",
      "positive MI cases: 87,173 on 2020-07-27\n"
     ]
    }
   ],
   "source": [
    "print(\"positive US cases: {:,} on {:s}\".format(positive_US_cases[0],mydate))\n",
    "print(\"positive \"+my_state+\" cases: {:,} on {:s}\".format(int(positive_state_cases.iloc[0]),mydate))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot cumulative positive tests for US and a state\n",
    "\n",
    "This plots the cumulative number of positive tests in the US as a whole and a single state, as specified at the top of this file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "ename": "ConversionError",
     "evalue": "Failed to convert value(s) to axis units: '2020-03-01'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/axis.py\u001b[0m in \u001b[0;36mconvert_units\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m   1572\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1573\u001b[0;31m             \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconverter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1574\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/dates.py\u001b[0m in \u001b[0;36mconvert\u001b[0;34m(value, unit, axis)\u001b[0m\n\u001b[1;32m   1920\u001b[0m         \"\"\"\n\u001b[0;32m-> 1921\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mdate2num\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1922\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/dates.py\u001b[0m in \u001b[0;36mdate2num\u001b[0;34m(d)\u001b[0m\n\u001b[1;32m    436\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 437\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0m_to_ordinalf_np_vectorized\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    438\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/numpy/lib/function_base.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   2090\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2091\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_vectorize_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mvargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2092\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/numpy/lib/function_base.py\u001b[0m in \u001b[0;36m_vectorize_call\u001b[0;34m(self, func, args)\u001b[0m\n\u001b[1;32m   2160\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2161\u001b[0;31m             \u001b[0mufunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0motypes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_ufunc_and_otypes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2162\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/numpy/lib/function_base.py\u001b[0m in \u001b[0;36m_get_ufunc_and_otypes\u001b[0;34m(self, func, args)\u001b[0m\n\u001b[1;32m   2120\u001b[0m             \u001b[0minputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflat\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2121\u001b[0;31m             \u001b[0moutputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   2122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/dates.py\u001b[0m in \u001b[0;36m_to_ordinalf\u001b[0;34m(dt)\u001b[0m\n\u001b[1;32m    221\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 222\u001b[0;31m     \u001b[0mbase\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtoordinal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    223\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'numpy.str_' object has no attribute 'toordinal'",
      "\nThe above exception was the direct cause of the following exception:\n",
      "\u001b[0;31mConversionError\u001b[0m                           Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-10-edd362e5ffd5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0myscale\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'log'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m4.0e+6\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'2020-03-01'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'2020-06-30'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      8\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxticks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrotation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m60\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Date'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m16\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/pyplot.py\u001b[0m in \u001b[0;36mxlim\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m   1394\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0margs\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1395\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_xlim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1396\u001b[0;31m     \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_xlim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1397\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1398\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py\u001b[0m in \u001b[0;36mset_xlim\u001b[0;34m(self, left, right, emit, auto, xmin, xmax)\u001b[0m\n\u001b[1;32m   3182\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3183\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_process_unit_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mleft\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mright\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3184\u001b[0;31m         \u001b[0mleft\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_converted_limits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mleft\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_xunits\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   3185\u001b[0m         \u001b[0mright\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_converted_limits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mright\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_xunits\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3186\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py\u001b[0m in \u001b[0;36m_validate_converted_limits\u001b[0;34m(self, limit, convert)\u001b[0m\n\u001b[1;32m   3096\u001b[0m         \"\"\"\n\u001b[1;32m   3097\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mlimit\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3098\u001b[0;31m             \u001b[0mconverted_limit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconvert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlimit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   3099\u001b[0m             if (isinstance(converted_limit, Real)\n\u001b[1;32m   3100\u001b[0m                     and not np.isfinite(converted_limit)):\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/artist.py\u001b[0m in \u001b[0;36mconvert_xunits\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m    176\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0max\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxaxis\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    177\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 178\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxaxis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_units\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    179\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    180\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mconvert_yunits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/matplotlib/axis.py\u001b[0m in \u001b[0;36mconvert_units\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m   1574\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1575\u001b[0m             raise munits.ConversionError('Failed to convert value(s) to axis '\n\u001b[0;32m-> 1576\u001b[0;31m                                          f'units: {x!r}') from e\n\u001b[0m\u001b[1;32m   1577\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1578\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mConversionError\u001b[0m: Failed to convert value(s) to axis units: '2020-03-01'"
     ]
    },
    {
     "data": {
      "image/png": "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FA61MspRX37po1J/9hkMHAh//GOSpTwvvujro46CnXdOSRpFpLColVGO+t3vvPK4SxcYNy4FRf7R+oMGTZggIsVERUY5aOlSuP123x4/HnbdNckLbt4Mf/+7b6v+QETqoICQg6680ouMzj47RcX9//u/sHatD2R34IEpuKCIFCIFhBzzzDMwdSq0bg133JGCC4bgc2wC/PSnam4qInVSQMghX34JV1zh2zfeCB06pOCib77plRG77+5NlkRE6qCAkEN+9ztYsgR69oTLL0/RRe+5x9cXXqjWRSKyQ2kJCGZ2ipn91cyeMjM1a0nAE0/48BRmnoc3bZqCi65e7YPZNWkCw4al4IIiUsgSDghmNtbM1pjZu7X29zOzxWa2xMxGAIQQngwhXAScB6icoh5z58KPfuTbt94K3/teii781796r7YBA7z9qojIDjTkDWEc0C92h5mVAKOA/kAvYIiZ9Yo55LrI36UOK1d6fr1xI5x7Llx7bYouXFUFo0f7dnTyZRGRHUg4IIQQZgCf1NrdG1gSQlgaQtgCTARONnc78GwI4a141zOzoWZWbmbllZWVjU1/XtuwwXshL18O3/kO3HdfChsBPf+8X7hHD/j+91N0UREpZMkObtcRWBbzuQLoA/wUOAZoa2bdQgija58YQhhjZiuBAc2aNTssyXTknS1b4LTToLwcunaFKVOgefMU3uDhh3197rlqaioiCUm2UjleThNCCHeFEA4LIQyLFwxiDizaoStGjPAf8Xvu6aNK7LlnCi++fj08+aRv//CHKbywiBSyZANCBdAp5nMpsCLRk4t1cLvXXoORI6GkBKZN8/lqUmrKFNi0ybs5qzJZRBKUbECYDXQ3s65m1gwYDExN9ORifEPYtAkuuMA7EA8fDn36pOEmjzzi67POSsPFRaRQNaTZ6QRgJrC/mVWY2QUhhCrgMmA6sAh4LISwoAHXLLo3hGuugcWLvfPZr3+dhhusXOlDXTdt6uNni4gkKOFK5RDCkDr2PwM805ibhxCmAdPKysouasz5+eaZZ2DUKM+rH37Y56pJuYkTYds2b760225puIGIFCpNkJMha9bA+ef79s03+8CjaRFtXXT22Wm6gYgUKk2QkwEh+FBCa9bA0UfD1Ven6UaLFvk0mW3bwoknpukmIlKoNLhdBkye7K2J2rb1CW9KStJ0o2hT01NPTVN5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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "state_lines=ax.plot(fixed_state_dates,positive_state_cases,'r-',label=my_state,linewidth=2)\n",
    "us_lines=ax.plot(fixed_US_dates,positive_US_cases,'b-',label='US',linewidth=2)\n",
    "plt.yscale('log')\n",
    "plt.ylim(1.0,4.0e+6)\n",
    "plt.xlim('2020-03-01','2020-06-30')\n",
    "plt.xticks(rotation=60)\n",
    "plt.xlabel('Date',size=16)\n",
    "plt.ylabel('Number of positive tests',size=16)\n",
    "plt.title(\"Cumulative positive COVID-19\\n tests in US, \"+my_state,size=18)\n",
    "plt.xticks(fontsize=14)\n",
    "plt.yticks(fontsize=14)\n",
    "plt.grid(zorder=-10,alpha=0.5)\n",
    "plt.text(\"2020-03-26\",12,\"Last data point:\\n\"+mydate,fontsize=14)\n",
    "\n",
    "legend = ax.legend(loc='upper left', shadow=True, fontsize='x-large')\n",
    "\n",
    "if save_plots==True:\n",
    "    plt.savefig(\"cum_pos_tests_US_and_\"+my_state+\".png\",dpi=200,bbox_inches='tight',pad_inches=0.25)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Doubling time plot\n",
    "\n",
    "Now we calculate an estimate of the [doubling time](https://en.wikipedia.org/wiki/Doubling_time) of positive COVID-19 tests (which gives us a sense of how quickly the virus is spreading).  The doubling time is the amount of time it takes the number of cases to increase by a factor of two.  We use the instantaneous approximation of the doubling time - for times $t_1$ and $t_2$, and number of cases at those times $n_1$ and $n_2$, we can approximately the doubling time $\\tau_d$ as:\n",
    "\n",
    "$\\tau_d \\simeq (t_2 - t_1) \\frac{ln(2)}{ln(n_2/n_1)}$\n",
    "\n",
    "A constant instantaneous doubling time as a function of time means that there is perfectly exponential growth of positive COVID-19 cases, which is what one expects for an infectious disease that is spreading without any attempts to control it.  The hope with social distancing and other measures is that the doubling time will get _larger_ - that is, the spread of the disease will slow down.\n",
    "\n",
    "Note that because this value is instantaneous, it's rather noisy (which is to say, it jumps around quite a bit).  Look for trends rather than any single day's value.  (A smoothed version is at the end of this notebook.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get just the values for positive cases\n",
    "us_case_vals = us['positive'].values\n",
    "us_dates_vals = us['date'].values\n",
    "\n",
    "state_case_vals = state['positive'].values\n",
    "state_dates_vals = state['date'].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dt=1.0\n",
    "\n",
    "# Estimate doubling time using the math above.  We're using day N and N-1, so we lose the first data of data.\n",
    "# Numpy will complain about divide-by-zero errors, but it will still make a plot!\n",
    "\n",
    "us_doubling_time = dt * math.log(2) / np.log(us_case_vals[0:-1]/us_case_vals[1:] )\n",
    "\n",
    "state_doubling_time = dt * math.log(2) / np.log(state_case_vals[0:-1]/state_case_vals[1:] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "us_lines=ax.plot(fixed_US_dates[1:],us_doubling_time,'b-',label='US',linewidth=2)\n",
    "state_lines=ax.plot(fixed_state_dates[1:],state_doubling_time,'r-',label=my_state,linewidth=2)\n",
    "plt.xlim('2020-03-01','2020-06-30')\n",
    "plt.xticks(rotation=60)\n",
    "plt.xlabel('Date',size=16)\n",
    "plt.ylim(0,300)\n",
    "plt.ylabel('Doubling time [days]',size=16)\n",
    "plt.title(\"COVID-19 positive test doubling \\ntime for US and \"+my_state,size=18)\n",
    "plt.xticks(fontsize=14)\n",
    "plt.yticks([0,50,100,150,200,250,300],fontsize=14)\n",
    "plt.grid(zorder=-10,alpha=0.5)\n",
    "plt.text(\"2020-03-07\",21,\"Last data point:\\n\"+mydate,fontsize=14)\n",
    "\n",
    "legend = ax.legend(loc='upper left', shadow=True, fontsize='x-large')\n",
    "\n",
    "if save_plots==True:\n",
    "    plt.savefig(\"doubling_time_pos_tests_US_and_\"+my_state+\".png\",dpi=200,bbox_inches='tight',pad_inches=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "state_delta=np.copy(state_case_vals)\n",
    "\n",
    "state_delta[1:] = state_case_vals[0:-1]-state_delta[1:]\n",
    "\n",
    "state_delta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot the daily new cases for Michigan\n",
    "\n",
    "Also plot the smoothed version of the \"daily new cases\" plot using a [Savitzky–Golay filter](https://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter) ([scipy docs](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html)) so it's easier to see trends!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "from scipy.signal import savgol_filter\n",
    "smoothed_state_cases = savgol_filter(state_delta[1:], 15, 2)\n",
    "\n",
    "state_lines=ax.plot(fixed_state_dates[1:],state_delta[1:],'r-',label=my_state,linewidth=2)\n",
    "state_smooth_lines=ax.plot(fixed_state_dates[1:],smoothed_state_cases,'r--',label=my_state,linewidth=2,alpha=0.5)\n",
    "plt.xticks(rotation=60)\n",
    "plt.xlabel('Date',size=16)\n",
    "#plt.ylim(0,2.0e4)\n",
    "plt.yscale('log')\n",
    "\n",
    "plt.ylabel('New cases',size=16)\n",
    "plt.title(\"COVID-19 daily new cases for \"+my_state,size=18)\n",
    "plt.xticks(fontsize=14)\n",
    "#plt.yticks([0,5,10,15,20,25,30,35,40],fontsize=14)\n",
    "plt.grid(zorder=-10,alpha=0.5)\n",
    "plt.text(\"2020-04-01\",50,\"Last data point:\\n\"+mydate,fontsize=14)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Smoothed version of doubling time plot\n",
    "\n",
    "Just to make it easier to see what's going on, do the same thing for doubling time.  This also uses a Savitzky-Golay filter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.signal import savgol_filter\n",
    "smoothed_us_doubling_time = savgol_filter(us_doubling_time, 21, 2)\n",
    "smoothed_state_doubling_time = savgol_filter(state_doubling_time, 11, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "us_lines=ax.plot(fixed_US_dates[1:],us_doubling_time,'b--',label='US',linewidth=2,alpha=0.5)\n",
    "state_lines=ax.plot(fixed_state_dates[1:],state_doubling_time,'r--',label=my_state,linewidth=2,alpha=0.5)\n",
    "\n",
    "us_lines=ax.plot(fixed_US_dates[1:],smoothed_us_doubling_time,'b-',label='US',linewidth=2)\n",
    "state_lines=ax.plot(fixed_state_dates[1:],smoothed_state_doubling_time,'r-',label=my_state,linewidth=2)\n",
    "plt.xticks(rotation=60)\n",
    "plt.xlabel('Date',size=16)\n",
    "plt.xlim('2020-03-01','2020-06-30')\n",
    "plt.ylim(0,250)\n",
    "plt.ylabel('Doubling time [days]',size=16)\n",
    "plt.title(\"COVID-19 positive test doubling \\ntime for US and \"+my_state+\" - SMOOTHED\",size=18)\n",
    "plt.xticks(fontsize=14)\n",
    "#plt.yticks([0,10,20,30,40,50,60,70,80,90,100,110,120],fontsize=14)\n",
    "plt.yticks([0,30,60,90,120,150,180,210,240],fontsize=14)\n",
    "plt.grid(zorder=-10,alpha=0.5)\n",
    "plt.text(\"2020-03-07\",21,\"Last data point:\\n\"+mydate,fontsize=14)\n",
    "\n",
    "legend = ax.legend(loc='upper left', shadow=True, fontsize='x-large')\n",
    "\n",
    "if save_plots==True:\n",
    "    plt.savefig(\"doubling_time_pos_tests_US_and_\"+my_state+\".png\",dpi=200,bbox_inches='tight',pad_inches=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
