def demand_curves(ranking_provider, vax_policy, phis=[25, 50, 100, 200], phi_benchmark=25, N_state=N_TN): wtp_rankings = {phi: ranking_provider(phi, vax_policy) for phi in phis} figure = plt.figure() lines = [] # benchmark benchmark = wtp_rankings[phi_benchmark] x_pop = list( chain(*zip(benchmark.loc[0]["num_vax"].shift(1).fillna(0), benchmark.loc[0]["num_vax"]))) y_wtp = list( chain(*zip(benchmark.loc[0]["wtp_pc_usd"], benchmark.loc[0] ["wtp_pc_usd"]))) lines.append( plt.plot(x_pop, y_wtp, figure=figure, color="black", linewidth=2)[0]) lines.append(plt.plot(0, 0, color="white")[0]) # plot dynamic curve for (phi, all_wtp) in wtp_rankings.items(): daily_doses = phi * percent * annually * N_state distributed_doses = 0 x_pop = [] y_wtp = [] t_vax = [] ranking = 0 for t in range(simulation_range): wtp = all_wtp.loc[t].reset_index() ranking = wtp[(wtp.index >= ranking) & (wtp.num_vax > distributed_doses)].index.min() if np.isnan(ranking): break x_pop += [distributed_doses, distributed_doses + daily_doses] t_vax += [t, t + 1] y_wtp += [wtp.iloc[ranking].wtp_pc_usd] * 2 distributed_doses += daily_doses lines.append( plt.plot(x_pop, y_wtp, label=f"dynamic, {vax_policy}, $\phi = ${phi}%", figure=figure)[0]) plt.legend(lines, [f"static, t = 0, $\phi = ${phi_benchmark}%", ""] + [f"dynamic, {vax_policy}, $\phi = ${phi}%" for phi in phis], title="allocation", title_fontsize="24", fontsize="20") plt.xticks(fontsize="20") plt.yticks(fontsize="20") plt.PlotDevice().ylabel("WTP (USD)\n").xlabel("\nnumber vaccinated") plt.ylim(0, 350) plt.xlim(left=0, right=N_TN) plt.show()
'Cumulative total per thousand': "total_per_thousand", 'Daily change in cumulative total per thousand': "delta_per_thousand", '7-day smoothed daily change': "smoothed_delta", '7-day smoothed daily change per thousand': "smoothed_delta_per_thousand", 'Short-term positive rate': "positivity", 'Short-term tests per case': "tests_per_case" } testing = pd.read_csv("data/covid-testing-all-observations.csv", parse_dates=["Date"]) testing = testing[testing["ISO code"] == "IND"]\ .dropna()\ [schema.keys()]\ .rename(columns = schema) testing["month"] = testing.date.dt.month def formula(order: int) -> str: powers = " + ".join(f"np.power(delta_per_thousand, {i + 1})" for i in range(order)) return f"smoothed_delta ~ -1 + daily_tests + C(month)*({powers})" model = OLS.from_formula(formula(order=3), data=testing).fit() print(summary_col(model, regressor_order=["daily_tests"], drop_omitted=True)) plt.plot(0.2093 * df["TT"][:, "delta", "tested"], label="test-scaled") plt.plot(df["TT"][:, "delta", "confirmed"], label="confirmed") plt.legend() plt.show()
outcomes_per_policy(v1_sum, reference = (25, "contact"), metric_label = "v1", fmt = "D") proxy_sum = {} proxy_raw = {} for (phi, policy) in params[1:]: pr = np.sum(np.load(src / f"proxyLLweight_BR_Gopalganj_phi{phi}_{policy}.npz")['arr_0'], axis = (0, 2)) ps = np.sum(np.load(src / f"proxyLLweight_BR_Gopalganj_phi{phi}_{policy}.npz")['arr_0'], axis = 0) @ (N_jk * years_life_remaining.loc["Bihar"]) proxy_raw[phi, policy] = np.percentile(pr, [50, 5, 95], axis = 0) proxy_sum[phi, policy] = np.percentile(ps, [50, 5, 95], axis = 0) outcomes_per_policy(proxy_raw, reference = (25, "contact"), metric_label = "sum 1-qbar * LE (no population weights)", fmt = "D") # outcomes_per_policy(proxy_sum, reference = (25, "contact"), metric_label = "sum 1-qbar * LE", fmt = "D") for phi, policy in params: plt.plot( np.median( np.load(tev_src / f"BR_Gopalganj_phi{phi}_{policy}.npz")['dT'], axis = 1), label = (phi, policy) ) plt.legend() plt.show() for phi, policy in params: plt.plot( np.median( np.load(tev_src / f"BR_Gopalganj_phi{phi}_{policy}.npz")['dD'], axis = 1), label = (phi, policy) ) plt.legend() plt.show()
state_code, N_district, N_0, N_1, N_2, N_3, N_4, N_5, N_6 = districts_to_run.loc[state, district][population_columns] def get_cons_decline(p1, p2 = None): if p2: p = src/f"{state_code}_{district}_phi{p1}_{p2}.npz" else: p = src/f"{state_code}_{district}_phi25_novax.npz" with np.load(p) as policy: dI_pc = policy['dT']/N_district dD_pc = policy['dD']/N_district return income_decline(state, district, dI_pc, dD_pc) rc_vectors = {p: np.median(get_cons_decline(*p), axis = 1) for p in params} for (k, v) in rc_vectors.items(): plt.plot(v, label = k) plt.legend() plt.show() state_code = "TN" TN_cons_predicted = {p:0 for p in params} TN_cons2019 = consumption_2019.loc["Tamil Nadu"].sum(axis = 1) rcs = dict() for district in TN_cons2019.index: N_district = districts_to_run.loc["Tamil Nadu", district].N_tot for p in params: if len(p) > 1: p1, p2 = p simfile = src/f"{state_code}_{district}_phi{p1}_{p2}.npz" else: simfile = src/f"{state_code}_{district}_phi25_novax.npz"
def plot_mobility(series, label, stringency = None, until = None, annotation = "Google Mobility Data; baseline mobility measured from Jan 3 - Feb 6"): plt.plot(series.date, smoothed(series.retail_and_recreation_percent_change_from_baseline), label = "Retail/Recreation") plt.plot(series.date, smoothed(series.grocery_and_pharmacy_percent_change_from_baseline), label = "Grocery/Pharmacy") plt.plot(series.date, smoothed(series.parks_percent_change_from_baseline), label = "Parks") plt.plot(series.date, smoothed(series.transit_stations_percent_change_from_baseline), label = "Transit Stations") plt.plot(series.date, smoothed(series.workplaces_percent_change_from_baseline), label = "Workplaces") plt.plot(series.date, smoothed(series.residential_percent_change_from_baseline), label = "Residential") if until: right = pd.Timestamp(until) elif stringency is not None: right = stringency.Date.max() else: right = series.date.iloc[-1] lax = plt.gca() if stringency is not None: plt.sca(lax.twinx()) stringency_IN = stringency.query("CountryName == 'India'") stringency_US = stringency.query("(CountryName == 'United States') & (RegionName.isnull())", engine = "python") plt.plot(stringency_IN.Date, stringency_IN.StringencyIndex, 'k--', alpha = 0.6, label = "IN Measure Stringency") plt.plot(stringency_US.Date, stringency_US.StringencyIndex, 'k.' , alpha = 0.6, label = "US Measure Stringency") plt.PlotDevice().ylabel("lockdown stringency index", rotation = -90, labelpad = 50) plt.legend() plt.sca(lax) plt.legend(loc = "lower right") plt.fill_betweenx((-100, 60), pd.to_datetime("March 24, 2020"), pd.to_datetime("June 1, 2020"), color = "black", alpha = 0.05, zorder = -1) plt.text(s = "national lockdown", x = pd.to_datetime("April 27, 2020"), y = -90, fontdict = plt.theme.note, ha = "center", va = "top") plt.PlotDevice()\ .xlabel("\ndate")\ .ylabel("% change in mobility\n") # .title(f"\n{label}: Mobility & Lockdown Trends")\ # .annotate(annotation)\ plt.ylim(-100, 60) plt.xlim(left = series.date.iloc[0], right = right)
import flat_table from epimargin.etl.commons import download_data data = Path("./data") download_data(data, 'timeseries.json', "https://api.covid19india.org/v3/") # data prep with (data/'timeseries.json').open("rb") as fp: df = flat_table.normalize(pd.read_json(fp)).fillna(0) df.columns = df.columns.str.split('.', expand = True) dates = np.squeeze(df["index"][None].values) df = df.drop(columns = "index").set_index(dates).stack([1, 2]).drop("UN", axis = 1) series = mobility[mobility.sub_region_1.isna()] plt.plot(series.date, smoothed(series.retail_and_recreation_percent_change_from_baseline), label = "Retail/Recreation") plt.fill_betweenx((-100, 60), pd.to_datetime("March 24, 2020"), pd.to_datetime("June 1, 2020"), color = "black", alpha = 0.05, zorder = -1) plt.text(s = "national lockdown", x = pd.to_datetime("April 27, 2020"), y = -20, fontdict = plt.note_font, ha = "center", va = "top") plt.ylim(-100, 10) plt.xlim(series.date.min(), series.date.max()) plt.legend(loc = 'upper right') lax = plt.gca() plt.sca(lax.twinx()) plt.plot(df["TT"][:, "delta", "confirmed"].index, smoothed(df["TT"][:, "delta", "confirmed"].values), label = "Daily Cases", color = plt.PRED_PURPLE) plt.legend(loc = 'lower right') plt.PlotDevice().ylabel("new cases", rotation = -90, labelpad = 50) plt.sca(lax) plt.PlotDevice().title("\nIndia Mobility and Case Count Trends")\ .annotate("Google Mobility Data + Covid19India.org")\ .xlabel("\ndate")\ .ylabel("% change in mobility\n")
all_tev_200 = pd.read_csv( data / f"all_tev_200_{vax_policy}.csv").set_index("t") # plot static benchmark N_natl = districts_to_run.N_tot.sum() figure = plt.figure() x_pop = list( chain(*zip( all_tev_50.loc[0]["num_vax"].shift(1).fillna(0) * 100 / N_natl, all_tev_50.loc[0]["num_vax"] * 100 / N_natl))) y_tev = list( chain(*zip(all_tev_50.loc[0]["pc_tev_usd"], all_tev_50.loc[0] ["pc_tev_usd"]))) static, = plt.plot(x_pop, y_tev, figure=figure, color="grey", linewidth=2) lines = [static] plt.xticks(fontsize="20") plt.yticks(fontsize="20") plt.PlotDevice().ylabel("TEV (USD)\n").xlabel( "\npercentage of country vaccinated") # plt.ylim(0, 1600) # plt.xlim(left = 0, right = 100) lines.append(plt.plot(0, 0, color="white")[0]) # plot dynamic curve phis = [25, 50, 100, 200] for (phi, all_tev) in zip(
meta_ifrs.male == 1.0)].query('age <= 70').query('age >= 10') cai_bihar_male = all_location_comparison[ (all_location_comparison.location == "Bihar") & (all_location_comparison.male == 1.0)].query('ifr > 0') cai_mumbai_male = all_location_comparison[ (all_location_comparison.location == "Mumbai") & (all_location_comparison.male == 1.0)].sort_values("age_bin_pooled") cai_karnataka_male = all_location_comparison[ (all_location_comparison.location == "Karnataka") & (all_location_comparison.male == 1.0)] cai_tamilnadu_male = all_location_comparison[ (all_location_comparison.location == "tamil_nadu") & (all_location_comparison.male == 1.0)] plt.plot(levin_male.age, (levin_male.ifr), color="gray", linestyle="dotted", label="meta (Levin et al. 2020; slope = 0.123)") plt.plot(od_male.age, (od_male.ifr), color="black", label="meta (O'Driscoll et al. 2020; slope = 0.114) ") plt.plot(cai_bihar_male.age_bin_pooled, (100 * cai_bihar_male.ifr), color="#007CD4", label="Bihar (Cai et al. 2021; slope = 0.047)") plt.plot(cai_mumbai_male.age_bin_pooled, (100 * cai_mumbai_male.ifr), color="#FF0000", label="Mumbai (Cai et al. 2021; slope = 0.100)") plt.plot(cai_karnataka_male.age_bin_pooled, (100 * cai_karnataka_male.ifr), color="#55A423", label="Karnataka (Cai et al. 2021; slope = 0.103)") plt.plot(cai_tamilnadu_male.age_bin_pooled, (100 * cai_tamilnadu_male.ifr), color="#FFB700",
one_day = pd.Timedelta(days=1) # fig 1 infections = ts[ ts.date >= "May 01, 2020"].Hospitalized #.sum(level = 2).sort_index() smoothed = convolution("uniform") scatter = plt.scatter(infections.index[:-7], infections.values[:-7], color="#CC4C75", marker="s", s=5, alpha=0.5) lineplot, = plt.plot(infections.index[:-7], smoothed(infections.values[:-7]), color="#CC4C75", linewidth=2) plt.PlotDevice()\ .l_title("daily confirmed cases in India")\ .r_title("source:\nCOVID19India")\ .axis_labels(x = "date", y = "cases", enforce_spacing = True)\ .adjust(left = 0.10, bottom = 0.15, right = 0.98, top = 0.90) plt.xlim(infections.index[0] - one_day, infections.index[-1] + one_day) plt.legend([scatter, lineplot], ["reported infection counts", "7-day moving average"], handlelength=0.5, framealpha=0, prop={'size': 16}) plt.show() # fig 2
plt.figure() plt.Rt(dates, Rt_pred, RR_CI_lower, RR_CI_upper, CI)\ .ylabel("Estimated $R_t$")\ .xlabel("Date")\ .title(district)\ .size(11, 8)\ .save(figs/f"Rt_est_MP{district}.png", dpi=600, bbox_inches="tight")#\ #.show() plt.close() from matplotlib.dates import DateFormatter formatter = DateFormatter("%b\n%Y") f = notched_smoothing(window=smoothing) plt.plot(ts.loc["Maharashtra"].index, ts.loc["Maharashtra"].Hospitalized, color="black", label="raw case counts from API") plt.plot(ts.loc["Maharashtra"].index, f(ts.loc["Maharashtra"].Hospitalized), color="black", linestyle="dashed", alpha=0.5, label="smoothed, seasonality-adjusted case counts") plt.PlotDevice()\ .l_title("daily case counts in Maharashtra")\ .axis_labels(x = "date", y = "daily cases") plt.gca().xaxis.set_major_formatter(formatter) plt.legend(prop=plt.theme.note, handlelength=1, framealpha=0) plt.show()
.dropna(how = 'all') parse_datetimes(cases.loc[:, "confirmed"]) cases.regency = cases.regency.str.title().map( lambda s: regency_names.get(s, s)) # generation_interval = cases[~cases.symptom_onset.isna() & ~cases.confirmed.isna()]\ # .apply(get_generation_interval, axis = 1)\ # .dropna()\ # .value_counts()\ # .sort_index() # generation_interval = generation_interval[(generation_interval.index >= 0) & (generation_interval.index <= 60)] # generation_interval /= generation_interval.sum() new_cases = cases.confirmed.value_counts().sort_index() new_cases_smoothed = smoothing(new_cases) plt.plot(new_cases, '.', color="blue") plt.plot(new_cases.index, new_cases_smoothed, '-', color="black") plt.show() logger.info("running province-level Rt estimate") (dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, T_pred, T_CI_upper, T_CI_lower, total_cases, new_cases_ts, anomalies, anomaly_dates)\ = analytical_MPVS(new_cases, CI = CI, smoothing = smoothing, totals = False) plt.Rt(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, CI)\ .title("\nSouth Sulawesi: Reproductive Number Estimate")\ .xlabel("\ndate")\ .ylabel("$R_t$\n", rotation=0, labelpad=30)\ .annotate(f"\n{window}-day smoothing window, gamma-prior Bayesian estimation method")\ .show() logger.info("running case-forward prediction")
dayfirst=False) valid.loc[(~monthfirst_idx)] = pd.to_datetime(valid[(~monthfirst_idx)], errors='coerce', format="%d/%m/%Y", dayfirst=True) # assert df.max() <= pd.to_datetime("October 03, 2020"), "date parsing resulted in future dates" df.loc[valid_idx] = valid.apply(pd.Timestamp) sulsel = pd.read_csv("data/3 OCT 2020 Data collection template update South Sulawesi_CASE.csv", usecols = schema.keys())\ .rename(columns = schema)\ .dropna(how = 'all') parse_datetimes(sulsel.loc[:, "confirmed"]) sulsel = sulsel.confirmed.value_counts().sort_index() plt.plot(dkij.index, dkij.values, color="royalblue", label="private") plt.plot(dkij_public.diff(), color="firebrick", label="public") plt.legend() plt.PlotDevice()\ .title("\nJakarta: public vs private case counts")\ .xlabel("date")\ .ylabel("cases") plt.xlim(right=dkij.index.max()) plt.ylim(top=800) plt.show() plt.plot(sulsel, color="royalblue", label="private", linewidth=3) plt.plot(sulsel_public.diff(), color="firebrick", label="public") plt.legend() plt.PlotDevice()\ .title("\nSouth Sulawesi: public vs private case counts")\
smoothed_cases = pd.Series(data=smoother(daily_cases), index=daily_cases.index) # plot raw and cleaned data beg = "December 15, 2020" end = "March 1, 2021" training_cases = smoothed_cases[beg:end] plt.scatter(daily_cases[beg:end].index, daily_cases[beg:end].values, color="black", s=5, alpha=0.5, label="raw case count data") plt.plot(training_cases.index, training_cases.values, color="black", linewidth=2, label="notch-filtered, smoothed case count data") plt.PlotDevice()\ .l_title("case timeseries for Mumbai")\ .axis_labels(x = "date", y = "daily cases")\ .legend()\ .adjust(bottom = 0.15, left = 0.15)\ .format_xaxis()\ .size(9.5, 6)\ .save(figs / "fig_1.svg")\ .show() # estimate Rt from epimargin.estimators import analytical_MPVS
policy_labels=["contact rate", "random", "mortality"]) plt.gca().ticklabel_format(axis="y", useOffset=False) plt.gcf().set_size_inches((16.8, 9.92)) plt.PlotDevice().l_title(f"{state_code}: tev") plt.savefig(dst / f"{state_code}_{district}_tev.png") plt.close("all") for (state, code) in [("Bihar", "BR")]: dst = dst0 / code dst.mkdir(exist_ok=True) # for district in simulation_initial_conditions.query(f"state == '{state}'").index.get_level_values(1).unique(): for district in simulation_initial_conditions.loc[state].index[:16]: cf_consumption = np.load( src / f"c_p0v0{code}_{district}_phi25_novax.npz")['arr_0'] cons_mean = np.mean(cf_consumption, axis=1) plt.plot(cons_mean) plt.PlotDevice().l_title(f"{code} {district}: mean consumption") plt.savefig(dst / f"c_p0v0_{district}.png") plt.close("all") for (phi, pol) in product(phis, ["contact", "random", "mortality"]): p_consumption = np.load( src / f"c_p1v1_{code}_{district}_phi{phi}_{pol}.npz")['arr_0'] cons_mean = np.mean(p_consumption, axis=1) plt.plot(cons_mean) plt.PlotDevice().l_title( f"{code} {district}: mean consumption") plt.savefig(dst / f"c_p1v1{district}_phi{phi}_{pol}.png") plt.close("all")
idx = dT_conf_scaled_TT.index[("March 1, 2020" <= dT_conf_scaled_TT.index) & (dT_conf_scaled_TT.index <= simulation_start)] fig = plt.figure() scatter_TN = plt.scatter(idx, dT_conf_scaled_TN[idx] / N_TN, color=TN_color, label="Tamil Nadu (raw)", figure=fig, alpha=0.5, marker="o", s=10, zorder=5) plot_TN, = plt.plot(idx, dT_conf_scaled_smooth_TN[idx] / N_TN, color=TN_color, label="Tamil Nadu (smoothed)", figure=fig, zorder=5, linewidth=2) scatter_TT = plt.scatter(idx, dT_conf_scaled_TT[idx] / N_TT, color=IN_color, label="India (raw)", figure=fig, alpha=0.5, marker="o", s=10, zorder=10) plot_TT, = plt.plot(idx, dT_conf_scaled_smooth_TT[idx] / N_TT, color=IN_color,
population=500000, I0=100, dT0=20, Rt0=1.01, random_seed=0) total_t = 0 schedule = [(1.01, 75), (1.4, 75), (0.9, 75)] R0_timeseries = [] for (R0, t) in schedule: R0_timeseries += [R0] * t sir_model.Rt0 = R0 sir_model.run(t) total_t += t plt.plot(sir_model.dT) plt.show() plt.plot(R0_timeseries, "-", color="black", label="$R_0$") plt.plot(sir_model.Rt, "-", color="dodgerblue", label="$R_t$") plt.legend(framealpha=1, handlelength=1, loc="best") plt.PlotDevice().xlabel("time").ylabel("reproductive rate").adjust(left=0.10, bottom=0.15, right=0.99, top=0.99) plt.ylim(0.5, 1.5) plt.show() # 1: parametric scheme: dates, Rt, Rt_lb, Rt_ub, *_, anomalies, anomaly_dates = analytical_MPVS( pd.DataFrame(sir_model.dT), smoothing=convolution("uniform", 2),
.xlabel("\nDate")\ .ylabel("Probability\n") plt.subplots_adjust(left=0.12, bottom=0.12, right=0.94, top=0.96) plt.gca().xaxis.set_minor_locator(mpl.ticker.NullLocator()) plt.gca().xaxis.set_minor_formatter(mpl.ticker.NullFormatter()) plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator()) plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) plt.xticks(fontsize="16") plt.yticks(fontsize="16") plt.gca().xaxis.grid(True, which="major") plt.semilogy() plt.ylim(bottom=1e-7) plt.show() PrD = pd.DataFrame(prob_death).set_index( pd.date_range(start=simulation_start, freq="D", periods=len(prob_death))) plt.plot(PrD, color=TN_color, linewidth=2, label="probability of death") plt.xlim(left=pd.Timestamp("Jan 01, 2021"), right=pd.Timestamp("Jan 01, 2022")) plt.PlotDevice().ylabel("log-probability\n") # plt.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.94, top = 0.96) plt.gca().xaxis.set_minor_locator(mpl.ticker.NullLocator()) plt.gca().xaxis.set_minor_formatter(mpl.ticker.NullFormatter()) plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator()) plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b %y')) plt.xticks(fontsize="20", rotation=45) plt.yticks(fontsize="20") plt.gca().xaxis.grid(True, which="major") plt.semilogy() plt.ylim(bottom=1e-7) plt.show()