jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def plotCosts(df):
    g = sns.lmplot('num_hole_vertices', 'cost', data=df, hue='planner', fit_reg=False, size=width, aspect=aspect, legend_out=False)
    g.set(xlim=(df['num_hole_vertices'].min() - 10, df['num_hole_vertices'].max() + 10))
    g.set(ylim=(df['cost'].min() - 100, df['cost'].max() + 100))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Cost [s]")
    g.ax.legend(loc="upper left")
    g.savefig("./data/cost.pdf", bbox_inches='tight')

    # Linear fit.
    df_fit = createCostFits(df)
    min = df['cost'].min()
    max = df['cost'].max()
    is_smaller = df_fit['y'] < max
    df_fit = df_fit[is_smaller]

    sns.regplot('x', 'y', data=df_fit, scatter=False, ax=g.axes[0, 0], label=None)
    g.set(xlim=(df['num_hole_vertices'].min() - 10, df['num_hole_vertices'].max() + 10))
    g.set(ylim=(df['cost'].min() - 10, df['cost'].max() + 10))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Cost [s]")
    g.savefig("./data/cost.pdf", bbox_inches='tight')
//  [python]
def plotCosts(df):
    g = sns.lmplot('num_hole_vertices', 'cost', data=df, hue='planner', fit_reg=False, size=width, aspect=aspect, legend_out=False)
    g.set(xlim=(df['num_hole_vertices'].min() - 10, df['num_hole_vertices'].max() + 10))
    g.set(ylim=(df['cost'].min() - 100, df['cost'].max() + 100))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Cost [s]")
    g.ax.legend(loc="upper left")
    g.savefig("./data/cost.pdf", bbox_inches='tight')

    # Linear fit.
    df_fit = createCostFits(df)
    min = df['cost'].min()
    max = df['cost'].max()
    is_smaller = df_fit['y'] < max
    df_fit = df_fit[is_smaller]

    sns.lineplot('x', 'y', data=df_fit, hue='planner', ax=g.axes[0, 0], legend=False)
    g.set(xlim=(df['num_hole_vertices'].min() - 10, df['num_hole_vertices'].max() + 10))
    g.set(ylim=(df['cost'].min() - 10, df['cost'].max() + 10))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Cost [s]")
    g.savefig("./data/cost.pdf", bbox_inches='tight')
//  [python]
def plotTimes(df):
    # Plot times
    t = df[['timer_setup_total','timer_solve_total']].values
    t_total = np.sum(t, axis=1)
    df_t_total = pd.DataFrame(t_total, columns=['t_total'])
    df_planner = df[['planner', 'num_hole_vertices']]
    df_t_total = df_planner.join(df_t_total)

    # Scatter plot
    g = sns.lmplot('num_hole_vertices', 't_total', data=df_t_total, hue='planner', fit_reg=False, legend=False, legend_out=False, size=width, aspect=aspect)

    # Exponential fit.
    df_fit = createFits(df_t_total)
    min = df_t_total['t_total'].min()
    max = df_t_total['t_total'].max()
    is_smaller = df_fit['y'] < max
    df_fit = df_fit[is_smaller]

    for planner in df_fit['planner'].unique():
        df_subset = df_fit[df_fit['planner'] == planner]
        plt.plot(df_subset['x'], df_subset['y'], label=planner, ax=g.axes[0, 0])
    g.set(xlim=(df_t_total['num_hole_vertices'].min() - 10, df_t_total['num_hole_vertices'].max() + 10))
    g.set(ylim=(df_t_total['t_total'].min() - 10, df_t_total['t_total'].max() + 10))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Runtime [s]")
    g.savefig("./data/time.pdf", bbox_inches='tight')

    print("Maximum computation times:")
    print("our_bcd: %.3f" %(df_t_total[df['planner'] == 'our_bcd']['t_total'].max()))
    print("our_tcd: %.3f" %(df_t_total[df['planner'] == 'our_tcd']['t_total'].max()))
    print("one_dir_gk: %.3f" %(df_t_total[df['planner'] == 'one_dir_gk']['t_total'].max()))
    print("gtsp_exact: %.3f" %(df_t_total[df['planner'] == 'gtsp_exact']['t_total'].max()))
    print("one_dir_exact: %.3f" %(df_t_total[df['planner'] == 'one_dir_exact']['t_total'].max()))

    instance = '15/0000'
    pd.set_option('display.max_columns', None)
    print("Computation times instance: %s" %(instance))
    print(df[df['instance'] == instance])
//  [python]
def plotTimes(df):
    # Plot times
    t = df[['timer_setup_total','timer_solve_total']].values
    t_total = np.sum(t, axis=1)
    df_t_total = pd.DataFrame(t_total, columns=['t_total'])
    df_planner = df[['planner', 'num_hole_vertices']]
    df_t_total = df_planner.join(df_t_total)

    # Scatter plot
    g = sns.lmplot('num_hole_vertices', 't_total', data=df_t_total, hue='planner', fit_reg=False, legend=False, legend_out=False, size=width, aspect=aspect)

    # Exponential fit.
    df_fit = createFits(df_t_total)
    min = df_t_total['t_total'].min()
    max = df_t_total['t_total'].max()
    is_smaller = df_fit['y'] < max
    df_fit = df_fit[is_smaller]

    sns.lineplot('x', 'y', data=df_fit, hue='planner', ax=g.axes[0, 0], legend=False)
    g.set(xlim=(df_t_total['num_hole_vertices'].min() - 10, df_t_total['num_hole_vertices'].max() + 10))
    g.set(ylim=(df_t_total['t_total'].min() - 10, df_t_total['t_total'].max() + 10))
    g.set(xlabel="Number of Hole Vertices [1]")
    g.set(ylabel="Runtime [s]")
    g.savefig("./data/time.pdf", bbox_inches='tight')

    print("Maximum computation times:")
    print("our_bcd: %.3f" %(df_t_total[df['planner'] == 'our_bcd']['t_total'].max()))
    print("our_tcd: %.3f" %(df_t_total[df['planner'] == 'our_tcd']['t_total'].max()))
    print("one_dir_gk: %.3f" %(df_t_total[df['planner'] == 'one_dir_gk']['t_total'].max()))
    print("gtsp_exact: %.3f" %(df_t_total[df['planner'] == 'gtsp_exact']['t_total'].max()))
    print("one_dir_exact: %.3f" %(df_t_total[df['planner'] == 'one_dir_exact']['t_total'].max()))

    instance = '15/0000'
    pd.set_option('display.max_columns', None)
    print("Computation times instance: %s" %(instance))
    print(df[df['instance'] == instance])
//  [python]
def plot(character, i, index0, index1, formula, ax, index2, index3):
    print(index0, index1)
    y = np.array([results[character][j] for j in range(index0, index1)])
    y2 = np.array([results[character][j] for j in range(index2, index3)])
    y = np.concatenate([y, y2])
    if character == "simple":
        y = (1 - y / 10)
    x_values = np.array([results["relative_weight"][j] for j in range(index0, index1)])
    x_2 = np.array([results["relative_weight"][j] for j in range(index2, index3)])
    x_values = np.concatenate([x_values, x_2])
    y_values = y
    s.lineplot(
        x=x_values,
        y=y_values,
        color=colors[i],
        ax=ax
    )
    if character == "educational":
        return
    index_ = order_first[character]
    actual_height = results.iloc[index_][character]
    if character == "simple":
        actual_height = (1 - actual_height / 10)
    s.lineplot(
        x=[min(x_values), max(x_values)],
        y=[actual_height, actual_height],
        color=colors[i],
        alpha=0.5,
        linestyle="--", 
        ax=ax
    )
//  [python]
def plot(character, i, index0, index1, formula, ax, index2, index3):
    print(index0, index1)
    y = np.array([results[character][j] for j in range(index0, index1)])
    y2 = np.array([results[character][j] for j in range(index2, index3)])
    y = np.concatenate([y, y2])
    if character == "simple":
        y = (1 - y / 10)
    x_values = np.array([results["relative_weight"][j] for j in range(index0, index1)])
    x_2 = np.array([results["relative_weight"][j] for j in range(index2, index3)])
    x_values = np.concatenate([x_values, x_2])
    y_values = y
    sns.lineplot(
        x=x_values,
        y=y_values,
        color=colors[i],
        ax=ax
    )
    if character == "educational":
        return
    index_ = order_first[character]
    actual_height = results.iloc[index_][character]
    if character == "simple":
        actual_height = (1 - actual_height / 10)
    sns.lineplot(
        x=[min(x_values), max(x_values)],
        y=[actual_height, actual_height],
        color=colors[i],
        alpha=0.5,
        linestyle="--", 
        ax=ax
    )
//  [python]
def plot_dataset_loss(dataset: str):

    df = all_results_df()

    df_pt = df[(df.dataset == dataset) & (df.dl_frame == "Pytorch")][
        ["loss", "n100", "r20", "r50"]
    ].melt("loss", var_name="metric", value_name="value")
    df_mx = df[(df.dataset == dataset) & (df.dl_frame == "Mxnet")][
        ["loss", "n100", "r20", "r50"]
    ].melt("loss", var_name="metric", value_name="value")

    # manually removing an results that were so bad that mess the plot
    if dataset == "movielens":
        df_mx = df_mx[df_mx.loss < 380]
    elif dataset == "amazon":
        df_mx = df_mx[df_mx.loss < 95]
        df_pt = df_pt[df_pt.loss < 105]

    plt.figure(figsize=(15, 4))

    plt.subplot(1, 2, 1)
    sns.pointplot(
        x="loss",
        y="value",
        hue="metric",
        data=df_pt,
        palette="Reds",
    )
    plt.xlabel("Loss")
    plt.ylabel("metric value")
    plt.title("Pytorch")

    plt.subplot(1, 2, 2)
    sns.pointplot(
        x="loss",
        y="value",
        hue="metric",
        data=df_mx,
        palette="Blues",
    )
    plt.xlabel("Loss")
    plt.ylabel("metric value")
    plt.title("Mxnet")

    plt.suptitle(dataset, fontweight="bold")
    plt.subplots_adjust(top=0.8)
//  [python]
def plot_dataset_loss(dataset: str):

    df = all_results_df()

    df_pt = df[(df.dataset == dataset) & (df.dl_frame == "Pytorch")][
        ["loss", "n100", "r20", "r50"]
    ].melt("loss", var_name="metric", value_name="value")
    df_mx = df[(df.dataset == dataset) & (df.dl_frame == "Mxnet")][
        ["loss", "n100", "r20", "r50"]
    ].melt("loss", var_name="metric", value_name="value")

    # manually removing an results that were so bad that mess the plot
    if dataset == "movielens":
        df_mx = df_mx[df_mx.loss < 380]
    elif dataset == "amazon":
        df_mx = df_mx[df_mx.loss < 95]
        df_pt = df_pt[df_pt.loss < 105]

    plt.figure(figsize=(15, 4))

    plt.subplot(1, 2, 1)
    sns.lineplot(
        x="loss",
        y="value",
        hue="metric",
        style="metric",
        markers=True,
        markersize=10,
        linewidth=2,
        data=df_pt,
        legend="full",
        palette="Reds",
    )
    plt.xlabel("Loss")
    plt.ylabel("metric value")
    plt.title("Pytorch")

    plt.subplot(1, 2, 2)
    sns.lineplot(
        x="loss",
        y="value",
        hue="metric",
        style="metric",
        markers=True,
        markersize=10,
        linewidth=2,
        data=df_mx,
        legend="full",
        palette="Blues",
    )
    plt.xlabel("Loss")
    plt.ylabel("metric value")
    plt.title("Mxnet")

    plt.suptitle(dataset, fontweight="bold")
    plt.subplots_adjust(top=0.8)
//  [python]
def plot_turtle_training_curves():
    # Load training and validation data
    log_dir = "saved_models/perception/turtlebot2d/commit_8439378/"
    train_log_file = "run-commit_8439378_version_0_total_loss_train.csv"
    val_log_file = "run-commit_8439378_version_0_total_loss_val.csv"
    train_loss_df = pd.read_csv(log_dir + train_log_file)
    train_loss_df["Dataset"] = "Training"
    val_loss_df = pd.read_csv(log_dir + val_log_file)
    val_loss_df["Dataset"] = "Validation"

    # Concatenate the datasets
    loss_df = pd.concat([train_loss_df, val_loss_df])
    loss_df.rename(columns={"Value": "Total Loss"}, inplace=True)

    # We took the model from epoch 72, which occured approx at step 19200, so
    # crop the data to that point
    data_mask = loss_df["Step"] < 19200

    # Plot!
    sns.set_theme(context="paper", style="white")
    sns.set_style({"font.family": "serif"})
    ax = sns.tsplot(
        time="Step",
        value="Total Loss",
        unit="Dataset",
        condition="Dataset",
        data=loss_df[data_mask],
        linewidth=2,
    )
    ax.set(yscale="log")
    fig = plt.gcf()
    fig.set_size_inches(4, 2)
    plt.tight_layout()
    plt.show()
//  [python]
def plot_turtle_training_curves():
    # Load training and validation data
    log_dir = "saved_models/perception/turtlebot2d/commit_8439378/"
    train_log_file = "run-commit_8439378_version_0_total_loss_train.csv"
    val_log_file = "run-commit_8439378_version_0_total_loss_val.csv"
    train_loss_df = pd.read_csv(log_dir + train_log_file)
    train_loss_df["Dataset"] = "Training"
    val_loss_df = pd.read_csv(log_dir + val_log_file)
    val_loss_df["Dataset"] = "Validation"

    # Concatenate the datasets
    loss_df = pd.concat([train_loss_df, val_loss_df])
    loss_df.rename(columns={"Value": "Total Loss"}, inplace=True)

    # We took the model from epoch 72, which occured approx at step 19200, so
    # crop the data to that point
    data_mask = loss_df["Step"] < 19200

    # Plot!
    sns.set_theme(context="paper", style="white")
    sns.set_style({"font.family": "serif"})
    ax = sns.lineplot(
        x="Step",
        y="Total Loss",
        hue="Dataset",
        data=loss_df[data_mask],
        linewidth=2,
    )
    ax.set(yscale="log")
    fig = plt.gcf()
    fig.set_size_inches(4, 2)
    plt.tight_layout()
    plt.show()
//  [python]
def plot_anneal_schedule_dataset(dataset: str):
    def epoch2anneal(x):
        return x * 1 / 170

    def anneal2epoch(x):
        return x * 170

    (
        pt_best_anneal_epochs,
        pt_df_anneal_schedules,
    ) = prepare_dataframe_for_anneal_schedule_plot(dataset, "pt")
    (
        mx_best_anneal_epochs,
        mx_df_anneal_schedules,
    ) = prepare_dataframe_for_anneal_schedule_plot(dataset, "mx")

    plt.figure(figsize=(15, 4))

    plt.subplot(1, 2, 1)
    ax1 = sns.tsplot(
        time=pt_df_anneal_schedules.epochs,
        value=pt_df_anneal_schedules["NDCG@100"],
        condition=pt_df_anneal_schedules.architecture,
        linewidth=2.0,
        legend="full",
    )
    ax1.set_title("Pytorch")
    ax1.axvline(pt_best_anneal_epochs[100], 0, 1, color="blue", linewidth=0.5)
    ax1.axvline(pt_best_anneal_epochs[200], 0, 1, color="orange", linewidth=0.5)
    ax1.axvline(pt_best_anneal_epochs[300], 0, 1, color="green", linewidth=0.5)
    if dataset == "movielens":
        ax1.legend(bbox_to_anchor=(0.075, 0.39))
    ax2 = ax1.secondary_xaxis("top", functions=(epoch2anneal, anneal2epoch))

    plt.suptitle(dataset, fontweight="bold")
    plt.subplots_adjust(top=0.8)

    plt.subplot(1, 2, 2)
    ax1 = sns.tsplot(
        time=mx_df_anneal_schedules.epochs,
        value=mx_df_anneal_schedules["NDCG@100"],
        condition=mx_df_anneal_schedules.architecture,
        linewidth=2.0,
        legend="full",
    )
    ax1.set_title("Mxnet")
    ax1.axvline(mx_best_anneal_epochs[100], 0, 1, color="blue", linewidth=0.5)
    ax1.axvline(mx_best_anneal_epochs[200], 0, 1, color="orange", linewidth=0.5)
    ax1.axvline(mx_best_anneal_epochs[300], 0, 1, color="green", linewidth=0.5)
    ax2 = ax1.secondary_xaxis("top", functions=(epoch2anneal, anneal2epoch))
//  [python]
def plot_anneal_schedule_dataset(dataset: str):
    def epoch2anneal(x):
        return x * 1 / 170

    def anneal2epoch(x):
        return x * 170

    (
        pt_best_anneal_epochs,
        pt_df_anneal_schedules,
    ) = prepare_dataframe_for_anneal_schedule_plot(dataset, "pt")
    (
        mx_best_anneal_epochs,
        mx_df_anneal_schedules,
    ) = prepare_dataframe_for_anneal_schedule_plot(dataset, "mx")

    plt.figure(figsize=(15, 4))

    plt.subplot(1, 2, 1)
    ax1 = sns.lineplot(
        pt_df_anneal_schedules.epochs,
        pt_df_anneal_schedules["NDCG@100"],
        hue=pt_df_anneal_schedules.architecture,
        style=pt_df_anneal_schedules.architecture,
        linewidth=2.0,
        legend="full",
    )
    ax1.set_title("Pytorch")
    ax1.axvline(pt_best_anneal_epochs[100], 0, 1, color="blue", linewidth=0.5)
    ax1.axvline(pt_best_anneal_epochs[200], 0, 1, color="orange", linewidth=0.5)
    ax1.axvline(pt_best_anneal_epochs[300], 0, 1, color="green", linewidth=0.5)
    if dataset == "movielens":
        ax1.legend(bbox_to_anchor=(0.075, 0.39))
    ax2 = ax1.secondary_xaxis("top", functions=(epoch2anneal, anneal2epoch))

    plt.suptitle(dataset, fontweight="bold")
    plt.subplots_adjust(top=0.8)

    plt.subplot(1, 2, 2)
    ax1 = sns.lineplot(
        mx_df_anneal_schedules.epochs,
        mx_df_anneal_schedules["NDCG@100"],
        hue=mx_df_anneal_schedules.architecture,
        style=mx_df_anneal_schedules.architecture,
        linewidth=2.0,
        legend="full",
    )
    ax1.set_title("Mxnet")
    ax1.axvline(mx_best_anneal_epochs[100], 0, 1, color="blue", linewidth=0.5)
    ax1.axvline(mx_best_anneal_epochs[200], 0, 1, color="orange", linewidth=0.5)
    ax1.axvline(mx_best_anneal_epochs[300], 0, 1, color="green", linewidth=0.5)
    ax2 = ax1.secondary_xaxis("top", functions=(epoch2anneal, anneal2epoch))
//  [python]
def make_plot():
    list_x = np.linspace(0, 1, num=200)
    for center in [0, 1, 2, 3]:
        print(f"doing center {center}")
        ds = FedLidcIdri(train=True, pooled=False, center=center, debug=False)
        list_data = []
        for k in tqdm(range(len(ds))):
            data = ds[k][0].detach().cpu().ravel()
            data = data[data > 0.0]
            data = data[data < 1.0]
            list_data.append(data)
        list_data = np.concatenate(list_data)
        counts, bins, bars = plt.hist(
            list_data, density=True, bins=list_x, alpha=0.5, label=f"Client {k+1}"
        )
        np.save("bins.npy", bins)
        np.save(f"counts_center_{center}.npy", counts)
    plt.clf()

    # dict_center = {0: "GE MEDICAL SYSTEMS", 1: "PHILIPS", 2: "SIEMENS", 3: "TOSHIBA"}

    df = pd.DataFrame()
    for center in [0, 1, 2, 3]:
        bins = np.load("bins.npy")
        bars = np.load(f"counts_center_{center}.npy")
        df["Client " + str(center)] = bars
    df["Intensity"] = bins[1:]
    df = df.set_index("Intensity")

    for column in df.columns:
        plt.plot(df.index, df[column], label=column)
    plt.xlabel("Intensity")
    plt.ylabel("Density of voxels")
    plt.savefig("fed_lidc_intensity.pdf", bbox_inches="tight")
    plt.show()
//  [python]
def make_plot():
    list_x = np.linspace(0, 1, num=200)
    for center in [0, 1, 2, 3]:
        print(f"doing center {center}")
        ds = FedLidcIdri(train=True, pooled=False, center=center, debug=False)
        list_data = []
        for k in tqdm(range(len(ds))):
            data = ds[k][0].detach().cpu().ravel()
            data = data[data > 0.0]
            data = data[data < 1.0]
            list_data.append(data)
        list_data = np.concatenate(list_data)
        counts, bins, bars = plt.hist(
            list_data, density=True, bins=list_x, alpha=0.5, label=f"Client {k+1}"
        )
        np.save("bins.npy", bins)
        np.save(f"counts_center_{center}.npy", counts)
    plt.clf()

    # dict_center = {0: "GE MEDICAL SYSTEMS", 1: "PHILIPS", 2: "SIEMENS", 3: "TOSHIBA"}

    df = pd.DataFrame()
    for center in [0, 1, 2, 3]:
        bins = np.load("bins.npy")
        bars = np.load(f"counts_center_{center}.npy")
        df["Client " + str(center)] = bars
    df["Intensity"] = bins[1:]
    df = df.set_index("Intensity")

    sns.lineplot(data=df)
    plt.xlabel("Intensity")
    plt.ylabel("Density of voxels")
    plt.savefig("fed_lidc_intensity.pdf", bbox_inches="tight")
    plt.show()
//  [python]
def plot(self):
        from matplotlib.lines import Line2D

        #calculate cumulative volumes
        volume_df = self.df['item_id'].value_counts().reset_index()
        volume_df.columns = ['item_id', "volume"]
        volume_df['item_id'] = volume_df['item_id'].astype(str)
        volume_df['cumulative_volume'] = volume_df['volume'].cumsum()
        volume_df['percent_of_total_volume'] = volume_df['cumulative_volume']/volume_df['volume'].sum()

        #line plot of cumulative volume
        x = range(0,len(volume_df))
        plt.plot(x, volume_df["volume"].values, color="black")
        plt.xticks(x)

        #set labels
        if self.percentage != None:
            #plot vertical line at the tail location
            head = volume_df[volume_df["percent_of_total_volume"] <= self.percentage]
            tail = volume_df[volume_df["percent_of_total_volume"] > self.percentage]
            items_in_head = len(head)
            items_in_tail = len(tail)
            plt.axvline(x=items_in_head, color="red",  linestyle='--')

            # fill area under plot
            head = head.append(tail.head(1))
            x1 = head.index.values
            y1 = head['volume']
            x2 = tail.index.values
            y2 = tail['volume']
            self.ax.fill_between(x1, y1, color="blue", alpha=0.2)
            self.ax.fill_between(x2, y2,  color="orange", alpha=0.2)

            #create legend
            legend_elements = [Line2D([0], [0], marker='o', color='w', label=str(items_in_head)+': items in the head', markerfacecolor='blue', markersize=5),
                            Line2D([0], [0], marker='o', color='w', label=str(items_in_tail)+': items in the tail', markerfacecolor='orange', markersize=5)]
            self.ax.legend(handles=legend_elements, loc=1)

        else:
            x1 = volume_df['item_id']
            y1 = volume_df['volume']
            self.ax.fill_between(x1, y1, color="blue", alpha=0.3)
        if self.x_labels == False:
            plt.xticks([], [])
            self.ax.set(xticklabels=[])
        else:
            self.ax.set_xticklabels(labels = volume_df['item_id'], rotation = 45, ha="right")
//  [python]
def plot(self):
        from matplotlib.lines import Line2D

        #calculate cumulative volumes
        volume_df = self.df['item_id'].value_counts().reset_index()
        volume_df.columns = ['item_id', "volume"]
        volume_df['item_id'] = volume_df['item_id'].astype(str)
        volume_df['cumulative_volume'] = volume_df['volume'].cumsum()
        volume_df['percent_of_total_volume'] = volume_df['cumulative_volume']/volume_df['volume'].sum()

        #line plot of cumulative volume
        x = range(0,len(volume_df))
        sns.lineplot(x=x, y=volume_df["volume"].values, color="black", ax=self.ax)
        plt.xticks(x)

        #set labels
        if self.percentage != None:
            #plot vertical line at the tail location
            head = volume_df[volume_df["percent_of_total_volume"] <= self.percentage]
            tail = volume_df[volume_df["percent_of_total_volume"] > self.percentage]
            items_in_head = len(head)
            items_in_tail = len(tail)
            plt.axvline(x=items_in_head, color="red",  linestyle='--')

            # fill area under plot
            head = head.append(tail.head(1))
            x1 = head.index.values
            y1 = head['volume']
            x2 = tail.index.values
            y2 = tail['volume']
            self.ax.fill_between(x1, y1, color="blue", alpha=0.2)
            self.ax.fill_between(x2, y2,  color="orange", alpha=0.2)

            #create legend
            legend_elements = [Line2D([0], [0], marker='o', color='w', label=str(items_in_head)+': items in the head', markerfacecolor='blue', markersize=5),
                            Line2D([0], [0], marker='o', color='w', label=str(items_in_tail)+': items in the tail', markerfacecolor='orange', markersize=5)]
            self.ax.legend(handles=legend_elements, loc=1)

        else:
            x1 = volume_df['item_id']
            y1 = volume_df['volume']
            self.ax.fill_between(x1, y1, color="blue", alpha=0.3)
        if self.x_labels == False:
            plt.xticks([], [])
            self.ax.set(xticklabels=[])
        else:
            self.ax.set_xticklabels(labels = volume_df['item_id'], rotation = 45, ha="right")
//  [python]
def model_param_ts(param_ts: Union[pd.Series, pd.DataFrame],
                   yvar_format: str = '{:.2f}',
                   x_rotation: int = 0,
                   title: str = None,
                   markers: bool = True,
                   legend_loc: str = 'upper center',
                   ax: plt.Subplot = None
                   ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    sns.tsplot(data=param_ts, dashes=True, markers=markers, ax=ax)

    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    ax.legend(loc=legend_loc, framealpha=0)
    get_legend_colors(ax)

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]
    if isinstance(param_ts, pd.Series):
        ax.set_title(param_ts.name, color='blue')
    elif title is not None:
        ax.set_title(title, color='blue')
    return fig
//  [python]
def model_param_ts(param_ts: Union[pd.Series, pd.DataFrame],
                   yvar_format: str = '{:.2f}',
                   x_rotation: int = 0,
                   title: str = None,
                   markers: bool = True,
                   legend_loc: str = 'upper center',
                   ax: plt.Subplot = None
                   ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    sns.lineplot(data=param_ts, dashes=True, markers=markers, ax=ax)

    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    ax.legend(loc=legend_loc, framealpha=0)
    get_legend_colors(ax)

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]
    if isinstance(param_ts, pd.Series):
        ax.set_title(param_ts.name, color='blue')
    elif title is not None:
        ax.set_title(title, color='blue')
    return fig
//  [python]
def plot_model_risk_var(risk_var: Union[pd.Series, pd.DataFrame],
                        xvar_format: str = '{:.2f}',
                        yvar_format: str = '{:.2f}',
                        x_rotation: int = 0,
                        xlabel: str = 'log-return',
                        ylabel: str = 'probability',
                        title: str = None,
                        ax: plt.Subplot = None
                        ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    if isinstance(risk_var, pd.Series):  # optimise for frame
        risk_var = risk_var.to_frame()

    if len(risk_var.columns) == 1:
        palette = ['black']
    else:
        palette = None

    sns.tsplot(data=risk_var, palette=palette, dashes=False, ax=ax)

    if len(risk_var.columns) == 1:
        ax.legend().set_visible(False)
        # ax.axes.get_yaxis().set_visible(False)
    else:
        ax.legend(loc='upper left', framealpha=0)
        get_legend_colors(ax)

    ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: xvar_format.format(z)))
    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]

    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)

    if title is not None:
        ax.set_title(title)

    return fig
//  [python]
def plot_model_risk_var(risk_var: Union[pd.Series, pd.DataFrame],
                        xvar_format: str = '{:.2f}',
                        yvar_format: str = '{:.2f}',
                        x_rotation: int = 0,
                        xlabel: str = 'log-return',
                        ylabel: str = 'probability',
                        title: str = None,
                        ax: plt.Subplot = None
                        ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    if isinstance(risk_var, pd.Series):  # optimise for frame
        risk_var = risk_var.to_frame()

    if len(risk_var.columns) == 1:
        palette = ['black']
    else:
        palette = None

    sns.lineplot(data=risk_var, palette=palette, dashes=False, ax=ax)

    if len(risk_var.columns) == 1:
        ax.legend().set_visible(False)
        # ax.axes.get_yaxis().set_visible(False)
    else:
        ax.legend(loc='upper left', framealpha=0)
        get_legend_colors(ax)

    ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: xvar_format.format(z)))
    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]

    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)

    if title is not None:
        ax.set_title(title)

    return fig
//  [python]
def model_vols_ts(model_vols: Union[pd.Series, pd.DataFrame],
                  is_delta_space: bool = False,
                  xvar_format: str = '{:0,.0f}',
                  yvar_format: str = '{:.0%}',
                  x_rotation: int = 0,
                  xlabel: str = 'strike',
                  n_tickwindow: int = None,
                  marker: str = None,
                  title: str = None,
                  fontsize: int = 10,
                  legend_loc: str = 'upper center',
                  ax: plt.Subplot = None,
                  **kwargs
                  ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    if is_delta_space:
        model_vols.index = map_deltas_to_str(bsm_deltas=model_vols.index.to_numpy())

    s.lineplot(data=model_vols, dashes=False,
                 marker=marker,
                 ax=ax)

    if is_delta_space:
        yvar_format = '{:,.2f}'

    ax.legend(loc=legend_loc, fontsize=fontsize, framealpha=0)
    get_legend_colors(ax)

    if not isinstance(model_vols.index.dtype, str):  # do not apply for str
        ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: xvar_format.format(z)))
    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    if n_tickwindow is not None:
        if n_tickwindow == 5:
            ax.set_xticks(ax.get_xticks()[::n_tickwindow])
        else:
            this = ax.get_xticks()
            ax.set_xticks([this[0]] + this[1:-1][::n_tickwindow]+[this[-1]])

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]

    if title is not None:
        ax.set_title(title, fontsize=fontsize)

    ax.set_xlabel(xlabel)

    return fig
//  [python]
def model_vols_ts(model_vols: Union[pd.Series, pd.DataFrame],
                  is_delta_space: bool = False,
                  xvar_format: str = '{:0,.0f}',
                  yvar_format: str = '{:.0%}',
                  x_rotation: int = 0,
                  xlabel: str = 'strike',
                  n_tickwindow: int = None,
                  marker: str = None,
                  title: str = None,
                  fontsize: int = 10,
                  legend_loc: str = 'upper center',
                  ax: plt.Subplot = None,
                  **kwargs
                  ) -> plt.Figure:
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    else:
        fig = None

    if is_delta_space:
        model_vols.index = map_deltas_to_str(bsm_deltas=model_vols.index.to_numpy())

    sns.lineplot(data=model_vols, dashes=False,
                 marker=marker,
                 ax=ax)

    if is_delta_space:
        yvar_format = '{:,.2f}'

    ax.legend(loc=legend_loc, fontsize=fontsize, framealpha=0)
    get_legend_colors(ax)

    if not isinstance(model_vols.index.dtype, str):  # do not apply for str
        ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: xvar_format.format(z)))
    ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda z, _: yvar_format.format(z)))

    if n_tickwindow is not None:
        if n_tickwindow == 5:
            ax.set_xticks(ax.get_xticks()[::n_tickwindow])
        else:
            this = ax.get_xticks()
            ax.set_xticks([this[0]] + this[1:-1][::n_tickwindow]+[this[-1]])

    if x_rotation != 0:
        [tick.set_rotation(x_rotation) for tick in ax.get_xticklabels()]

    if title is not None:
        ax.set_title(title, fontsize=fontsize)

    ax.set_xlabel(xlabel)

    return fig
//  [python]
ord2num = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 5.46}
bleu["x"] = bleu["data_ord"].apply(lambda x: ord2num[x])

plt.ion()
fig, ax = plt.subplots(1, 1)
g = sns.tsplot(x="x", y="bleu", hue="direction", data=bleu, legend="brief", condition="train", err_style="ci_band", marker=["o","o"], linestyles=["--","-"], ci=[68])
//  [python]
ord2num = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 5.46}
bleu["x"] = bleu["data_ord"].apply(lambda x: ord2num[x])

plt.ion()
fig, ax = plt.subplots(1, 1)
g = sns.lineplot(x="x", y="bleu", hue="direction", data=bleu, legend="brief", style="train", markers=["o","o"], dashes=[(2,1),""])
//  [python]
def analyze(self):
        self.find_best_run()
        for field in ["total reward", "length", "crashed", "speed", "distance"]:
            logging.info("Analyzing {}".format(field))
            fig, ax = plt.subplots()
            sns.tsplot(x="episode", y=field, hue="agent", data=self.data, ax=ax, ci=95)
            field_path = self.out / "{}.pdf".format(field)
            fig.savefig(field_path, bbox_inches='tight')
            plt.show()
            plt.close()
//  [python]
def analyze(self):
        self.find_best_run()
        for field in ["total reward", "length", "crashed", "speed", "distance"]:
            logging.info("Analyzing {}".format(field))
            fig, ax = plt.subplots()
            sns.lineplot(x="episode", y=field, hue="agent", data=self.data, ax=ax, ci=95)
            field_path = self.out / "{}.pdf".format(field)
            fig.savefig(field_path, bbox_inches='tight')
            plt.show()
            plt.close()
//  [python]
def lineplots(df, y, x, col, row,
              hue=None,
              style=None, filename=None, y_lim=None,
              df_horizontal=None,
              y_log=False, show=True):
    num_cols = len(df[col].unique())

    num_rows = len(df[row].unique())

    figsize = list(bundles.icml2022()['figure.figsize'])
    figsize[0] *= num_cols
    figsize[1] *= num_rows
    figsize = tuple(figsize)

    hue_order = None if hue is None else sorted(df[hue].unique())

    fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize)

    legend_row = -(-num_rows // 2) - 1

    if style:
        style_order = sorted(df[style].unique())
    else:
        style_order = None

    for i, (row_name, df_i) in enumerate(df.groupby(row)):
        for j, (col_name, df_ij) in enumerate(df_i.groupby(col)):
            ax = get_ax(axes, num_cols, num_rows, i, j)
            if isinstance(y, list):
                y_0, y_1 = y
            else:
                y_0 = y
            _ = s.lineplot(data=df_ij,
                             x=x,
                             y=y_0,
                             hue=hue,
                             hue_order=hue_order,
                             style=style,
                             style_order=style_order,
                             ax=ax)

            if df_horizontal is not None:
                ax.axhline(df_horizontal.loc[row_name, y_0], color='black', linestyle='--')

            if isinstance(y, list):
                ax2 = ax.twinx()
                _ = s.lineplot(data=df_ij,
                                 x=x,
                                 y=y_1,
                                 hue=hue,
                                 hue_order=hue_order,
                                 style=style,
                                 style_order=style_order,
                                 color='red',
                                 ax=ax2)

            ax.set_title(f"{row_name} - {col_name}")
            if y_log:
                ax.set_yscale("log")
                if isinstance(y, list):
                    ax2.set_yscale('log')

            if j == 0:
                if y_lim is None:
                    y_lim_ = ax.get_ylim()
                    diff = (y_lim_[1] - y_lim_[0]) * 0.15
                    y_lim_ = (y_lim_[0] - diff, y_lim_[1] + diff)
                else:
                    y_lim_ = y_lim

            ax.set_ylim(y_lim_)
            if isinstance(y, list):
                ax2.set_ylim(y_lim_)

            if i == legend_row and j == (num_cols - 1) and hue is not None:
                l = ax.legend(loc='center right', bbox_to_anchor=(1.4, 0.5), ncol=1)
                l.set_title(pb_str.capitalize_words(hue))
            elif hue is not None:
                ax.legend().remove()

            ax.grid(True)
            if isinstance(y, list):
                ax2.grid(True)

        # g.set(yscale='log')
        fig.suptitle(f"Rows: {row} - Cols: {col}")

    # Add a legend to the last axis
    if filename is not None:
        fig.savefig(filename)
    if show: plt.show()
//  [python]
def lineplots(df, y, x, col, row,
              hue=None,
              style=None, filename=None, y_lim=None,
              df_horizontal=None,
              y_log=False, show=True):
    num_cols = len(df[col].unique())

    num_rows = len(df[row].unique())

    figsize = list(bundles.icml2022()['figure.figsize'])
    figsize[0] *= num_cols
    figsize[1] *= num_rows
    figsize = tuple(figsize)

    hue_order = None if hue is None else sorted(df[hue].unique())

    fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize)

    legend_row = -(-num_rows // 2) - 1

    if style:
        style_order = sorted(df[style].unique())
    else:
        style_order = None

    for i, (row_name, df_i) in enumerate(df.groupby(row)):
        for j, (col_name, df_ij) in enumerate(df_i.groupby(col)):
            ax = get_ax(axes, num_cols, num_rows, i, j)
            if isinstance(y, list):
                y_0, y_1 = y
            else:
                y_0 = y
            _ = sns.lineplot(data=df_ij,
                             x=x,
                             y=y_0,
                             hue=hue,
                             hue_order=hue_order,
                             style=style,
                             style_order=style_order,
                             ax=ax)

            if df_horizontal is not None:
                ax.axhline(df_horizontal.loc[row_name, y_0], color='black', linestyle='--')

            if isinstance(y, list):
                ax2 = ax.twinx()
                _ = sns.lineplot(data=df_ij,
                                 x=x,
                                 y=y_1,
                                 hue=hue,
                                 hue_order=hue_order,
                                 style=style,
                                 style_order=style_order,
                                 color='red',
                                 ax=ax2)

            ax.set_title(f"{row_name} - {col_name}")
            if y_log:
                ax.set_yscale("log")
                if isinstance(y, list):
                    ax2.set_yscale('log')

            if j == 0:
                if y_lim is None:
                    y_lim_ = ax.get_ylim()
                    diff = (y_lim_[1] - y_lim_[0]) * 0.15
                    y_lim_ = (y_lim_[0] - diff, y_lim_[1] + diff)
                else:
                    y_lim_ = y_lim

            ax.set_ylim(y_lim_)
            if isinstance(y, list):
                ax2.set_ylim(y_lim_)

            if i == legend_row and j == (num_cols - 1) and hue is not None:
                l = ax.legend(loc='center right', bbox_to_anchor=(1.4, 0.5), ncol=1)
                l.set_title(pb_str.capitalize_words(hue))
            elif hue is not None:
                ax.legend().remove()

            ax.grid(True)
            if isinstance(y, list):
                ax2.grid(True)

        # g.set(yscale='log')
        fig.suptitle(f"Rows: {row} - Cols: {col}")

    # Add a legend to the last axis
    if filename is not None:
        fig.savefig(filename)
    if show: plt.show()
//  [python]
def log_plot(epoches, tags, save_fig_dir, csv_save_path=None):
    """
    :param epoches:迭代次数
    :param tags:[loss,acc,precision,recall,f1]
    :param save_fig_path:保存路径
    """
    df = df_generator(epoches, tags, save_path=csv_save_path)
    sns.set_style("whitegrid")
    indicators = list(df.columns[2:])
    data = df.to_numpy()[:, 2:]
    index = list(df.index)
    df_ = pd.DataFrame(data=data,index=index,columns=indicators)
    plt.rc('font', family='Times New Roman', size=14)
    plt.figure(dpi=300,figsize=(4,3))
    plt.xlabel("Epoch")
    plt.ylabel("Indicator")
    sns.tsplot(data=df_.T, time=df_.index, err_style="band", ci=[68,95])
    plt.savefig(save_fig_dir + '/indicators.svg')

    plt.figure(dpi=300,figsize=(4,3))
    sns.tsplot(data=df['Loss'], time=df.index, err_style="band", ci=[68,95])
    plt.savefig(save_fig_dir + '/loss_epoch.svg')
    #------------------------------------
    """
    子图代码
    """
//  [python]
def log_plot(epoches, tags, save_fig_dir, csv_save_path=None):
    """
    :param epoches:迭代次数
    :param tags:[loss,acc,precision,recall,f1]
    :param save_fig_path:保存路径
    """
    df = df_generator(epoches, tags, save_path=csv_save_path)
    sns.set_style("whitegrid")
    indicators = list(df.columns[2:])
    data = df.to_numpy()[:, 2:]
    index = list(df.index)
    df_ = pd.DataFrame(data=data,index=index,columns=indicators)
    plt.rc('font', family='Times New Roman', size=14)
    plt.figure(dpi=300,figsize=(4,3))
    plt.xlabel("Epoch")
    plt.ylabel("Indicator")
    sns.lineplot(data=df_, markers=True)
    plt.savefig(save_fig_dir + '/indicators.svg')

    plt.figure(dpi=300,figsize=(4,3))
    sns.lineplot(data=df,y='Loss',x="Epoch")
    plt.savefig(save_fig_dir + '/loss_epoch.svg')
    #------------------------------------
    """
    子图代码
    """
//  [python]
main_ax = wb.get_main_ax()
main_ax.set_axis_off()
main_ax.pcolormesh(Z, cmap="Greens")

x1_ax = wb.get_ax("x1")
s.lineplot(x=np.arange(len(zy)), y=zy,
             ax=x1_ax, color="b", alpha=.7)
//  [python]
main_ax = wb.get_main_ax()
main_ax.set_axis_off()
main_ax.pcolormesh(Z, cmap="Greens")

x1_ax = wb.get_ax("x1")
sns.lineplot(x=np.arange(len(zy)), y=zy,
             ax=x1_ax, color="b", alpha=.7)
//  [python]
def plot_compression_ratio(data, y, hue_order, style_order, style, hue, output):
    fig, ax = plt.subplots(dpi=DPI, figsize=FIGSIZE)
    sns.pointplot(
        data=data,
        x=X,
        y=y,
        hue=hue,
        hue_order=hue_order,
        style=style,
        style_order=style_order,
        palette=PALETTE,
        markers=True,
        ax=ax,
        dashes=DASHES,
        mec=MEC,
        err_kws=ERR_KWS,
    )
    xticks = list(range(1, 20))
    _ = ax.set_xticks(xticks)

    ax.set_ylabel("Compression ratio")
    ax.yaxis.set_major_formatter(PercentFormatter(1.0, decimals=0))

    leg = ax.legend(
        loc="center right", framealpha=1, frameon=True, markerscale=MARKERSCALE
    )
    # change the line width for the legend
    for line in leg.get_lines():
        line.set_linewidth(LEG_LW)

    for tool, lvl in DEFAULT_LVL.items():
        for t in set(data["technology"]):
            mean = data.query("tool==@tool and level==@lvl and technology==@t")[
                "compress_ratio"
            ].mean()
            ax.scatter(lvl, mean, s=110, fc="None", ec="red")

    fig.savefig(output)
//  [python]
def plot_compression_ratio(data, y, hue_order, style_order, style, hue, output):
    fig, ax = plt.subplots(dpi=DPI, figsize=FIGSIZE)
    sns.lineplot(
        data=data,
        x=X,
        y=y,
        hue=hue,
        hue_order=hue_order,
        style=style,
        style_order=style_order,
        palette=PALETTE,
        markers=True,
        ax=ax,
        dashes=DASHES,
        mec=MEC,
        err_kws=ERR_KWS,
    )
    xticks = list(range(1, 20))
    _ = ax.set_xticks(xticks)

    ax.set_ylabel("Compression ratio")
    ax.yaxis.set_major_formatter(PercentFormatter(1.0, decimals=0))

    leg = ax.legend(
        loc="center right", framealpha=1, frameon=True, markerscale=MARKERSCALE
    )
    # change the line width for the legend
    for line in leg.get_lines():
        line.set_linewidth(LEG_LW)

    for tool, lvl in DEFAULT_LVL.items():
        for t in set(data["technology"]):
            mean = data.query("tool==@tool and level==@lvl and technology==@t")[
                "compress_ratio"
            ].mean()
            ax.scatter(lvl, mean, s=110, fc="None", ec="red")

    fig.savefig(output)
//  [python]
def ts_plot(data, cols, title, output_folder, name, labels=None, subtitles=None, ylabel=None):
    plot_height = 3
    plot_width = 10
    import matplotlib.pyplot as plt
    import seaborn as sns
    sns.set(font_scale=1.2)
    fig, axes = plt.subplots(len(cols), 1, figsize=(plot_width, len(cols)*plot_height))
    for i in range(0, len(cols)):
        if len(cols) == 1:
            ax = axes
        else:
            ax = axes[i]
        if isinstance(cols[i], list):
            # multiple lines
            for j in range(0, len(cols[i])):
                sns.tsplot(data=data, time=TIMESTAMP_COL, value=cols[i][j], ax=ax, label=labels[j])
            ax.set_title(subtitles[i])
        else:
            sns.tsplot(data=data, time=TIMESTAMP_COL, value=cols[i], ax=ax)
            ax.set_title(cols[i])
        if ylabel is not None:
            ax.set_ylabel(ylabel)
    plt.suptitle(title, x=0.5, y=0.99)
    plt.tight_layout()
    filename = os.path.join(output_folder, name + ".png")
    fig.savefig(filename)
    plt.close()
//  [python]
def ts_plot(data, cols, title, output_folder, name, labels=None, subtitles=None, ylabel=None):
    plot_height = 3
    plot_width = 10
    import matplotlib.pyplot as plt
    import seaborn as sns
    sns.set(font_scale=1.2)
    fig, axes = plt.subplots(len(cols), 1, figsize=(plot_width, len(cols)*plot_height))
    for i in range(0, len(cols)):
        if len(cols) == 1:
            ax = axes
        else:
            ax = axes[i]
        if isinstance(cols[i], list):
            # multiple lines
            for j in range(0, len(cols[i])):
                sns.lineplot(data=data, x=TIMESTAMP_COL, y=cols[i][j], ax=ax, label=labels[j])
            ax.set_title(subtitles[i])
        else:
            sns.lineplot(data=data, x=TIMESTAMP_COL, y=cols[i], ax=ax)
            ax.set_title(cols[i])
        if ylabel is not None:
            ax.set_ylabel(ylabel)
    plt.suptitle(title, x=0.5, y=0.99)
    plt.tight_layout()
    filename = os.path.join(output_folder, name + ".png")
    fig.savefig(filename)
    plt.close()
//  [python]
def plot_rate_and_memory(ys, data, hue, hue_order, style, style_order, output):
    fig, axes = plt.subplots(
        nrows=2,
        ncols=2,
        dpi=DPI,
        figsize=(10, 10),
        sharex=True,
        sharey="row",
        tight_layout=True,
    )

    for i, (y, ax) in enumerate(zip(ys, axes.flatten())):
        sns.pointplot(
            data=data,
            x=X,
            y=y,
            hue=hue,
            hue_order=hue_order,
            style=style,
            style_order=style_order,
            palette=PALETTE,
            markers=True,
            ax=ax,
            dashes=DASHES,
            mec=MEC,
            err_kws=ERR_KWS,
        )
        xticks = list(range(1, 20))
        _ = ax.set_xticks(xticks)

        if "rate" in y:
            ax.set_ylabel("Rate")
            ax.set_title(y.replace("_rate", "").capitalize())
            ax.set_yscale("log")
            KB = 1000
            MB = 1000 * KB
            yticks = [MB, 10 * MB, 25 * MB, 50 * MB, 100 * MB, 250 * MB, 500 * MB]
            ax.set_yticks(yticks)
            yticklabels = []
            for rate in yticks:
                rate, unit = format_size(rate).split()
                rate = round(float(rate))
                yticklabels.append(f"{rate} {unit}/s")

            ax.set_yticklabels(yticklabels)

            ax.legend(loc="upper right")

        else:
            ax.set_ylabel("Max. memory (MiB)")

        if y != "decompress_max_rss":
            ax.get_legend().remove()
        else:
            leg = ax.legend(loc="upper left", framealpha=1, frameon=True)
            # change the line width for the legend
            for line in leg.get_lines():
                line.set_linewidth(LEG_LW)

        for tool, lvl in DEFAULT_LVL.items():
            for t in set(data["technology"]):
                mean = data.query("tool==@tool and level==@lvl and technology==@t")[
                    y
                ].mean()
                ax.scatter(lvl, mean, s=110, fc="None", ec="red")

    fig.savefig(output)