jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 5))
plt.subplots_adjust(wspace=0.25, hspace=0.55)

for case_idx in range(5):
    random_scheduler_results = np.zeros(shape=(5000))
    hybrid_scheduler_results = np.zeros(shape=(5000))
    our_scheduler_results = np.zeros(shape=(5000))
    for repetition in range(3):
        with open('data/random_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            random_scheduler_results += np.load(f) / 3

        with open('data/hybrid_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            hybrid_scheduler_results += np.load(f) / 3

        with open('data/our_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            our_scheduler_results += np.load(f) / 3

    assert(len(random_scheduler_results) == len(hybrid_scheduler_results))
    assert(len(random_scheduler_results) == len(our_scheduler_results))

    data=[]
    for i in range(5000):
        data.append([i, random_scheduler_results[i], 'Random'])
        data.append([i, hybrid_scheduler_results[i], 'Hybrid'])
        data.append([i, our_scheduler_results[i], 'Ours'])

    df=pd.DataFrame(data, columns=['trial', 'cost', 'scheduler'])
    ax=s.tsplot(ax=axes[case_idx // 3, case_idx % 3], condition='scheduler', time='trial', value='cost',
                      unit='unit', data=df, color=['tab:blue', 'tab:orange', 'tab:green'])
    ax.lines[2].set_linestyle("--")

    ax.set_xlabel(None)
    ax.set_ylabel(None)
    if case_idx == 0:
        ax.set(ylim=(0, 20))
        ax.set_yticks([0, 5, 10, 15, 20])
        ax.set_yticklabels([0, 5, 10, 15, 20], fontsize=15)
    elif case_idx == 1:
        ax.set(ylim=(0, 40))
        ax.set_yticks([0, 10, 20, 30, 40])
        ax.set_yticklabels([0, 10, 20, 30, 40], fontsize=15)
    elif case_idx == 2:
        ax.set(ylim=(0, 40))
        ax.set_yticks([0, 10, 20, 30, 40])
        ax.set_yticklabels([00, 10, 20, 30, 40], fontsize=15)
    elif case_idx == 3:
        ax.set(ylim=(0, 60))
        ax.set_yticks([0, 20, 40, 60])
        ax.set_yticklabels([0, 20, 40, 60], fontsize=15)
    elif case_idx == 4:
        ax.set(ylim=(0, 200))
        ax.set_yticks([0, 50, 100, 150, 200])
        ax.set_yticklabels([0, 50, 100, 150, 200], fontsize=15)

    ax.set_xticks([0, 2500, 5000])
    ax.set_xticklabels([0, 2500, 5000], fontsize=15)

    if case_idx == 4:
        ax.get_legend().set_title(None)
        handles, labels=ax.get_legend_handles_labels()
        handles[2].set_linestyle('--')
        handles=[handles[2], handles[1], handles[0]]
        labels=[labels[2], labels[1], labels[0]]
        ax.legend(handles, labels, ncol=1, handletextpad=0.3,
                  loc='upper left', bbox_to_anchor=(1.2, 1), fontsize=15)
    else:
        ax.get_legend().remove()
//  [python]
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 5))
plt.subplots_adjust(wspace=0.25, hspace=0.55)

for case_idx in range(5):
    random_scheduler_results = np.zeros(shape=(5000))
    hybrid_scheduler_results = np.zeros(shape=(5000))
    our_scheduler_results = np.zeros(shape=(5000))
    for repetition in range(3):
        with open('data/random_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            random_scheduler_results += np.load(f) / 3

        with open('data/hybrid_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            hybrid_scheduler_results += np.load(f) / 3

        with open('data/our_scheduler_' + str(case_idx) + '_' + str(repetition) + '.npy', 'rb') as f:
            our_scheduler_results += np.load(f) / 3

    assert(len(random_scheduler_results) == len(hybrid_scheduler_results))
    assert(len(random_scheduler_results) == len(our_scheduler_results))

    data=[]
    for i in range(5000):
        data.append([i, random_scheduler_results[i], 'Random'])
        data.append([i, hybrid_scheduler_results[i], 'Hybrid'])
        data.append([i, our_scheduler_results[i], 'Ours'])

    df=pd.DataFrame(data, columns=['trial', 'cost', 'scheduler'])
    ax=sns.lineplot(ax=axes[case_idx // 3, case_idx % 3], hue_order=['Ours', 'Hybrid', 'Random'], linewidth=2,
                      palette=['tab:green', 'tab:orange', 'tab:blue'],
                      data=df, x="trial", y="cost", hue='scheduler')
    ax.lines[2].set_linestyle("--")

    ax.set_xlabel(None)
    ax.set_ylabel(None)
    if case_idx == 0:
        ax.set(ylim=(0, 20))
        ax.set_yticks([0, 5, 10, 15, 20])
        ax.set_yticklabels([0, 5, 10, 15, 20], fontsize=15)
    elif case_idx == 1:
        ax.set(ylim=(0, 40))
        ax.set_yticks([0, 10, 20, 30, 40])
        ax.set_yticklabels([0, 10, 20, 30, 40], fontsize=15)
    elif case_idx == 2:
        ax.set(ylim=(0, 40))
        ax.set_yticks([0, 10, 20, 30, 40])
        ax.set_yticklabels([00, 10, 20, 30, 40], fontsize=15)
    elif case_idx == 3:
        ax.set(ylim=(0, 60))
        ax.set_yticks([0, 20, 40, 60])
        ax.set_yticklabels([0, 20, 40, 60], fontsize=15)
    elif case_idx == 4:
        ax.set(ylim=(0, 200))
        ax.set_yticks([0, 50, 100, 150, 200])
        ax.set_yticklabels([0, 50, 100, 150, 200], fontsize=15)

    ax.set_xticks([0, 2500, 5000])
    ax.set_xticklabels([0, 2500, 5000], fontsize=15)

    if case_idx == 4:
        ax.get_legend().set_title(None)
        handles, labels=ax.get_legend_handles_labels()
        handles[2].set_linestyle('--')
        handles=[handles[2], handles[1], handles[0]]
        labels=[labels[2], labels[1], labels[0]]
        ax.legend(handles, labels, ncol=1, handletextpad=0.3,
                  loc='upper left', bbox_to_anchor=(1.2, 1), fontsize=15)
    else:
        ax.get_legend().remove()
//  [python]
def plot_line_plaid_buffer_count(
    sample: pd.DataFrame,
    title: Optional[str] = None,
    filename: Optional[Union[str, os.PathLike]] = None,
    margins: Optional[dict] = None,
    hue: Optional[str] = None,
    *,
    x_column: str = "plaid_buffers",
    x_label: str = "plaid buffer count",
    y_column: str = "rate",
    y_label: str = "download speed (GiB / sec)",
    save: bool = True,
):
    set_sns_style()
    sample = sample[sample[x_column] >= 1]
    ax = sns.pointplot(
        sample,
        x=x_column,
        y=y_column,
        hue=hue,
    )

    max_x_tick_position = sample[x_column].max()
    x_tick_positions = []
    i = 1
    while i <= max_x_tick_position:
        x_tick_positions.append(i)
        i <<= 1
    ax.set_xticks(x_tick_positions)

    ax.set(xlabel=x_label, ylabel=y_label)
    fig = ax.get_figure()
    if title:
        fig.suptitle(title)

    if save:
        if not filename:
            raise ValueError()
        save_figure(fig, filename, margins)
    else:
        return ax
//  [python]
def plot_line_plaid_buffer_count(
    sample: pd.DataFrame,
    title: Optional[str] = None,
    filename: Optional[Union[str, os.PathLike]] = None,
    margins: Optional[dict] = None,
    hue: Optional[str] = None,
    *,
    x_column: str = "plaid_buffers",
    x_label: str = "plaid buffer count",
    y_column: str = "rate",
    y_label: str = "download speed (GiB / sec)",
    save: bool = True,
):
    set_sns_style()
    sample = sample[sample[x_column] >= 1]
    ax = sns.lineplot(
        sample,
        x=x_column,
        y=y_column,
        hue=hue,
    )

    max_x_tick_position = sample[x_column].max()
    x_tick_positions = []
    i = 1
    while i <= max_x_tick_position:
        x_tick_positions.append(i)
        i <<= 1
    ax.set_xticks(x_tick_positions)

    ax.set(xlabel=x_label, ylabel=y_label)
    fig = ax.get_figure()
    if title:
        fig.suptitle(title)

    if save:
        if not filename:
            raise ValueError()
        save_figure(fig, filename, margins)
    else:
        return ax
//  [python]
def solution_plot(self):
        self._view.solution()
        plt.figure(figsize=(12,6))
        sns.tsplot(data=df)
        plt.title("Monthly Visitors to Los Angeles City Museums")
//  [python]
def solution_plot(self):
        self._view.solution()
        plt.figure(figsize=(12,6))
        sns.lineplot(data=df)
        plt.title("Monthly Visitors to Los Angeles City Museums")
//  [python]
num_rows_vitals = len(vitals) // num_cols + int(len(vitals) % num_cols > 0)
num_rows_clinical = len(clinical_measures) // num_cols + int(len(clinical_measures) % num_cols > 0)
num_rows_ours = len(our_measures) // num_cols + int(len(our_measures) % num_cols > 0)
fig, axs = plt.subplots(num_rows_vitals + num_rows_clinical + num_rows_ours, num_cols, figsize=figsize, dpi=300, sharex=True)
for i, item in enumerate(vitals):
    ax = axs[i // num_cols, i % num_cols]
    s.lineplot(x="step", y=item, data=monitor_pos, legend=False, color="green", ci="sd", linewidth=1, ax=ax)
    s.lineplot(x="step", y=item, data=monitor_neg, legend=False, color="blue", ci="sd", linewidth=1, ax=ax)
    # ax.lines[1].set_linestyle(':')
    tt = item[2:] if item[:2] == "o:" else item
    ax.set_title(tt, fontsize=7, pad=3)
    ax.set_xticks(np.arange(-window_pre, window_post+1))
    plt.setp(ax.get_xticklabels(), rotation=42, ha="right", rotation_mode="anchor")
    ax.set_ylabel("")
//  [python]
num_rows_vitals = len(vitals) // num_cols + int(len(vitals) % num_cols > 0)
num_rows_clinical = len(clinical_measures) // num_cols + int(len(clinical_measures) % num_cols > 0)
num_rows_ours = len(our_measures) // num_cols + int(len(our_measures) % num_cols > 0)
fig, axs = plt.subplots(num_rows_vitals + num_rows_clinical + num_rows_ours, num_cols, figsize=figsize, dpi=300, sharex=True)
for i, item in enumerate(vitals):
    ax = axs[i // num_cols, i % num_cols]
    seaborn.lineplot(x="step", y=item, data=monitor_pos, legend=False, color="green", ci="sd", linewidth=1, ax=ax)
    seaborn.lineplot(x="step", y=item, data=monitor_neg, legend=False, color="blue", ci="sd", linewidth=1, ax=ax)
    # ax.lines[1].set_linestyle(':')
    tt = item[2:] if item[:2] == "o:" else item
    ax.set_title(tt, fontsize=7, pad=3)
    ax.set_xticks(np.arange(-window_pre, window_post+1))
    plt.setp(ax.get_xticklabels(), rotation=42, ha="right", rotation_mode="anchor")
    ax.set_ylabel("")
//  [python]
def solution_plot(self):
        self._view.solution()
        plt.figure(figsize=(12,6))
        plt.title("Monthly Visitors to Avila Adobe")
        plt.plot(df['Avila Adobe'])
        plt.xlabel("Date")
//  [python]
def solution_plot(self):
        self._view.solution()
        plt.figure(figsize=(12,6))
        plt.title("Monthly Visitors to Avila Adobe")
        sns.lineplot(data=df['Avila Adobe'])
        plt.xlabel("Date")
//  [python]
peng_df = sns.load_dataset("penguins")

#If you are unable to load the data due to SSL certificate error
#you can either fix it following this:
#https://stackoverflow.com/questions/57483667/ssl-certificate-verify-failed-error-when-loading-data-into-seaborn
#or you can download the data as a csv file from here
#https://github.com/mwaskom/seaborn-data

#Check the dataset
peng_df.info()

#Scatterplot
sns.scatterplot(x="flipper_length_mm", y="body_mass_g", 
                data=peng_df, hue="species")
plt.show()

# #Lineplot
sns.pointplot(x="flipper_length_mm", y="body_mass_g", 
             data=peng_df, hue="species")
//  [python]
peng_df = sns.load_dataset("penguins")

#If you are unable to load the data due to SSL certificate error
#you can either fix it following this:
#https://stackoverflow.com/questions/57483667/ssl-certificate-verify-failed-error-when-loading-data-into-seaborn
#or you can download the data as a csv file from here
#https://github.com/mwaskom/seaborn-data

#Check the dataset
peng_df.info()

#Scatterplot
sns.scatterplot(x="flipper_length_mm", y="body_mass_g", 
                data=peng_df, hue="species")
plt.show()

# #Lineplot
sns.lineplot(x="flipper_length_mm", y="body_mass_g", 
             data=peng_df, hue="species")
//  [python]
def compare_curve(listdir, window):
    df = pd.DataFrame([])
    for subfolder in listdir:
        df_sub = pd.read_csv(subfolder+'/test_result.txt', sep=',', skipinitialspace=True)
        df_sub['reward_mean'] = df_sub['reward'].rolling(window).mean()
        df_sub['collision_mean'] = df_sub['collision'].rolling(window).mean()
        df_sub['reward_std'] = df_sub['reward'].rolling(window).std()
        df_sub['collision_std'] = df_sub['collision'].rolling(window).std()
        name = subfolder.split('-')[1]
        if name == 'event': name = 'ours'
        df_sub['method'] = name
        df = df.append(df_sub)

    sns.set_style("darkgrid")

    # fig 1
    reward_plot = sns.tsplot(
        data=df,
        time="epoch", value="reward_mean", unit="method",
        err_style=None, color="method", palette="flare"
    )
    reward_plot.set(xlabel='Epoch', ylabel='Reward')
    reward_plot.legend_.set_title(None)

    figname = args.foldername + 'reward' + args.figtype
    fig = reward_plot.get_figure()
    fig.set_size_inches(4, 3)
    fig.savefig(figname, dpi=300, bbox_inches='tight', pad_inches=0.1)
    fig.clear()

    # fig 2
    df['collision_mean'] *= 100
    col_plot = sns.tsplot(
        data=df,
        time="epoch", value="collision_mean", unit="method",
        err_style=None, color="method", palette="flare"
    )
    col_plot.set(xlabel='Epoch', ylabel='Collision (%)')
    col_plot.set(ylim=(0.0, 55.0), xlabel='Epoch', ylabel='Collision (%)')
    col_plot.legend_.set_title(None)

    figname = args.foldername + 'collision' + args.figtype
    fig = col_plot.get_figure()
    fig.set_size_inches(4, 3)
    fig.savefig(figname, dpi=300, bbox_inches='tight', pad_inches=0.1)
    fig.clear()
//  [python]
def compare_curve(listdir, window):
    df = pd.DataFrame([])
    for subfolder in listdir:
        df_sub = pd.read_csv(subfolder+'/test_result.txt', sep=',', skipinitialspace=True)
        df_sub['reward_mean'] = df_sub['reward'].rolling(window).mean()
        df_sub['collision_mean'] = df_sub['collision'].rolling(window).mean()
        df_sub['reward_std'] = df_sub['reward'].rolling(window).std()
        df_sub['collision_std'] = df_sub['collision'].rolling(window).std()
        name = subfolder.split('-')[1]
        if name == 'event': name = 'ours'
        df_sub['method'] = name
        df = df.append(df_sub)

    sns.set_style("darkgrid")

    # fig 1
    reward_plot = sns.lineplot(
        data=df,
        x="epoch", y="reward_mean", hue="method",
        markers=False, dashes=False, palette="flare"
    )
    reward_plot.set(xlabel='Epoch', ylabel='Reward')
    reward_plot.legend_.set_title(None)

    figname = args.foldername + 'reward' + args.figtype
    fig = reward_plot.get_figure()
    fig.set_size_inches(4, 3)
    fig.savefig(figname, dpi=300, bbox_inches='tight', pad_inches=0.1)
    fig.clear()

    # fig 2
    df['collision_mean'] *= 100
    col_plot = sns.lineplot(
        data=df,
        x="epoch", y="collision_mean", hue="method",
        markers=False, dashes=False, palette="flare"
    )
    col_plot.set(xlabel='Epoch', ylabel='Collision (%)')
    col_plot.set(ylim=(0.0, 55.0), xlabel='Epoch', ylabel='Collision (%)')
    col_plot.legend_.set_title(None)

    figname = args.foldername + 'collision' + args.figtype
    fig = col_plot.get_figure()
    fig.set_size_inches(4, 3)
    fig.savefig(figname, dpi=300, bbox_inches='tight', pad_inches=0.1)
    fig.clear()
//  [python]
def plot_non_dp_ebm(filepath="./paper_plots/", dataset="Credit 1"):
    df = pd.read_csv("./paper_results/E4_non_dp_ebm.csv")
    df = process_df_for_plotting(df)

    # Needed for ebm rework dataset
    df["ebm"] = True
    df["ebm"][df["feature_interaction_method"] == "standard"] = False
    df["ebm"] = df["ebm"].astype("str")

    print("Options:", set(df["dataset"].values), set(df["epsilon"].values), set(df["max_depth"].values))

    depth = '4'
    df = df[df["dataset"] == dataset]
    df = df[df["max_depth"] == depth]

    cm = sns.color_palette("Purples_r", 2) +  sns.color_palette("Greens_r", 2)
    cm = None

    df["args"] = df["split_method"] + df["weight_update"] + df["ebm"]
    df["args"] = df["args"].str.replace(" ", "")
    arg_map = {"totally_randomgbmFalse" : "Gradient",
               "totally_randomgbmTrue" : "Gradient EBM",
               "totally_randomxgboostFalse": "Newton",
               "totally_randomxgboostTrue": "Newton EBM"}

    df = df.replace({"args":arg_map})
    df = df.sort_values("args")

    with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
        print(df.groupby(["dataset", "args", "num_trees", "max_depth"]).mean()["test_auc"])

    ax = sns.pointplot(data=df, x="num_trees", y="test_auc", hue="args", ci="sd", palette=cm)
    cm = None
    handles, labels = ax.get_legend_handles_labels()
    ax.legend(handles=handles[0:], labels=labels[0:], loc="lower right")
    # plt.title(dataset + " depth " + depth)
    plt.xlabel("Number of trees (T)")
    plt.ylabel("Test AUC")
    #plt.show()
    plt.tight_layout()
    plt.savefig(filepath+ "non_dp_ebm_vary_T_" + dataset+".pdf")
    plt.clf()
//  [python]
def plot_non_dp_ebm(filepath="./paper_plots/", dataset="Credit 1"):
    df = pd.read_csv("./paper_results/E4_non_dp_ebm.csv")
    df = process_df_for_plotting(df)

    # Needed for ebm rework dataset
    df["ebm"] = True
    df["ebm"][df["feature_interaction_method"] == "standard"] = False
    df["ebm"] = df["ebm"].astype("str")

    print("Options:", set(df["dataset"].values), set(df["epsilon"].values), set(df["max_depth"].values))

    depth = '4'
    df = df[df["dataset"] == dataset]
    df = df[df["max_depth"] == depth]

    cm = sns.color_palette("Purples_r", 2) +  sns.color_palette("Greens_r", 2)
    cm = None

    df["args"] = df["split_method"] + df["weight_update"] + df["ebm"]
    df["args"] = df["args"].str.replace(" ", "")
    arg_map = {"totally_randomgbmFalse" : "Gradient",
               "totally_randomgbmTrue" : "Gradient EBM",
               "totally_randomxgboostFalse": "Newton",
               "totally_randomxgboostTrue": "Newton EBM"}

    df = df.replace({"args":arg_map})
    df = df.sort_values("args")

    with pd.option_context('display.max_rows', None, 'display.max_columns', None):  # more options can be specified also
        print(df.groupby(["dataset", "args", "num_trees", "max_depth"]).mean()["test_auc"])

    ax = sns.lineplot(data=df, x="num_trees", y="test_auc", hue="args", ci="sd", palette=cm)
    cm = None
    handles, labels = ax.get_legend_handles_labels()
    ax.legend(handles=handles[0:], labels=labels[0:], loc="lower right")
    # plt.title(dataset + " depth " + depth)
    plt.xlabel("Number of trees (T)")
    plt.ylabel("Test AUC")
    #plt.show()
    plt.tight_layout()
    plt.savefig(filepath+ "non_dp_ebm_vary_T_" + dataset+".pdf")
    plt.clf()
//  [python]
def plot_errors(df, foldername):
    
    df["cls"] *= 100.0
    clsplot = sns.tsplot(data=df, time="Epoch", value="cls", unit="Corruption", color="Corruption", palette="husl")
    clsplot.set(ylim=(0.0, 80.0))
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    figname = os.path.join(foldername, 'cls.png')
    plt.savefig(figname, bbox_inches='tight', pad_inches=0)
    print('Save figure to {}'.format(figname))

    plt.clf()

    df["ssl"] *= 100.0
    sslplot = sns.tsplot(data=df, time="Epoch", value="ssl", unit="Corruption", color="Corruption", palette="husl")
    sslplot.set(ylim=(0.0, 80.0))
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    figname = os.path.join(foldername, 'ssl.png')
    plt.savefig(figname, bbox_inches='tight', pad_inches=0)
    print('Save figure to {}'.format(figname))
//  [python]
def plot_errors(df, foldername):
    
    df["cls"] *= 100.0
    clsplot = sns.lineplot(data=df, x="Epoch", y="cls", hue="Corruption", palette="husl")
    clsplot.set(ylim=(0.0, 80.0))
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    figname = os.path.join(foldername, 'cls.png')
    plt.savefig(figname, bbox_inches='tight', pad_inches=0)
    print('Save figure to {}'.format(figname))

    plt.clf()

    df["ssl"] *= 100.0
    sslplot = sns.lineplot(data=df, x="Epoch", y="ssl", hue="Corruption", palette="husl")
    sslplot.set(ylim=(0.0, 80.0))
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    figname = os.path.join(foldername, 'ssl.png')
    plt.savefig(figname, bbox_inches='tight', pad_inches=0)
    print('Save figure to {}'.format(figname))
//  [python]
def visualize(model_dict, train_loader, test_loader, Y_LB, Y_UB, K, B):
    sns.set_theme(palette='colorblind')
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

    # Get model outputs
    model_df = []
    x_test, _ = unzip_dataloader(test_loader)
    for model_name in model_dict:
        model = model_dict[model_name]
        model.eval()
        y = model(x_test)
        model_df.append(make_dataframe(x_test, y, model_name))

    training_df = make_dataframe(*unzip_dataloader(train_loader), 'Training')
    test_df = make_dataframe(*unzip_dataloader(test_loader), 'Testing')
    oracle_df = make_dataframe(*unzip_dataloader(test_loader), 'Oracle')

    # plot oracle and predictions
    sns.pointplot(data=pd.concat([oracle_df, *model_df], ignore_index=True), x='x', y='y', hue='Method', ax=ax1)

    # plot data points
    sns.scatterplot(data=training_df, x='x', y='y', color='#003ea1', alpha=0.2, linewidths=0, s=100, ax=ax1,
                    legend=False)

    ax1.set_xlim((Y_LB - B) / K, (Y_UB - B) / K)
    ax1.set_ylim(Y_LB, Y_UB)
    ax1.set_xlabel(r'$x$', fontsize=10)
    ax1.set_ylabel(r'$y$', fontsize=10)

    # plot training histogram
    bins = np.linspace(Y_LB, Y_UB, 20)
    sns.histplot(data=training_df, y='y', kde=False, stat='density', hue='Method', common_norm=False, bins=bins, ax=ax2)

    # plot kdeplot
    sns.kdeplot(data=pd.concat([training_df, *model_df, test_df], ignore_index=True), y='y', hue='Method',
                common_norm=False, ax=ax2)

    ax2.set_ylim(Y_LB, Y_UB)
    ax2.set_xlabel(r'$p(y)$', fontsize=10)
    ax2.set_ylabel(r'$y$', fontsize=10)
    plt.tight_layout()
    plt.show()
//  [python]
def visualize(model_dict, train_loader, test_loader, Y_LB, Y_UB, K, B):
    sns.set_theme(palette='colorblind')
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

    # Get model outputs
    model_df = []
    x_test, _ = unzip_dataloader(test_loader)
    for model_name in model_dict:
        model = model_dict[model_name]
        model.eval()
        y = model(x_test)
        model_df.append(make_dataframe(x_test, y, model_name))

    training_df = make_dataframe(*unzip_dataloader(train_loader), 'Training')
    test_df = make_dataframe(*unzip_dataloader(test_loader), 'Testing')
    oracle_df = make_dataframe(*unzip_dataloader(test_loader), 'Oracle')

    # plot oracle and predictions
    sns.lineplot(data=pd.concat([oracle_df, *model_df], ignore_index=True), x='x', y='y', hue='Method', ax=ax1)

    # plot data points
    sns.scatterplot(data=training_df, x='x', y='y', color='#003ea1', alpha=0.2, linewidths=0, s=100, ax=ax1,
                    legend=False)

    ax1.set_xlim((Y_LB - B) / K, (Y_UB - B) / K)
    ax1.set_ylim(Y_LB, Y_UB)
    ax1.set_xlabel(r'$x$', fontsize=10)
    ax1.set_ylabel(r'$y$', fontsize=10)

    # plot training histogram
    bins = np.linspace(Y_LB, Y_UB, 20)
    sns.histplot(data=training_df, y='y', kde=False, stat='density', hue='Method', common_norm=False, bins=bins, ax=ax2)

    # plot kdeplot
    sns.kdeplot(data=pd.concat([training_df, *model_df, test_df], ignore_index=True), y='y', hue='Method',
                common_norm=False, ax=ax2)

    ax2.set_ylim(Y_LB, Y_UB)
    ax2.set_xlabel(r'$p(y)$', fontsize=10)
    ax2.set_ylabel(r'$y$', fontsize=10)
    plt.tight_layout()
    plt.show()
//  [python]
def plot_convergence_speed_for_different_goal_perf(env):
    _, _, lbs, palette, goal_perf_list, dir_str = help_func(env)
    result2print = {}
    df_list = []
    for goal_perf in goal_perf_list:
        result2print.update({goal_perf: dict()})
        result_dict_for_this_goal_perf = compute_convergence_speed(goal_perf)
        for alg in result_dict_for_this_goal_perf:
            first_arrive_steps_list = result_dict_for_this_goal_perf[alg]
            df_for_this_alg_this_goal = pd.DataFrame(dict(algorithm=alg,
                                                          goal_perf=str(goal_perf),
                                                          first_arrive_steps=list(map(lambda x: x/10000., min_n(first_arrive_steps_list, 3)))))
            result2print[goal_perf].update({alg: [np.mean(min_n(first_arrive_steps_list, 3)), 2*np.std(min_n(first_arrive_steps_list, 3))]})
            df_list.append(df_for_this_alg_this_goal)
    total_dataframe = df_list[0].append(df_list[1:], ignore_index=True) if len(df_list) > 1 else df_list[0]
    figsize = (20, 8)
    axes_size = [0.06, 0.12, 0.94, 0.88]
    fontsize = 25
    f1 = plt.figure(1, figsize=figsize)
    ax1 = f1.add_axes(axes_size)
    for alg in total_dataframe['algorithm'].unique():
        data_alg = total_dataframe[total_dataframe['algorithm'] == alg]
        plt.plot(data_alg["goal_perf"], data_alg["first_arrive_steps"], linewidth=2, label=alg, color=palette[alg])

    ax1.set_ylabel('Iterations required [x10000]', fontsize=fontsize)
    ax1.set_xlabel("Goal performance", fontsize=fontsize)
    handles, labels = ax1.get_legend_handles_labels()
    labels = lbs
    ax1.legend(handles=handles, labels=labels, loc='upper left', frameon=False, fontsize=11)
    ax1.set_xticklabels([str(goal) for goal in goal_perf_list])
    plt.yticks(fontsize=fontsize)
    plt.xticks(fontsize=fontsize)
    print(result2print)
    plt.show()
//  [python]
def plot_convergence_speed_for_different_goal_perf(env):
    _, _, lbs, palette, goal_perf_list, dir_str = help_func(env)
    result2print = {}
    df_list = []
    for goal_perf in goal_perf_list:
        result2print.update({goal_perf: dict()})
        result_dict_for_this_goal_perf = compute_convergence_speed(goal_perf)
        for alg in result_dict_for_this_goal_perf:
            first_arrive_steps_list = result_dict_for_this_goal_perf[alg]
            df_for_this_alg_this_goal = pd.DataFrame(dict(algorithm=alg,
                                                          goal_perf=str(goal_perf),
                                                          first_arrive_steps=list(map(lambda x: x/10000., min_n(first_arrive_steps_list, 3)))))
            result2print[goal_perf].update({alg: [np.mean(min_n(first_arrive_steps_list, 3)), 2*np.std(min_n(first_arrive_steps_list, 3))]})
            df_list.append(df_for_this_alg_this_goal)
    total_dataframe = df_list[0].append(df_list[1:], ignore_index=True) if len(df_list) > 1 else df_list[0]
    figsize = (20, 8)
    axes_size = [0.06, 0.12, 0.94, 0.88]
    fontsize = 25
    f1 = plt.figure(1, figsize=figsize)
    ax1 = f1.add_axes(axes_size)
    sns.lineplot(x="goal_perf", y="first_arrive_steps", hue="algorithm", data=total_dataframe, linewidth=2,
                 palette=palette, legend=False)
    ax1.set_ylabel('Iterations required [x10000]', fontsize=fontsize)
    ax1.set_xlabel("Goal performance", fontsize=fontsize)
    handles, labels = ax1.get_legend_handles_labels()
    labels = lbs
    ax1.legend(handles=handles, labels=labels, loc='upper left', frameon=False, fontsize=11)
    ax1.set_xticklabels([str(goal) for goal in goal_perf_list])
    plt.yticks(fontsize=fontsize)
    plt.xticks(fontsize=fontsize)
    print(result2print)
    plt.show()
//  [python]
axes[0].set_title('Correlation matrix')

### Let's start with PCA-based reactivation method
pca = PCA()
zSpkWake = StandardScaler().fit_transform(binWake)
pca.fit(zSpkWake)

# Plot the eigenvalues. Here it's all random, should be distributed around 1
sns.pointplot(ax = axes[1], data=pca.explained_variance_)
//  [python]
axes[0].set_title('Correlation matrix')

### Let's start with PCA-based reactivation method
pca = PCA()
zSpkWake = StandardScaler().fit_transform(binWake)
pca.fit(zSpkWake)

# Plot the eigenvalues. Here it's all random, should be distributed around 1
sns.lineplot(ax = axes[1], data=pca.explained_variance_)
//  [python]
def plot_avg_coverage_vs_time(cov_df, time_units="m"):
  print(yellow("Generating plot ..."))

  # Set plot style and extract only HDL line coverage
  sns.set_theme(context="notebook", style="darkgrid")
  hdl_cov_df = cov_df[cov_df[COVERAGE_TYPE_LABEL] == HW_LINE_COVERAGE_LABEL]

  # create figure and plot the data
  fig, ax = plt.subplots(1, 1, figsize=(4, 2))
  sns.pointplot(data=hdl_cov_df,
               x=TIME_LABEL,
               y=COVERAGE_LABEL,
               hue=TOPLEVEL_LABEL,
               ax=ax,
               markers="x",
               linestyles='-')

  # format the plot
  if time_units == "m":
    time_units_label = "min."
  elif time_units == "h":
    time_units_label = "hours"
  else:
    time_units_label = "s"
  ax.set_xlabel(TIME_LABEL + " (%s)" % time_units_label,
                fontsize=LABEL_FONT_SIZE)
  ax.set_ylabel("HDL Line " + COVERAGE_LABEL, fontsize=LABEL_FONT_SIZE)
  ax.tick_params("x", labelsize=TICK_FONT_SIZE)
  ax.tick_params("y", labelsize=TICK_FONT_SIZE)
  plt.legend(title="Core",
             fontsize=LEGEND_FONT_SIZE,
             title_fontsize=LEGEND_TITLE_FONT_SIZE,
             ncol=2)
  plt.tight_layout()

  # save the plot
  plt.savefig(PLOT_FILE_NAME, format=PLOT_FORMAT)
  print(green("Done."))
  print(LINE_SEP)
//  [python]
def plot_avg_coverage_vs_time(cov_df, time_units="m"):
  print(yellow("Generating plot ..."))

  # Set plot style and extract only HDL line coverage
  sns.set_theme(context="notebook", style="darkgrid")
  hdl_cov_df = cov_df[cov_df[COVERAGE_TYPE_LABEL] == HW_LINE_COVERAGE_LABEL]

  # create figure and plot the data
  fig, ax = plt.subplots(1, 1, figsize=(4, 2))
  sns.lineplot(data=hdl_cov_df,
               x=TIME_LABEL,
               y=COVERAGE_LABEL,
               hue=TOPLEVEL_LABEL,
               ax=ax,
               markers="x")

  # format the plot
  if time_units == "m":
    time_units_label = "min."
  elif time_units == "h":
    time_units_label = "hours"
  else:
    time_units_label = "s"
  ax.set_xlabel(TIME_LABEL + " (%s)" % time_units_label,
                fontsize=LABEL_FONT_SIZE)
  ax.set_ylabel("HDL Line " + COVERAGE_LABEL, fontsize=LABEL_FONT_SIZE)
  ax.tick_params("x", labelsize=TICK_FONT_SIZE)
  ax.tick_params("y", labelsize=TICK_FONT_SIZE)
  plt.legend(title="Core",
             fontsize=LEGEND_FONT_SIZE,
             title_fontsize=LEGEND_TITLE_FONT_SIZE,
             ncol=2)
  plt.tight_layout()

  # save the plot
  plt.savefig(PLOT_FILE_NAME, format=PLOT_FORMAT)
  print(green("Done."))
  print(LINE_SEP)
//  [python]
axes = (
    axes.flatten() if isinstance(axes, np.ndarray) else [axes]
)  # make it as a flat list

# use lineplot that has average curve (for same x-value) with 95% confidence interval on y-value
# https://seaborn.pydata.org/generated/seaborn.lineplot.html
# has at most 3 independent dims to plot, using hue and style. But recommend to use at most 2 dims,
# 	by setting hue and style the same key
# NOTE: any seaborn function has argument ax to support subplots

df_ours = df.loc[df["method"] == "ours"]
df_others = df.loc[df["method"] != "ours"]
ax_id = 0
for key in key_of_interests[1:]:
    for variant_tag_name in FLAGS.factors:

        sns.tsplot(
            ax=axes[ax_id],
            data=df_ours,
            time=x_tag,
            value=key,
            condition=variant_tag_name,
            # hue_order=order,
            # style=variant_tag,
            # style_order=order,
            # ci=None, # save a lot time without error bars
            err_style="band",
        )
        axes[ax_id].legend(framealpha=0.5, loc="upper left")
        axes[ax_id].set_title(variant_tag_name)
        # if FLAGS.max_x is not None:
        #     axes[ax_id].set_xlim(0, FLAGS.max_x)
        ax_id += 1
//  [python]
axes = (
    axes.flatten() if isinstance(axes, np.ndarray) else [axes]
)  # make it as a flat list

# use lineplot that has average curve (for same x-value) with 95% confidence interval on y-value
# https://seaborn.pydata.org/generated/seaborn.lineplot.html
# has at most 3 independent dims to plot, using hue and style. But recommend to use at most 2 dims,
# 	by setting hue and style the same key
# NOTE: any seaborn function has argument ax to support subplots

df_ours = df.loc[df["method"] == "ours"]
df_others = df.loc[df["method"] != "ours"]
ax_id = 0
for key in key_of_interests[1:]:
    for variant_tag_name in FLAGS.factors:

        sns.lineplot(
            ax=axes[ax_id],
            data=df_ours,
            x=x_tag,
            y=key,
            hue=variant_tag_name,
            # hue_order=order,
            # style=variant_tag,
            # style_order=order,
            # ci=None, # save a lot time without error bars
            sort=False,
        )
        axes[ax_id].legend(framealpha=0.5, loc="upper left")
        axes[ax_id].set_title(variant_tag_name)
        # if FLAGS.max_x is not None:
        #     axes[ax_id].set_xlim(0, FLAGS.max_x)
        ax_id += 1
//  [python]
def plot_log(info, title, filename, xlim, ylim, inicio, countries, colors): 
  
  plt.close('all')
  valores = {}
  plt.figure(figsize=(14, 8))
  styles = ['dashed', 'solid', 'dotted', 'solid', 'dashdot']
 
  n = -1
  for k, country in enumerate(countries):
    valores[country] = [t for t in ts[info][country] if t > inicio]
    if len(valores[country]) == 0: continue
    if country == 'China': n = xlim
    else: n = -1
    y = len(valores[country][:n]) +0.1
    altura = np.log10(valores[country][:n])[-1]
    alpha = 0.85
    if country == 'Germany': altura -= 0.05
    if country == 'Brazil': 
      # altura += 0.05
      y += 0.1
      alpha = 1
      colors[country] = [0, 0, 0, 1]
    p = plt.plot(np.arange(len(valores[country][:n])), np.log10(valores[country][:n]), label=country, linewidth=3, color=colors[country], alpha=alpha, marker='o', linestyle='solid')
    color = p[0].get_color()

    dy = np.log10(valores[country][-1]) - np.log10(valores[country][-7]) 
    rot = max(0, math.atan2(dy,7))  * (180/math.pi) * 10
    t = plt.text(y-0.5, altura, country , fontsize=12, rotation=rot,color='w',alpha=1.,
                bbox=dict(facecolor=color, edgecolor='none', alpha=alpha))

  
  plt.xticks(fontsize=14)
  ticks = [str(10**i) for i in np.arange(0, ylim+1)]
  plt.yticks(np.arange(0, ylim+1), ticks, fontsize=14, rotation=46)
  plt.xlabel('Dias', fontsize=16)
  plt.ylabel(title + ' acumulados', fontsize=16)
  
  plt.title(title + ' acumulados a partir do registro N > ' + str(inicio), fontsize=16)
  plt.grid(True, alpha=0.5)
  
  plt.xlim(0, xlim)
  ylim_lower = max(0, np.floor(np.log10(inicio)) )
  plt.ylim(ylim_lower,ylim)
  plt.legend(fontsize=14, loc=4)
  
  plt.savefig(filename+'.png', format='png', dpi=150, bbox_inches='tight')
//  [python]
def plot_log(info, title, filename, xlim, ylim, inicio, countries, colors): 
  
  plt.close('all')
  valores = {}
  plt.figure(figsize=(14, 8))
  styles = ['dashed', 'solid', 'dotted', 'solid', 'dashdot']
 
  n = -1
  for k, country in enumerate(countries):
    valores[country] = [t for t in ts[info][country] if t > inicio]
    if len(valores[country]) == 0: continue
    if country == 'China': n = xlim
    else: n = -1
    y = len(valores[country][:n]) +0.1
    altura = np.log10(valores[country][:n])[-1]
    alpha = 0.85
    if country == 'Germany': altura -= 0.05
    if country == 'Brazil': 
      # altura += 0.05
      y += 0.1
      alpha = 1
      colors[country] = [0, 0, 0, 1]
    p = sns.lineplot(np.arange(len(valores[country][:n])), np.log10(valores[country][:n]), label=country, linewidth=3, color=colors[country], alpha=alpha, marker='o', linestyle='solid')
    color = p.get_lines()[-1].get_color()

    dy = np.log10(valores[country][-1]) - np.log10(valores[country][-7]) 
    rot = max(0, math.atan2(dy,7))  * (180/math.pi) * 10
    t = plt.text(y-0.5, altura, country , fontsize=12, rotation=rot,color='w',alpha=1.,
                bbox=dict(facecolor=color, edgecolor='none', alpha=alpha))

  
  plt.xticks(fontsize=14)
  ticks = [str(10**i) for i in np.arange(0, ylim+1)]
  plt.yticks(np.arange(0, ylim+1), ticks, fontsize=14, rotation=46)
  plt.xlabel('Dias', fontsize=16)
  plt.ylabel(title + ' acumulados', fontsize=16)
  
  plt.title(title + ' acumulados a partir do registro N > ' + str(inicio), fontsize=16)
  plt.grid(True, alpha=0.5)
  
  plt.xlim(0, xlim)
  ylim_lower = max(0, np.floor(np.log10(inicio)) )
  plt.ylim(ylim_lower,ylim)
  plt.legend(fontsize=14, loc=4)
  
  plt.savefig(filename+'.png', format='png', dpi=150, bbox_inches='tight')
//  [python]
def plot_metric_vs_missing_fraction(data, y, ylabel, ci, fpath, fname):
    plt.figure(figsize=(8, 6))
    ax = sns.pointplot(
        data=data,
        x="Missing Fraction",
        y=y,
        hue="Imputer",
        ci=ci
    )
    ax.set(ylabel=ylabel)
    ax.set_xticks(sorted(data["Missing Fraction"].unique()))
    plt.legend(bbox_to_anchor=(1, 1), loc="upper left")  # place legend in top right corner
    fpath.mkdir(parents=True, exist_ok=True)
    plt.savefig(fpath/fname)
//  [python]
def plot_metric_vs_missing_fraction(data, y, ylabel, ci, fpath, fname):
    plt.figure(figsize=(8, 6))
    ax = sns.lineplot(
        data=data,
        x="Missing Fraction",
        y=y,
        hue="Imputer",
        style="Imputer",
        ci=ci
    )
    ax.set(ylabel=ylabel)
    ax.set_xticks(sorted(data["Missing Fraction"].unique()))
    plt.legend(bbox_to_anchor=(1, 1), loc="upper left")  # place legend in top right corner
    fpath.mkdir(parents=True, exist_ok=True)
    plt.savefig(fpath/fname)
//  [python]
def learning_curve(episode_rewards, log_dir, window=10):
    # Calculate rolling window metrics
    rolling_average = episode_rewards.rolling(window=window, min_periods=window).mean().dropna()
    rolling_max = episode_rewards.rolling(window=window, min_periods=window).max().dropna()
    rolling_min = episode_rewards.rolling(window=window, min_periods=window).min().dropna()

    # Change column name
    rolling_average.columns = ['Average Reward']
    rolling_max.columns = ['Max Reward']
    rolling_min.columns = ['Min Reward']
    rolling_data = pd.concat([rolling_average, rolling_max, rolling_min], axis=1)

    # Plot
    sns.set()
    plt.figure(0)
    ax = plt.plot(rolling_average)
    plt.fill_between(rolling_average.index, rolling_min.iloc[:, 0], rolling_max.iloc[:, 0], alpha=0.2)
    ax = plt.plot(rolling_max)
    ax = plt.plot(rolling_min)
    ax.set_title('Learning Curve')
    ax.set_ylabel('Reward')
    ax.set_xlabel('Episodes')

    # Save figure
    plt.savefig(log_dir + 'learning_curve' + str(window) + '.png')
//  [python]
def learning_curve(episode_rewards, log_dir, window=10):
    # Calculate rolling window metrics
    rolling_average = episode_rewards.rolling(window=window, min_periods=window).mean().dropna()
    rolling_max = episode_rewards.rolling(window=window, min_periods=window).max().dropna()
    rolling_min = episode_rewards.rolling(window=window, min_periods=window).min().dropna()

    # Change column name
    rolling_average.columns = ['Average Reward']
    rolling_max.columns = ['Max Reward']
    rolling_min.columns = ['Min Reward']
    rolling_data = pd.concat([rolling_average, rolling_max, rolling_min], axis=1)

    # Plot
    sns.set()
    plt.figure(0)
    ax = sns.lineplot(data=rolling_data)
    ax.fill_between(rolling_average.index, rolling_min.iloc[:, 0], rolling_max.iloc[:, 0], alpha=0.2)
    ax.set_title('Learning Curve')
    ax.set_ylabel('Reward')
    ax.set_xlabel('Episodes')

    # Save figure
    plt.savefig(log_dir + 'learning_curve' + str(window) + '.png')
//  [python]
def plot_coverage(self) -> None:
        """Plot Coverage over time graph."""
        if not self.coverage_plot_data:
            return
        data = self.coverage_plot_data + \
            [(time.time() - self.start_time, len(self.coverage_plot_data))]
        frame = pd.DataFrame(
            data, columns=['Time (seconds)', 'Basic Blocks covered'])
        plot = sns.tsplot(
            data=frame, time='Time (seconds)', value='Basic Blocks covered')
        plot.set(xlim=(1, None))
        plot.set_title(f'Timestamp of last update: {str(datetime.now())}')

        path = os.path.join(
            self.output_directory,
            'coverage_over_time_plot.svg'
        )
        plot.figure.savefig(path)
        plt.clf()
        with open(path) as f:
            svg = f.read()
        self.mqtt_client.publish('coverage_over_time', svg)
//  [python]
def plot_coverage(self) -> None:
        """Plot Coverage over time graph."""
        if not self.coverage_plot_data:
            return
        data = self.coverage_plot_data + \
            [(time.time() - self.start_time, len(self.coverage_plot_data))]
        frame = pd.DataFrame(
            data, columns=['Time (seconds)', 'Basic Blocks covered'])
        plot = sns.lineplot(
            data=frame, x='Time (seconds)', y='Basic Blocks covered')
        plot.set(xlim=(1, None))
        plot.set_title(f'Timestamp of last update: {str(datetime.now())}')

        path = os.path.join(
            self.output_directory,
            'coverage_over_time_plot.svg'
        )
        plot.figure.savefig(path)
        plt.clf()
        with open(path) as f:
            svg = f.read()
        self.mqtt_client.publish('coverage_over_time', svg)
//  [python]
def lineplot(x, y, y2=None, filename='', xaxis='Steps', yaxis='Return', title=''):
  y = np.array(y)
  y_mean, y_std = y.mean(axis=1), y.std(axis=1)
  plt.plot(x, y_mean, color='coral')
  plt.fill_between(x, y_mean - y_std, y_mean + y_std, color='coral', alpha=0.3)
  if y2:
    y2 = np.array(y2)
    y2_mean, y2_std = y2.mean(axis=1), y2.std(axis=1)
    plt.plot(x, y2_mean, color='b')
    plt.fill_between(x, y2_mean - y2_std, y2_mean + y2_std, color='b', alpha=0.3)

  plt.xlim(left=0, right=x[-1])
  plt.xlabel(xaxis)
  plt.ylabel(yaxis)
  plt.title(title)
  plt.savefig(f'{filename}.png')
  plt.close()
//  [python]
def lineplot(x, y, y2=None, filename='', xaxis='Steps', yaxis='Return', title=''):
  y = np.array(y)
  y_mean, y_std = y.mean(axis=1), y.std(axis=1)
  sns.lineplot(x=x, y=y_mean, color='coral')
  plt.fill_between(x, y_mean - y_std, y_mean + y_std, color='coral', alpha=0.3)
  if y2:
    y2 = np.array(y2)
    y2_mean, y2_std = y2.mean(axis=1), y2.std(axis=1)
    sns.lineplot(x=x, y=y2_mean, color='b')
    plt.fill_between(x, y2_mean - y2_std, y2_mean + y2_std, color='b', alpha=0.3)

  plt.xlim(left=0, right=x[-1])
  plt.xlabel(xaxis)
  plt.ylabel(yaxis)
  plt.title(title)
  plt.savefig(f'{filename}.png')
  plt.close()
//  [python]
def plot(df, end_time, figname, x="time", y="pct", hue="Mode"):
    fig, ax = plt.subplots(figsize=figsize)
    ax.set_ylabel("\% reducer outputs available", fontsize=11)
    g = sns.tsplot(data=df, time=x, value=y, unit="id", condition=hue, ax=ax)
    plt.axvline(
        end_time,
        figure=fig,
        color="gray",
        linestyle="dotted",
        linewidth=3,
        label="Unpipelined\nfull shuffle",
    )
    #    plt.fill_between(df[x].values, df[y].values, alpha=0.1)
    plt.xlim((0, int(math.ceil(end_time)) + 10))
    plt.ylim((0, 100))
    ax.yaxis.set_major_formatter(mpl.ticker.PercentFormatter(decimals=0))
    plt.grid(axis="y")
    plt.xlabel("Time (s)")
    plt.legend()
    plt.tight_layout()
    filename = figname + ".pdf"
    print(filename)
    plt.savefig(filename, bbox_inches="tight")
//  [python]
def plot(df, end_time, figname, x="time", y="pct", hue="Mode"):
    fig, ax = plt.subplots(figsize=figsize)
    ax.set_ylabel("\% reducer outputs available", fontsize=11)
    g = sns.lineplot(data=df, x=x, y=y, hue=hue, ax=ax)
    plt.axvline(
        end_time,
        figure=fig,
        color="gray",
        linestyle="dotted",
        linewidth=3,
        label="Unpipelined\nfull shuffle",
    )
    #    plt.fill_between(df[x].values, df[y].values, alpha=0.1)
    plt.xlim((0, int(math.ceil(end_time)) + 10))
    plt.ylim((0, 100))
    ax.yaxis.set_major_formatter(mpl.ticker.PercentFormatter(decimals=0))
    plt.grid(axis="y")
    plt.xlabel("Time (s)")
    plt.legend()
    plt.tight_layout()
    filename = figname + ".pdf"
    print(filename)
    plt.savefig(filename, bbox_inches="tight")
//  [python]
def lineplot_thetas_log_squared_y_residual_error(
    df: pd.DataFrame, y_key: str, y_label: str, suptitle: str = "", save_as: Union[str, Path] = None,
):

    plt.figure()
    x = sns.tsplot(
        data=df, time="theta", value=y_key, unit="gamma", condition="gamma", ci=[68,95],  interpolate=True
    )

    plt.ylabel(y_label)
    plt.xlabel("$\\theta_0$")
    # plt.suptitle(suptitle)
    plt.legend(title="$\gamma$")
    plt.tight_layout()
    if save_as is not None:
        plt.savefig(save_as)
    plt.close()
//  [python]
def lineplot_thetas_log_squared_y_residual_error(
    df: pd.DataFrame, y_key: str, y_label: str, suptitle: str = "", save_as: Union[str, Path] = None,
):

    plt.figure()
    x = sns.lineplot(
        data=df, x="theta", y=y_key, hue="gamma", style="gamma", hue_norm=mplc.LogNorm(), markers=True, palette="Set1"
    )

    plt.ylabel(y_label)
    plt.xlabel("$\\theta_0$")
    # plt.suptitle(suptitle)
    plt.legend(title="$\gamma$")
    plt.tight_layout()
    if save_as is not None:
        plt.savefig(save_as)
    plt.close()
//  [python]
def lineplot_thetas_squared_bias(
    df: pd.DataFrame, y_key: str, y_label: str, suptitle: str = "", save_as: Union[str, Path] = None,
):

    plt.figure()
    x = sns.pointplot(data=df, x="theta", y=y_key, hue="gamma", style="gamma", markers=True, palette="Set1")

    plt.ylabel(y_label)
    plt.xlabel("$\\theta_0$")
    # plt.suptitle(suptitle)
    plt.legend(title="$\gamma$")
    plt.tight_layout()
    if save_as is not None:
        plt.savefig(save_as)
    plt.close()
//  [python]
def lineplot_thetas_squared_bias(
    df: pd.DataFrame, y_key: str, y_label: str, suptitle: str = "", save_as: Union[str, Path] = None,
):

    plt.figure()
    x = sns.lineplot(data=df, x="theta", y=y_key, hue="gamma", style="gamma", markers=True, palette="Set1")

    plt.ylabel(y_label)
    plt.xlabel("$\\theta_0$")
    # plt.suptitle(suptitle)
    plt.legend(title="$\gamma$")
    plt.tight_layout()
    if save_as is not None:
        plt.savefig(save_as)
    plt.close()
//  [python]
def gen_plot(config, file_path, data, title=None, learning_curve=False):
    plt.figure(figsize=(6, 5))

    plt.title(config['title'] if not title else title)
    plt.xlabel(config['x_label'])
    plt.ylabel(config['y_label'])

    plt.ylim(*config['ylim'])
    if config['solved']:
        # plt.axhline(config['solved'], color=COLORS[4], linestyle='--', label='$[Solved]$') # only for figure 1
        plt.axhline(config['solved'], color=COLORS[3], linestyle='--', label='$[Solved]$')

    # colors = config['colors'][::-1][1:] # only for figure 1
    colors = config['colors']
    for i, entry in enumerate(data):
        timesteps, averaged_curve, sigma, convergence = entry
        plt.plot(timesteps,
                     averaged_curve,
                     c=colors[i],
                     label=config['labels'][i])
        if convergence is not None:
            plt.plot([timesteps[-1], timesteps[-1] + 0.5],
                     [averaged_curve.values[-1], averaged_curve.values[-1]],
                     color=colors[i],
                     linestyle='--')

        plt.fill_between(x=timesteps,
                         y1=averaged_curve + sigma,
                         y2=averaged_curve - sigma,
                         facecolor=colors[i],
                         alpha=0.1)
    if learning_curve:
        plt.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))

    plt.legend(loc=config['legend_loc'], frameon=True, framealpha=0.5)
    plt.grid(b=False)

    # plt.show()

    plt.savefig(fname=file_path,
                bbox_inches='tight',
                pad_inches=0)
    plt.close()