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)
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()
def plot_district_age_distribution(percentiles, ylabel, fmt, phi=50, vax_policy="random", N_jk=None, n=5, district_spacing=1.5, age_spacing=0.1, rotation=0): fig = plt.figure() district_ordering = list(districts_to_run.index)[:n] for (i, district) in enumerate(district_ordering): ylls = percentiles[district, phi, vax_policy] for j in range(7): plt.errorbar(x=[district_spacing * i + age_spacing * (j - 3)], y=ylls[1, 6 - j] * USD / (N_jk[f"N_{6-j}"][district] if N_jk else 1), yerr=[[(ylls[1, 6 - j] - ylls[0, 6 - j]) * USD / (N_jk[f"N_{6-j}"][district] if N_jk else 1)], [(ylls[2, 6 - j] - ylls[1, 6 - j]) * USD / (N_jk[f"N_{6-j}"][district] if N_jk else 1)]], fmt=fmt, color=age_group_colors[6 - j], figure=fig, label=None if i > 0 else age_bin_labels[6 - j], ms=12, elinewidth=5) plt.xticks([1.5 * _ for _ in range(n)], district_ordering, rotation=rotation, fontsize="20") plt.yticks(fontsize="20") plt.legend(title="age bin", title_fontsize="20", fontsize="20", ncol=7, loc="lower center", bbox_to_anchor=(0.5, 1)) ymin, ymax = plt.ylim() plt.vlines(x=[0.75 + 1.5 * _ for _ in range(n - 1)], ymin=ymin, ymax=ymax, color="gray", alpha=0.5, linewidths=2) plt.ylim(ymin, ymax) plt.gca().grid(False, axis="x") plt.PlotDevice().title(f"\n{vax_policy} demand curves").ylabel( f"{ylabel}\n")
def plot_state_age_distribution(percentiles, ylabel, fmt, district_spacing=1.5, n=5, age_spacing=0.1, rotation=0, ymin=0, ymax=1000): fig = plt.figure() state_ordering = list( sorted(percentiles.keys(), key=lambda k: percentiles[k][0].max(), reverse=True)) for (i, state) in enumerate(state_ordering[:n]): ylls = percentiles[state] for j in range(7): plt.errorbar(x=[district_spacing * i + age_spacing * (j - 3)], y=ylls[0, 6 - j], yerr=[[(ylls[0, 6 - j] - ylls[1, 6 - j])], [(ylls[2, 6 - j] - ylls[0, 6 - j])]], fmt=fmt, color=agebin_colors[6 - j], figure=fig, label=None if i > 0 else agebin_labels[6 - j], ms=12, elinewidth=5) plt.xticks([1.5 * _ for _ in range(n)], state_ordering, rotation=rotation, fontsize="20") plt.yticks(fontsize="20") # plt.legend(title = "age bin", title_fontsize = "20", fontsize = "20", ncol = 7, plt.legend(fontsize="20", ncol=7, loc="lower center", bbox_to_anchor=(0.5, 1)) plt.vlines(x=[0.75 + 1.5 * _ for _ in range(n - 1)], ymin=ymin, ymax=ymax, color="gray", alpha=0.5, linewidths=4) plt.ylim(ymin, ymax) plt.gca().grid(False, axis="x") plt.PlotDevice().ylabel(f"{ylabel}\n")
def plot_component_breakdowns(color, white, colorlabel, whitelabel, semilogy=False, ylabel="WTP (USD)"): fig, ax = plt.subplots() ax.bar(range(7), white * USD, bottom=color * USD, color="white", edgecolor=age_group_colors, linewidth=2, figure=fig) ax.bar(range(7), color * USD, color=age_group_colors, edgecolor=age_group_colors, linewidth=2, figure=fig) ax.bar(range(7), [0], label=whitelabel, color="white", edgecolor="black", linewidth=2) ax.bar(range(7), [0], label=colorlabel, color="black", edgecolor="black", linewidth=2) plt.xticks(range(7), age_bin_labels, fontsize="20") plt.yticks(fontsize="20") plt.legend(ncol=4, fontsize="20", loc="lower center", bbox_to_anchor=(0.5, 1)) plt.PlotDevice().ylabel(f"{ylabel}\n") if semilogy: plt.semilogy()
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()
plt.xlim(left = series.date.iloc[0], right = right) # for state in ["Bihar", "Maharashtra", "Tamil Nadu", "Punjab", "Delhi"][1:]: # plot_mobility(mobility[(mobility.sub_region_1 == state) & (mobility.sub_region_2.isna())], state) # for city in ["Mumbai", "Bangalore Urban", "Hyderabad"]: # plot_mobility(mobility[mobility.sub_region_2 == city], city) # plot_mobility(mobility[mobility.sub_region_1.isna()], "India") plot_mobility( mobility[mobility.sub_region_1.isna()], "India", stringency = stringency) plt.PlotDevice()\ .title("\nIndia: Mobility & Lockdown Trends")\ .annotate("Google Mobility Data (baseline mobility measured from Jan 3 - Feb 6, 2020) + Oxford COVID Policy Tracker") plt.show() # mobility vs cases from pathlib import Path 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:
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( phis, [all_tev_25, all_tev_50, all_tev_100, all_tev_200]): daily_doses = phi * percent * annually * N_natl distributed_doses = 0 x_pop = [] y_tev = [] t_vax = [] ranking = 0
choro = plt.choropleth.vertical(gdf, lambda _: "", mappable=sm).adjust(left=0.01) ax1, ax2, _ = choro.figure.axes for ax in (ax1, ax2): MYS.plot(color="gray", ax=ax) PNG.plot(color="gray", ax=ax) TLS.plot(color="gray", ax=ax) ax.set_xlim(left=94.65, right=144.0) ax.set_ylim(bottom=-11.32) plt.show() max_cmap = plt.get_cmap(vmin=1, vmax=4) fig, ax = plt.subplots() gdf.plot(color=[max_cmap.to_rgba(_) for _ in gdf.Rt_max], ax=ax, legend=True) plt.PlotDevice(fig)\ .adjust(left = 0.1, bottom = 0.11, right = 0.9, top = 0.9)\ .title("\n\nIndonesia: maximum $R_t$ by province for April, 2020", x = 0.1) ax.grid(False) ax.set_xticks([]) ax.set_yticks([]) MYS.plot(color="gray", ax=ax, alpha=0.5) PNG.plot(color="gray", ax=ax, alpha=0.5) TLS.plot(color="gray", ax=ax, alpha=0.5) ax.set_xlim(left=94.65, right=141.379) ax.set_ylim(bottom=-11.32, top=5.93) for (_, row) in gdf.iterrows(): Rtm = round(row["Rt_max"], 2) Rtlabel = str(Rtm) if Rtm < 4 else ">4" ax.annotate(s=f"{Rtlabel}", xy=list(row["pt"].coords)[0], ha = "center", fontfamily = plt.note_font["family"], color="white")\ .set_path_effects([plt.Stroke(linewidth = 3, foreground = "black"), plt.Normal()]) cbar_ax = fig.add_axes([0.95, 0.25, 0.01, 0.5])
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", label="Tamil Nadu (Cai et al. 2021; slope = 0.089)") plt.legend(prop=plt.theme.note, handlelength=1, framealpha=0) plt.PlotDevice().axis_labels( x="age", y="IFR (%; log-scale)").l_title("IFRs by age (male)").adjust(bottom=0.16) plt.semilogy() plt.show() ## levin_female = meta_ifrs[(meta_ifrs.location == "levin") & ( meta_ifrs.male == 0.0)].query('age <= 70').query('age >= 20') od_female = meta_ifrs[(meta_ifrs.location == "od") & ( meta_ifrs.male == 0.0)].query('age <= 70').query('age >= 20') cai_bihar_female = all_location_comparison[ (all_location_comparison.location == "Bihar") & (all_location_comparison.male == 0.0)] cai_mumbai_female = all_location_comparison[ (all_location_comparison.location == "Mumbai") & (all_location_comparison.male == 0.0)].sort_values("age_bin_pooled")
plt.Rt(inf_dates, inf_Rt_pred, inf_Rt_CI_lower, inf_Rt_CI_upper, CI)\ .axis_labels("date", "$R_t$") plt.title("estimated from infections", loc="left", fontdict=plt.theme.label) # fig, axs = plt.subplots(3, 1, sharex = True) # plt.sca(axs[0]) # plt.plot(dth_dates, delhi_dD_smoothed[2:], color = "orange") # plt.title("d$D$/d$t$", loc = "left", fontdict = plt.theme.label) # plt.sca(axs[1]) # plt.plot(dth_dates, np.diff(delhi_dD_smoothed)[1:], color = "red") # plt.title("d$^2D$/d$t^2$", loc = "left", fontdict = plt.theme.label) plt.sca(axs[1]) plt.Rt(dth_dates, dth_Rt_pred, dth_Rt_CI_lower, dth_Rt_CI_upper, CI)\ .axis_labels("date", "$R_t$") plt.title("estimated from deaths", loc="left", fontdict=plt.theme.label) plt.PlotDevice()\ .title(f"$R_t$ estimates: {state}", ha = "center", x = 0.5)\ .adjust(left = 0.08, right = 0.96) plt.show() inf_estimates.to_csv( data / f"india_rt_comparison_inf_{state}_{data_recency}_run{run_date}.csv") dth_estimates.to_csv( data / f"india_rt_comparison_dth_{state}_{data_recency}_run{run_date}.csv")
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")\ .xlabel("date")\ .ylabel("cases") plt.xlim(right=sulsel.index.max()) plt.show()
("no", "new VSLY, old q1"), ("nn", "new VSLY, new q1") ]: VSLY_percentiles = { p: aggregate_dynamic_percentiles(src, f"total_{s}VSLY_{state_code}_{district}_*phi{'_'.join(map(str, p))}.npz") for p in tqdm(params[1:]) } outcomes_per_policy( {k: v * USD/(1e9) for (k, v) in VSLY_percentiles.items()}, "VSLY (USD, billions)", "D", reference = (25, "contact"), phis = [25, 50, 100, 200, 500, 1000], vax_policies = ["contact", "random", "mortality"], policy_colors = [contactrate_vax_color, random_vax_color, mortality_vax_color], policy_labels = ["contact rate", "random", "mortality"] ) plt.PlotDevice().title(f"VSLY Gopalganj: {label}").show() q_bar_sum = {} for (phi, policy) in params[1:]: qbs = np.sum(np.load(src / f"q_bar_BR_Gopalganj_phi{phi}_{policy}.npz")['arr_0'], axis = 0) q_bar_sum[phi, policy] = np.percentile(qbs, [50, 5, 95], axis = 0) @ N_jk outcomes_per_policy(q_bar_sum, reference = (25, "contact"), metric_label = "sum qbar", fmt = "D") q_bar_sum_LE = {} for (phi, policy) in params[1:]: qbs = np.sum(np.load(src / f"q_bar_BR_Gopalganj_phi{phi}_{policy}.npz")['arr_0'], axis = 0) q_bar_sum_LE[phi, policy] = np.percentile(qbs, [50, 5, 95], axis = 0) @ (N_jk * years_life_remaining.loc["Bihar"])
figure=fig, fmt="o", color=clr, label=None if i > 0 else [ "contact rate prioritized", "random assignment", "mortality prioritized" ][dx], ms=12, elinewidth=5) [_.set_alpha(0.5) for _ in bars] plt.xticks(list(range(-1, len(metrics))), [f"$\phi = {phi}$%" for phi in [0, 25, 50, 75, 100, 200, 400]], fontsize="20") plt.yticks(fontsize="20") plt.PlotDevice().ylabel("\ndeaths") plt.legend(fontsize="20", ncol=4, loc="lower center", bbox_to_anchor=(0.5, 1)) plt.show() evaluated_YLL_percentiles = { k: np.percentile(v, [5, 50, 95]) for (k, v) in evaluated_YLLs.items() if "ve70" in k or "novaccination" in k } contact_percentiles = { k: v for (k, v) in evaluated_YLL_percentiles.items() if "contact" in k } random_percentiles = { k: v for (k, v) in evaluated_YLL_percentiles.items() if "random" in k }
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 (dates, Rt, Rt_CI_upper, Rt_CI_lower, *_) = analytical_MPVS(training_cases, smoother, infectious_period=10, totals=False) plt.Rt(dates[1:], Rt[1:], Rt_CI_upper[1:], Rt_CI_lower[1:], 0.95, legend_loc = "upper left")\ .l_title("$R_t$ over time for Mumbai")\
) for p in params } outcomes_per_policy( death_percentiles, "deaths", "o", reference=(25, "novax"), phis=[25, 50, 100, 200], vax_policies=["contact", "random", "mortality"], policy_colors=[ contactrate_vax_color, random_vax_color, mortality_vax_color ], policy_labels=["contact rate", "random", "mortality"]) plt.PlotDevice().l_title(f"{state_code} {district}: deaths") plt.gcf().set_size_inches((16.8, 9.92)) plt.savefig(dst / f"{state_code}_{district}_deaths.png") plt.close("all") # vsly VSLY_percentiles = { p: aggregate_dynamic_percentiles( src, f"total_VSLY_{state_code}_{district}_*phi{'_'.join(map(str, p))}.npz" ) for p in tqdm(params) } outcomes_per_policy( {k: v * USD / (1e9)
p: aggregate_static_percentiles( src, f"deaths_{state_code}_*phi{'_'.join(map(str, p))}.npz") for p in params } outcomes_per_policy( death_percentiles, "deaths", "o", reference=(25, "novax"), phis=[25, 50, 100, 200], vax_policies=["contact", "random", "mortality"], policy_colors=[ contactrate_vax_color, random_vax_color, mortality_vax_color ], policy_labels=["contact rate", "random", "mortality"]) plt.PlotDevice().l_title(f"{state_code}: deaths") plt.gcf().set_size_inches((16.8, 9.92)) plt.savefig(dst / f"{state_code}_deaths.png") plt.close("all") # vsly VSLY_percentiles = { p: aggregate_dynamic_percentiles( src, f"total_VSLY_{state_code}_*phi{'_'.join(map(str, p))}.npz") for p in tqdm(params) } outcomes_per_policy( {k: v * USD / (1e9) for (k, v) in VSLY_percentiles.items()},
.axis_labels("date", "$R_t$")\ .title("Maharashtra: $R_t$ over time", ha = "center", x = 0.5)\ .adjust(left = 0.11, bottom = 0.16) plt.gcf().set_size_inches(3840 / 300, 1986 / 300) plt.savefig("./MH_Rt_timeseries.png") plt.clf() gdf = gpd.read_file("data/maharashtra.json", dpi=600) gdf["Rt"] = gdf.district.map(latest_Rt) fig, ax = plt.subplots() fig.set_size_inches(3840 / 300, 1986 / 300) plt.choropleth(gdf, title = None, mappable = plt.get_cmap(0.75, 2.5), fig = fig, ax = ax)\ .adjust(left = 0) plt.sca(fig.get_axes()[0]) plt.PlotDevice(fig).title(f"{state}: $R_t$ by district", ha="center", x=0.5) plt.axis('off') plt.savefig(f"./{state_code}_Rt_choropleth.png", dpi=300) plt.clf() top10 = [ (k, "> 3.0" if v > 3 else f"{v:.2f}", v) for (k, v) in sorted(latest_Rt.items(), key=lambda t: t[1], reverse=True)[:10] ] fig, ax = plt.subplots(1, 1) ax.axis('tight') ax.axis('off') table = ax.table(cellText=[(k, l) for (k, l, v) in top10], colLabels=["district", "$R_t$"],
figure=fig, fmt="o", color=clr, label=None if i > 0 else [ "contact rate prioritized", "random assignment", "mortality prioritized" ][dx], ms=12, elinewidth=5) [_.set_alpha(0.5) for _ in bars] plt.xticks( range(len(metrics)), [f"{phi}%" for phi in (100 * (10**np.linspace(-1, 1, 11))).round(0)], fontsize="20") plt.yticks(fontsize="20") plt.PlotDevice().ylabel("deaths\n").xlabel( "\npercentage of population vaccinated annually") # plt.ylim(200, 450) plt.legend(fontsize="20") plt.show() # evaluated_YLL_percentiles = {k: np.percentile(v, [5, 50, 95]) for (k, v) in evaluated_YLLs.items() if "ve70" in k or "novaccination" in k} # contact_percentiles = {k: v for (k, v) in evaluated_YLL_percentiles.items() if "contact" in k} # random_percentiles = {k: v for (k, v) in evaluated_YLL_percentiles.items() if "random" in k} # mortality_percentiles = {k: v for (k, v) in evaluated_YLL_percentiles.items() if "mortality" in k} # novax_percentiles = {k: v for (k, v) in evaluated_YLL_percentiles.items() if "novacc" in k} # fig = plt.figure() # plt.errorbar( # x = [-1], # y = novax_percentiles["novaccination"][1], # yerr = [novax_percentiles["novaccination"][1] - [novax_percentiles["novaccination"][0]],[novax_percentiles["novaccination"][2] - novax_percentiles["novaccination"][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 mob2020 = pd.read_csv("data/2020_IN_Region_Mobility_Report.csv", parse_dates=["date"]) mob2021 = pd.read_csv("data/2021_IN_Region_Mobility_Report.csv", parse_dates=["date"])
plt.legend([scatter_TN, plot_TN, scatter_TT, plot_TT], [ "Tamil Nadu (raw)", "Tamil Nadu (smoothed)", "India (raw)", "India (smoothed)" ], fontsize="20", ncol=4, framealpha=1, handlelength=0.75, loc="lower center", bbox_to_anchor=(0.5, 1)) plt.gca().xaxis.set_major_formatter(plt.bY_FMT) plt.gca().xaxis.set_minor_formatter(plt.bY_FMT) plt.xlim(left=pd.Timestamp("March 1, 2020"), right=pd.Timestamp("April 15, 2021")) plt.ylim(bottom=0) plt.PlotDevice().ylabel("per-capita infection rate\n").xlabel("\ndate") plt.show() # 1B: per capita vaccination rates vax = load_vax_data()\ .reindex(pd.date_range(start = pd.Timestamp("Jan 1, 2021"), end = simulation_start, freq = "D"), fill_value = 0)\ [pd.Timestamp("Jan 1, 2021"):simulation_start]\ .drop(labels = [pd.Timestamp("2021-03-15")]) # handle NAN plt.plot(vax.index, vax["Tamil Nadu"] / N_TN, color=TN_color, label="Tamil Nadu", linewidth=2) plt.plot(vax.index, vax["Total"] / N_TT,
rt_data.RR_CI_upper, rt_data.RR_CI_lower, 0.95, yaxis_colors=False, ymin=0.5, ymax=2.0) if (x, y) != (4, 1): plt.gca().get_legend().remove() plt.gca().set_xticks([ pd.Timestamp("February 1, 2021"), pd.Timestamp("March 1, 2021"), pd.Timestamp("April 1, 2021") ]) plt.PlotDevice()\ .l_title(district, fontsize = 12)\ .r_title(f"{urban_share}% urban, {density}/km$^2$", fontsize = 10) if district not in xticks: plt.gca().set_xticklabels([]) if district not in yticks: plt.gca().set_yticklabels([]) plt.subplots_adjust(hspace=0.3, wspace=0.25, left=0.05, bottom=0.05, right=0.95, top=0.95) plt.show()
def generate_report(state_code: str): print(f"Received request for {state_code}.") state = state_code_lookup[state_code] normalized_state = state.replace(" and ", " And ").replace(" & ", " And ") blobs = { f"pipeline/est/{state_code}_state_Rt.csv": f"/tmp/state_Rt_{state_code}.csv", f"pipeline/est/{state_code}_district_Rt.csv": f"/tmp/district_Rt_{state_code}.csv", f"pipeline/commons/maps/{state_code}.json": f"/tmp/state_{state_code}.geojson" } if normalized_state not in dissolved_states else { f"pipeline/est/{state_code}_state_Rt.csv": f"/tmp/state_Rt_{state_code}.csv", } for (blob_name, filename) in blobs.items(): bucket.blob(blob_name).download_to_filename(filename) print(f"Downloaded estimates for {state_code}.") state_Rt = pd.read_csv(f"/tmp/state_Rt_{state_code}.csv", parse_dates=["dates"], index_col=0) plt.close("all") dates = [pd.Timestamp(date).to_pydatetime() for date in state_Rt.dates] plt.Rt(dates, state_Rt.Rt_pred, state_Rt.Rt_CI_lower, state_Rt.Rt_CI_upper, CI)\ .axis_labels("date", "$R_t$")\ .title(f"{state}: $R_t$ over time", ha = "center", x = 0.5)\ .adjust(left = 0.11, bottom = 0.16) plt.gcf().set_size_inches(3840 / 300, 1986 / 300) plt.savefig(f"/tmp/{state_code}_Rt_timeseries.png") plt.close() print(f"Generated timeseries plot for {state_code}.") # check output is at least 50 KB timeseries_size_kb = os.stat( f"/tmp/{state_code}_Rt_timeseries.png").st_size / 1000 print(f"Timeseries artifact size: {timeseries_size_kb} kb") assert timeseries_size_kb > 50 bucket.blob( f"pipeline/rpt/{state_code}_Rt_timeseries.png").upload_from_filename( f"/tmp/{state_code}_Rt_timeseries.png", content_type="image/png") if normalized_state not in (island_states + dissolved_states): district_Rt = pd.read_csv(f"/tmp/district_Rt_{state_code}.csv", parse_dates=["dates"], index_col=0) latest_Rt = district_Rt[district_Rt.dates == district_Rt.dates.max( )].set_index("district")["Rt_pred"].to_dict() top10 = [(k, "> 3.0" if v > 3 else f"{v:.2f}") for (k, v) in sorted( latest_Rt.items(), key=lambda t: t[1], reverse=True)[:10]] gdf = gpd.read_file(f"/tmp/state_{state_code}.geojson") gdf["Rt"] = gdf.district.map(latest_Rt) fig, ax = plt.subplots() fig.set_size_inches(3840 / 300, 1986 / 300) plt.choropleth(gdf, title = None, mappable = plt.get_cmap(0.75, 2.5), fig = fig, ax = ax)\ .adjust(left = 0) plt.sca(fig.get_axes()[0]) plt.PlotDevice(fig).title(f"{state}: $R_t$ by district", ha="center", x=0.5) plt.axis('off') plt.savefig(f"/tmp/{state_code}_Rt_choropleth.png", dpi=300) plt.close() print(f"Generated choropleth for {state_code}.") # check output is at least 100 KB choropleth_size_kb = os.stat( f"/tmp/{state_code}_Rt_choropleth.png").st_size / 1000 print(f"Choropleth artifact size: {choropleth_size_kb} kb") assert choropleth_size_kb > 100 bucket.blob(f"pipeline/rpt/{state_code}_Rt_choropleth.png" ).upload_from_filename( f"/tmp/{state_code}_Rt_choropleth.png", content_type="image/png") else: print(f"Skipped choropleth for {state_code}.") if normalized_state not in dissolved_states: fig, ax = plt.subplots(1, 1) ax.axis('tight') ax.axis('off') table = ax.table(cellText=top10, colLabels=["district", "$R_t$"], loc='center', cellLoc="center") table.scale(1, 2) for (row, col), cell in table.get_celld().items(): if (row == 0): cell.set_text_props(fontfamily=plt.theme.label["family"], fontsize=plt.theme.label["size"], fontweight="semibold") else: cell.set_text_props(fontfamily=plt.theme.label["family"], fontsize=plt.theme.label["size"], fontweight="light") plt.PlotDevice().title(f"{state}: top districts by $R_t$", ha="center", x=0.5) plt.savefig(f"/tmp/{state_code}_Rt_top10.png", dpi=600) plt.close() print(f"Generated top 10 district listing for {state_code}.") # check output is at least 50 KB top10_size_kb = os.stat( f"/tmp/{state_code}_Rt_top10.png").st_size / 1000 print(f"Top 10 listing artifact size: {top10_size_kb} kb") assert top10_size_kb > 50 bucket.blob( f"pipeline/rpt/{state_code}_Rt_top10.png").upload_from_filename( f"/tmp/{state_code}_Rt_top10.png", content_type="image/png") else: print(f"Skipped top 10 district listing for {state_code}.") # sleep for 15 seconds to ensure the images finish saving time.sleep(15) print(f"Uploaded artifacts for {state_code}.") return "OK!"
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), CI=0.99, totals=False) pd = plt.Rt(dates, Rt, Rt_ub, Rt_lb, ymin = 0.5, ymax = 2.5, CI = 0.99, yaxis_colors = False, format_dates = False, critical_threshold = False)\ .xlabel("time")\ .ylabel("reproductive rate")\ .adjust(left = 0.11, bottom = 0.15, right = 0.98, top = 0.98) plt.plot(sir_model.Rt, "-", color="white", linewidth=3, zorder=10)
def outcomes_per_policy(percentiles, metric_label, fmt, phis=[25, 50, 100, 200], reference=(25, "no_vax"), reference_color=no_vax_color, vax_policies=["contact", "random", "mortality"], policy_colors=[ contactrate_vax_color, random_vax_color, mortality_vax_color ], policy_labels=[ "contact rate priority", "random assignment", "mortality priority" ], spacing=0.2): fig = plt.figure() md, lo, hi = percentiles[reference] *_, bars = plt.errorbar(x=[0], y=[md], yerr=[[md - lo], [hi - md]], figure=fig, fmt=fmt, color=reference_color, label="no vaccination", ms=12, elinewidth=5) [_.set_alpha(0.5) for _ in bars] plt.hlines(md, xmin=-1, xmax=5, linestyles="dotted", colors=reference_color) for (i, phi) in enumerate(phis, start=1): for (j, (vax_policy, color, label)) in enumerate( zip(vax_policies, policy_colors, policy_labels)): md, lo, hi = death_percentiles[phi, vax_policy] *_, bars = plt.errorbar(x=[i + spacing * (j - 1)], y=[md], yerr=[[md - lo], [hi - md]], figure=fig, fmt=fmt, color=color, label=label if i == 0 else None, ms=12, elinewidth=5) [_.set_alpha(0.5) for _ in bars] plt.legend(ncol=4, fontsize="20", loc="lower center", bbox_to_anchor=(0.5, 1)) plt.xticks(range(len(phis) + 1), [f"$\phi = {phi}$%" for phi in ([0] + phis)], fontsize="20") plt.yticks(fontsize="20") plt.PlotDevice().ylabel(f"{metric_label}\n") plt.gca().grid(False, axis="x") ymin, ymax = plt.ylim() plt.vlines(x=[0.5 + _ for _ in range(len(phis))], ymin=ymin, ymax=ymax, color="gray", alpha=0.5, linewidths=2) plt.ylim(ymin, ymax) plt.xlim(-0.5, len(phis) + 1.5)
sns.set_palette(age_group_colors) dt = [simulation_start + pd.Timedelta(n, "days") for n in range(max_t - 1)] PrD = pd.DataFrame(prob_deathx).T\ .rename(columns = dict(enumerate(IN_age_structure.keys())))\ .assign(t = dt)\ .set_index("t") PrD.plot() plt.legend(title="Age category", title_fontsize=18, fontsize=16, framealpha=1, handlelength=1) plt.xlim(right=pd.Timestamp("Jan 01, 2022")) plt.PlotDevice()\ .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)))