示例#1
0
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)
示例#2
0
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()
示例#3
0
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")
示例#4
0
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")
示例#5
0
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)
示例#6
0
plt.yticks(fontsize="20")
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,
示例#7
0
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")
plt.show()

plt.plot(series.date, smoothed(series.retail_and_recreation_percent_change_from_baseline), label = "Retail/Recreation")
示例#8
0
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)
sim_rt, = plt.plot(sir_model.Rt,
                   "-",
示例#9
0
                         label=f"dynamic, {vax_policy}, $phi = ${phi}%",
                         figure=figure)[0]
            ]
        plt.legend(
            lines,
            # ["static, t = 0, $\phi = $50%", ""]  + [f"dynamic, {vax_policy}, $\phi = ${phi}%" for phi in phis],
            ["static, t = 0, $phi = $50%", ""] +
            [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("TEV (USD)\n").xlabel(
            "\npercentage of country vaccinated")
        plt.ylim(0, 1600)
        plt.xlim(left=0, right=100)
        plt.show()

    # 3C: YLL per million choropleth
    if "3C" in figs_to_run or run_all:
        india = gpd.read_file(data/"india.geojson")\
            .drop(columns = ["id", "dt_code", "st_code", "year"])\
            .rename(columns = {"st_nm": "state"})\
            .set_index(["state", "district"])\
            .rename(index = lambda s: s.replace(" and ", " And "))\
            .assign(
                dissolve_state    = lambda _:_.index.get_level_values(0),
                dissolve_district = lambda _:np.where(
                    _.index.isin(coalesce_states, level = 0),
                    _.index.get_level_values(0),
示例#10
0
plt.vlines(x=pd.Timestamp("March 1, 2021"),
           ymin=-60,
           ymax=10,
           linewidths=2,
           color="grey",
           linestyles="dotted")
plt.text(x=pd.Timestamp("March 2, 2021"),
         y=-40,
         s=" $2^{nd}$\n wave\n starts",
         ha="left",
         va="bottom",
         color="grey",
         font_properties=FontProperties(family=plt.theme.note["family"],
                                        size=14))
plt.xlim(MH_mob.index[0] - one_day, MH_mob.index[-1] + one_day)
plt.ylim(-60, 10)
plt.legend([IN_marker, MH_marker], ["all India", "Maharashtra"],
           handlelength=0.5,
           framealpha=0,
           prop={'size': 16},
           loc="upper center",
           ncol=2)
plt.show()

# fig 5: variants
mutations = pd.read_json(data/"outbreakinfo_mutation_report_data_2021-04-18.json")\
    .set_index("date_time")   \
    .loc["October 1, 2020":]  \
    .drop(columns = "source") \
    * 100
示例#11
0
estimates = pd.DataFrame(estimates)
estimates.columns = ["regency", "Rt", "Rt_CI_lower", "Rt_CI_upper", "Rt_proj"]
estimates.set_index("regency", inplace=True)
estimates.to_csv("data/SULSEL_Rt_projections.csv")
print(estimates)

gdf = gpd.read_file("data/gadm36_IDN_shp/gadm36_IDN_2.shp")\
    .query("NAME_1 == 'Sulawesi Selatan'")\
    .merge(estimates, left_on = "NAME_2", right_on = "regency")

choro = plt.choropleth(gdf, mappable=plt.get_cmap(0.4, 1.4, "viridis"))

for ax in choro.figure.axes[:-1]:
    plt.sca(ax)
    plt.xlim(left=119, right=122)
    plt.ylim(bottom=-7.56, top=-1.86)

plt.show()

logger.info("adaptive control")
(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)
Rt = pd.DataFrame(data={"Rt": Rt_pred[1:]}, index=dates)
Rt_current = Rt_pred[-1]
Rt_m = np.mean(Rt[(Rt.index >= "April 21, 2020")
                  & (Rt.index <= "May 22, 2020")])[0]
Rt_v = np.mean(Rt[(Rt.index <= "April 14, 2020")])[0]

Rt_m_scaled = Rt_current + 0.75 * (Rt_m - Rt_current)
Rt_v_scaled = Rt_current + 0.75 * (Rt_v - Rt_current)
示例#12
0
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()

# correlation: dkij
dkij_diff = dkij_public.diff().dropna()
dkij_pub_clipped = dkij_diff[dkij_diff.index <= dkij.index.max()].iloc[1:]
(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(age_ts.sum(level = 1), CI = CI, smoothing = smoothing, totals = False)

MAK = SIR(name="MAK",
          population=1.339e6,
          dT0=T_pred[-1],
          Rt0=Rt_pred[-1],
          upper_CI=T_CI_upper[-1],
          lower_CI=T_CI_lower[-1],
          mobility=0,
          random_seed=0,
          I0=age_ts.sum(level=1).sum()).run(30)

plt.daily_cases(dates, T_pred, T_CI_upper, T_CI_lower, new_cases_ts, anomaly_dates, anomalies, CI,
    prediction_ts = [
        (MAK.dT[:-1], MAK.lower_CI[1:], MAK.upper_CI[1:], plt.PRED_PURPLE, "current social distancing"),
        (*rt1_10x, "orange",         "10% increase in school-age $R_t$"),
        (*rt1_25x, "mediumseagreen", "25% increase in school-age $R_t$"),
        (*rt1_50x, "hotpink",        "50% increase in school-age $R_t$"),
    ])\
    .xlabel("\ndate")\
    .ylabel("cases\n")
# .title("\nMakassar Daily Cases - school reopening scenarios")\
# .annotate("\nBayesian training process on empirical data, with anomalies identified")
(_, r) = plt.xlim()
plt.xlim(left=pd.Timestamp("Sep 1, 2020"), right=r)
plt.ylim(bottom=10, top=1000)
plt.vlines(dates[-1], ymin=1, ymax=1000, color="black", linestyles="solid")
plt.semilogy()
plt.show()
示例#14
0
           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)))
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")