jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def plot_loss_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(y="loss",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Loss')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_loss_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="loss",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Loss')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_loss_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(time="num_grad_steps",
                 value="loss",
                 unit="run_id",
                 condition="optimizer",
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Loss (Avg Across Runs)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps_by_optimizer.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_loss_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="loss",
                 x='num_grad_steps',
                 hue='optimizer',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Loss (Avg Across Runs)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps_by_optimizer.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def lineplot_elo_vs_days(filename):
    print("reading csv...")
    df = pd.read_csv("query_out_storage/total_blitz_games_per_player_over_time.csv")
    print("converting days since start...")
    df["days_since_start"] = df["days_since_start"].apply(lambda x: int(re.search(r'\d+', x).group(0)))
    df_starting_elo = df[df["days_since_start"] == 0]
    #assign rating bands to players
    for lower_elo_lim in range(800,2201,200):
        upper_elo_lim = lower_elo_lim + 199
        df_band = df_starting_elo[(df_starting_elo["min"] >= lower_elo_lim) & (df_starting_elo["min"] <= upper_elo_lim)]
        df.loc[df["player"].isin(df_band["player"]), "band"] = f"{lower_elo_lim} - {upper_elo_lim}"
    df = df.dropna()    #drop extreme elo values (600-800 and 2400+) due to low sample size
    print("plotting...")
    ax = sns.tsplot(x="days_since_start", y="min", unit="player", condition="band", data=df)
    box = ax.get_position()
    ax.set_position([box.x0, box.y0,box.width*.8, box.height])
    handles, labels = ax.get_legend_handles_labels()
    labels, handles = zip(*sorted(zip(labels, handles), key=lambda x: int(x[0][0:4])))  #sort by elo number instead of str
    ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1,.5), title="starting elo")
    ax.set_xlabel("days since player's first stable rating")
    ax.set_ylabel('stable elo rating')
    ax.set_title('elo rating over time (95% confidence interval)')
    fig = ax.get_figure()
    print("saving figure...")
    fig.savefig(filename, dpi=300)
//  [python]
def lineplot_elo_vs_days(filename):
    print("reading csv...")
    df = pd.read_csv("query_out_storage/total_blitz_games_per_player_over_time.csv")
    print("converting days since start...")
    df["days_since_start"] = df["days_since_start"].apply(lambda x: int(re.search(r'\d+', x).group(0)))
    df_starting_elo = df[df["days_since_start"] == 0]
    #assign rating bands to players
    for lower_elo_lim in range(800,2201,200):
        upper_elo_lim = lower_elo_lim + 199
        df_band = df_starting_elo[(df_starting_elo["min"] >= lower_elo_lim) & (df_starting_elo["min"] <= upper_elo_lim)]
        df.loc[df["player"].isin(df_band["player"]), "band"] = f"{lower_elo_lim} - {upper_elo_lim}"
    df = df.dropna()    #drop extreme elo values (600-800 and 2400+) due to low sample size
    print("plotting...")
    ax = sns.lineplot(x="days_since_start", y="min", hue="band", data=df)
    box = ax.get_position()
    ax.set_position([box.x0, box.y0,box.width*.8, box.height])
    handles, labels = ax.get_legend_handles_labels()
    labels, handles = zip(*sorted(zip(labels, handles), key=lambda x: int(x[0][0:4])))  #sort by elo number instead of str
    ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1,.5), title="starting elo")
    ax.set_xlabel("days since player's first stable rating")
    ax.set_ylabel('stable elo rating')
    ax.set_title('elo rating over time (95% confidence interval)')
    fig = ax.get_figure()
    print("saving figure...")
    fig.savefig(filename, dpi=300)
//  [python]
def plot_grid_score_max_as_lines_vs_place_cell_rf(max_grid_scores_by_run_id_df: pd.DataFrame,
                                                  plot_dir: str):
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)
    ax = axes[0]
    sns.pointplot(y="score_60_by_neuron_max",
                 x='place_cell_rf',
                 data=max_grid_scores_by_run_id_df,
                 ax=ax)
    ax.set_ylabel(f'Max Grid Score (Avg Across Runs)')
    ax.set_xlabel(r'$\sigma$')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.pointplot(y="score_90_by_neuron_max",
                 x='place_cell_rf',
                 data=max_grid_scores_by_run_id_df,
                 ax=ax,
                 )
    # ax.set_ylabel(None)
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel(r'$\sigma$')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'grid_score_max_as_lines_vs_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_grid_score_max_as_lines_vs_place_cell_rf(max_grid_scores_by_run_id_df: pd.DataFrame,
                                                  plot_dir: str):
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)
    ax = axes[0]
    sns.lineplot(y="score_60_by_neuron_max",
                 x='place_cell_rf',
                 data=max_grid_scores_by_run_id_df,
                 ax=ax)
    ax.set_ylabel(f'Max Grid Score (Avg Across Runs)')
    ax.set_xlabel(r'$\sigma$')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.lineplot(y="score_90_by_neuron_max",
                 x='place_cell_rf',
                 data=max_grid_scores_by_run_id_df,
                 ax=ax,
                 )
    # ax.set_ylabel(None)
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel(r'$\sigma$')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'grid_score_max_as_lines_vs_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_loss_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(time="num_grad_steps",
                 value="loss",
                 unit="run_id",
                 condition='place_cell_rf',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Loss')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps_by_place_cell_rf.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_loss_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="loss",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 legend="full")
    plt.ylabel(f'Loss')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'loss_vs_num_grad_steps_by_place_cell_rf.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_max_grid_score_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.pointplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 )
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.pointplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax)
    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_max_grid_score_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.lineplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 )
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.lineplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax)
    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_participation_ratio_by_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(y="participation_ratio",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Participation Ratio')
    plt.xlabel('Num Grad Steps')

    plot_path = os.path.join(plot_dir,
                             f'participation_ratio_by_num_grad_steps.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_participation_ratio_by_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="participation_ratio",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Participation Ratio')
    plt.xlabel('Num Grad Steps')

    plot_path = os.path.join(plot_dir,
                             f'participation_ratio_by_num_grad_steps.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(y="pos_decoding_err",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Pos Decoding Error (cm)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="pos_decoding_err",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Pos Decoding Error (cm)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_max_grid_score_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str,
        grid_score_d60_threshold: int = 1.2,
        grid_score_d90_threshold: int = 1.5):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.pointplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 hue='optimizer',
                 join=True,
                 ci=None,
                 )
    ax.set_ylabel(f'Max Grid Score (Max Across Runs)')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')
    ax.axhline(y=grid_score_d60_threshold,
               label='Likely Hexagonal Lattices',
               color='r')

    ax = axes[1]
    sns.pointplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 hue='optimizer',
                 join=True,
                 ci=None,
                 ax=ax)

    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    ax.axhline(y=grid_score_d90_threshold,
               label='Likely Square Lattices',
               color='r')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps_by_optimizer.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_max_grid_score_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str,
        grid_score_d60_threshold: int = 1.2,
        grid_score_d90_threshold: int = 1.5):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.lineplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 hue='optimizer',
                 estimator='max',
                 ci=None,
                 )
    ax.set_ylabel(f'Max Grid Score (Max Across Runs)')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')
    ax.axhline(y=grid_score_d60_threshold,
               label='Likely Hexagonal Lattices',
               color='r')

    ax = axes[1]
    sns.lineplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 data=runs_augmented_histories_df,
                 hue='optimizer',
                 estimator='max',
                 ci=None,
                 ax=ax)

    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    ax.axhline(y=grid_score_d90_threshold,
               label='Likely Square Lattices',
               color='r')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps_by_optimizer.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_pos_decoding_err_over_min_pos_decoding_err_vs_epoch_by_run_id(
        runs_histories_df: pd.DataFrame,
        plot_dir: str):
    plt.close()
    sns.tsplot(
        data=runs_histories_df,
        time='_step',
        value='pos_decoding_err_over_min_pos_decoding_err',
        unit='run_id',
        legend=False,
        linewidth=1.5,
    )

    plt.yscale('log')
    plt.ylabel('Pos Decoding Err / Min(Pos Decoding Err)')
    plt.xlabel('Epoch')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_err_over_min_pos_decoding_err_vs_epoch_by_run_id.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_pos_decoding_err_over_min_pos_decoding_err_vs_epoch_by_run_id(
        runs_histories_df: pd.DataFrame,
        plot_dir: str):
    plt.close()
    sns.lineplot(
        data=runs_histories_df,
        x='_step',
        y='pos_decoding_err_over_min_pos_decoding_err',
        hue='run_id',
        legend=False,
        linewidth=1.5,
    )

    plt.yscale('log')
    plt.ylabel('Pos Decoding Err / Min(Pos Decoding Err)')
    plt.xlabel('Epoch')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_err_over_min_pos_decoding_err_vs_epoch_by_run_id.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_percent_runs_with_grid_cells_vs_grid_score_threshold(
        runs_configs_with_scores_max_df: pd.DataFrame,
        plot_dir: str):
    thresholds = np.linspace(0.35, 1.15, 150)
    percent_runs_above_threshold = np.zeros_like(thresholds)
    for threshold_idx, threshold in enumerate(thresholds):
        percent_runs_above_threshold[threshold_idx] = 100 * (
                runs_configs_with_scores_max_df['score_60_by_neuron_max'] > threshold).mean()

    y_label = f'% Runs with (Possible) Grid Cells (N={len(runs_configs_with_scores_max_df)})'
    plot_df = pd.DataFrame.from_dict({
        'Grid Score Threshold': thresholds,
        y_label: percent_runs_above_threshold
    })

    plt.close()
    plt.plot(plot_df['Grid Score Threshold'], plot_df[y_label])
    plt.ylim(0, 100)

    plot_path = os.path.join(plot_dir, f'percent_runs_with_grid_cells_vs_grid_score_threshold.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_percent_runs_with_grid_cells_vs_grid_score_threshold(
        runs_configs_with_scores_max_df: pd.DataFrame,
        plot_dir: str):
    thresholds = np.linspace(0.35, 1.15, 150)
    percent_runs_above_threshold = np.zeros_like(thresholds)
    for threshold_idx, threshold in enumerate(thresholds):
        percent_runs_above_threshold[threshold_idx] = 100 * (
                runs_configs_with_scores_max_df['score_60_by_neuron_max'] > threshold).mean()

    y_label = f'% Runs with (Possible) Grid Cells (N={len(runs_configs_with_scores_max_df)})'
    plot_df = pd.DataFrame.from_dict({
        'Grid Score Threshold': thresholds,
        y_label: percent_runs_above_threshold
    })

    plt.close()
    sns.lineplot(
        data=plot_df,
        x='Grid Score Threshold',
        y=y_label)
    plt.ylim(0, 100)

    plot_path = os.path.join(plot_dir, f'percent_runs_with_grid_cells_vs_grid_score_threshold.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_percent_grid_cells_vs_place_cell_rf_by_threshold(
        augmented_percent_neurons_score60_above_threshold_by_run_id_df: pd.DataFrame,
        plot_dir: str):
    """
    Plot percent of units (aggregating across all runs) with a 60d grid score
    above a threshold (Y) against place cell RF (X). Each threshold is plotted
    as a trace in a different hue.
    """
    plt.close()
    g = sns.pointplot(
        data=augmented_percent_neurons_score60_above_threshold_by_run_id_df,
        x='place_cell_rf',
        y='Percent',
        hue='Grid Score Threshold',
        join=True,
        ci=None
    )
    g.legend(
        title='Grid Score Threshold',  # For some reason, the legend title disappears, so add it manually.
        bbox_to_anchor=(1, 0.5),  # 1 on the x axis, 0.5 on the y axis
        loc='center left',  # Legend goes center-left of anchor
    )

    plt.xlabel(r'$\sigma$ (m)')
    plt.ylabel('% Grid Cells')

    plot_path = os.path.join(plot_dir,
                             f'percent_grid_cells_vs_place_cell_rf_by_threshold.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_percent_grid_cells_vs_place_cell_rf_by_threshold(
        augmented_percent_neurons_score60_above_threshold_by_run_id_df: pd.DataFrame,
        plot_dir: str):
    """
    Plot percent of units (aggregating across all runs) with a 60d grid score
    above a threshold (Y) against place cell RF (X). Each threshold is plotted
    as a trace in a different hue.
    """
    plt.close()
    g = sns.lineplot(
        data=augmented_percent_neurons_score60_above_threshold_by_run_id_df,
        x='place_cell_rf',
        y='Percent',
        hue='Grid Score Threshold',
    )
    g.legend(
        title='Grid Score Threshold',  # For some reason, the legend title disappears, so add it manually.
        bbox_to_anchor=(1, 0.5),  # 1 on the x axis, 0.5 on the y axis
        loc='center left',  # Legend goes center-left of anchor
    )

    plt.xlabel(r'$\sigma$ (m)')
    plt.ylabel('% Grid Cells')

    plot_path = os.path.join(plot_dir,
                             f'percent_grid_cells_vs_place_cell_rf_by_threshold.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_max_grid_score_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.pointplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 legend="full"
                 )
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.pointplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 legend="full",
                 ax=ax)
    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps_by_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_max_grid_score_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(24, 8),
                             sharey=True, sharex=True)

    ax = axes[0]
    sns.lineplot(y="score_60_by_neuron_max",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 ax=ax,
                 legend="full"
                 )
    ax.set_ylabel(f'Max Grid Score')
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$60^{\circ}$')

    ax = axes[1]
    sns.lineplot(y="score_90_by_neuron_max",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 legend="full",
                 ax=ax)
    ax.set_ylabel(None)  # Use ylabel from left plot
    ax.set_xlabel('Num Grad Steps')
    ax.set_title(r'$90^{\circ}$')
    plot_path = os.path.join(plot_dir,
                             f'max_grid_score_vs_num_grad_steps_by_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(time="num_grad_steps",
                 value="pos_decoding_err",
                 unit="run_id",
                 condition='optimizer',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Pos Decoding Error (cm)\n(Avg Across Runs)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps_by_optimizer.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps_by_optimizer(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="pos_decoding_err",
                 x='num_grad_steps',
                 hue='optimizer',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Pos Decoding Error (cm)\n(Avg Across Runs)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plt.savefig(os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps_by_optimizer.png'),
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.tsplot(time='num_grad_steps',
                 value="pos_decoding_err",
                 unit='run_id',
                 condition='place_cell_rf',
                 data=runs_augmented_histories_df)
    plt.ylabel(f'Pos Decoding Error (cm)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plot_path = os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps_by_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def plot_pos_decoding_err_vs_num_grad_steps_by_place_cell_rf(
        runs_augmented_histories_df: pd.DataFrame,
        plot_dir: str, ):
    plt.close()
    sns.lineplot(y="pos_decoding_err",
                 x='num_grad_steps',
                 hue='place_cell_rf',
                 data=runs_augmented_histories_df,
                 legend="full")
    plt.ylabel(f'Pos Decoding Error (cm)')
    plt.yscale('log')
    plt.xlabel('Num Grad Steps')

    plot_path = os.path.join(plot_dir,
                             f'pos_decoding_error_vs_num_grad_steps_by_place_cell_rf.png')
    plt.savefig(plot_path,
                bbox_inches='tight',
                dpi=300)
    # plt.show()
    plt.close()
    print(f'Plotted {plot_path}')
//  [python]
def timeplot(self, locator: str = "month",
                 interval: int = 1, **kwargs: Dict) -> Any:
        df = self.duration.get_dataframe()
        ax = sns.tsplot(
            data=df,
            time=self.duration.column_start,
            value=Durations.COLUMN_STAY_DURATION,
            lw=0.8,
            **kwargs
        )
        plt.axhline(df.mean(numeric_only=True)[Durations.COLUMN_STAY_DURATION],
                    color="black", linestyle="--", lw=0.8, label="Mean")
        loc = mdates.MonthLocator(interval=interval)
        formatter = mdates.DateFormatter(fmt="%b %Y")
        if locator == "day":
            loc = mdates.DayLocator(interval=interval)
            formatter = mdates.DateFormatter(fmt="%d %b %Y")
        ax.xaxis.set_major_locator(loc)
        ax.xaxis.set_major_formatter(formatter)
        ax.figure.autofmt_xdate(rotation=90, ha='center')
        sns.despine()
        plt.ylabel("Stay (in days)")
        plt.xlabel("Start date")
        plt.legend()
        return ax
//  [python]
def timeplot(self, locator: str = "month",
                 interval: int = 1, **kwargs: Dict) -> Any:
        df = self.duration.get_dataframe()
        ax = sns.lineplot(
            data=df,
            x=self.duration.column_start,
            y=Durations.COLUMN_STAY_DURATION,
            lw=0.8,
            **kwargs
        )
        plt.axhline(df.mean(numeric_only=True)[Durations.COLUMN_STAY_DURATION],
                    color="black", linestyle="--", lw=0.8, label="Mean")
        loc = mdates.MonthLocator(interval=interval)
        formatter = mdates.DateFormatter(fmt="%b %Y")
        if locator == "day":
            loc = mdates.DayLocator(interval=interval)
            formatter = mdates.DateFormatter(fmt="%d %b %Y")
        ax.xaxis.set_major_locator(loc)
        ax.xaxis.set_major_formatter(formatter)
        ax.figure.autofmt_xdate(rotation=90, ha='center')
        sns.despine()
        plt.ylabel("Stay (in days)")
        plt.xlabel("Start date")
        plt.legend()
        return ax
//  [python]
task.logger.report_matplotlib_figure(
    title="Manual Reporting",
    series="Image plot",
    iteration=0,
    figure=plt,
    report_interactive=False,
)
# Show plot
plt.show()

# Create Seaborn plot
sns.set(style="darkgrid")
# Load an example dataset with long-form data
fmri = sns.load_dataset("fmri")
# Plot the responses for different events and regions
sns.tsplot(time="timepoint", value="signal", unit="subject", condition="region", data=fmri)
//  [python]
task.logger.report_matplotlib_figure(
    title="Manual Reporting",
    series="Image plot",
    iteration=0,
    figure=plt,
    report_interactive=False,
)
# Show plot
plt.show()

# Create Seaborn plot
sns.set(style="darkgrid")
# Load an example dataset with long-form data
fmri = sns.load_dataset("fmri")
# Plot the responses for different events and regions
sns.lineplot(x="timepoint", y="signal", hue="region", style="event", data=fmri)
//  [python]
def plot_run(
    paths: List[str],
    name: str,
    ax=None,
    x_key: str = "steps",
    y_keys: List[str] = ["eval/loss"],
    window_size: int = 1,
    max_x_value: Optional[int] = None,
    **kwargs,
) -> None:
    for path in paths:
        assert LOG_FILE_NAME in os.listdir(path), "Did not find log file, found " + " ".join(os.listdir(path))
    for y_key in y_keys:
        xs, ys = [], []
        for path in paths:
            df = pd.read_csv(os.path.join(path, LOG_FILE_NAME))
            if y_key not in df:
                print("[research] WARNING: y_key was not in run, skipping plot", path)
                continue
            x, y = moving_avg(df[x_key], df[y_key], window_size=window_size)
            assert len(x) == len(y)
            if max_x_value is not None:
                y = y[x <= max_x_value]  # need to set y value first
                x = x[x <= max_x_value]
            xs.append(x)
            ys.append(y)
        if len(ys) == 0:
            print("[research], WARNING: had no runs for y_key", y_key, "skipping.")
            continue
        xs = np.concatenate(xs, axis=0)
        ys = np.concatenate(ys, axis=0)
        plot_df = pd.DataFrame({x_key: xs, y_key: ys})
        label = name + " " + y_key if len(y_keys) > 1 else name
        ci = "sd" if len(paths) > 0 else None
        sns.tsplot(ax=ax, x=x_key, y=y_key, data=plot_df, ci=ci, label=label, **kwargs)
//  [python]
def plot_run(
    paths: List[str],
    name: str,
    ax=None,
    x_key: str = "steps",
    y_keys: List[str] = ["eval/loss"],
    window_size: int = 1,
    max_x_value: Optional[int] = None,
    **kwargs,
) -> None:
    for path in paths:
        assert LOG_FILE_NAME in os.listdir(path), "Did not find log file, found " + " ".join(os.listdir(path))
    for y_key in y_keys:
        xs, ys = [], []
        for path in paths:
            df = pd.read_csv(os.path.join(path, LOG_FILE_NAME))
            if y_key not in df:
                print("[research] WARNING: y_key was not in run, skipping plot", path)
                continue
            x, y = moving_avg(df[x_key], df[y_key], window_size=window_size)
            assert len(x) == len(y)
            if max_x_value is not None:
                y = y[x <= max_x_value]  # need to set y value first
                x = x[x <= max_x_value]
            xs.append(x)
            ys.append(y)
        if len(ys) == 0:
            print("[research], WARNING: had no runs for y_key", y_key, "skipping.")
            continue
        xs = np.concatenate(xs, axis=0)
        ys = np.concatenate(ys, axis=0)
        plot_df = pd.DataFrame({x_key: xs, y_key: ys})
        label = name + " " + y_key if len(y_keys) > 1 else name
        ci = "sd" if len(paths) > 0 else None
        sns.lineplot(ax=ax, x=x_key, y=y_key, data=plot_df, sort=True, ci=ci, label=label, **kwargs)
//  [python]
def plot_loss_acc(path, num_epoch, train_accuracies_superclass, train_accuracies_subclass, train_losses,
                    test_accuracies_superclass, test_accuracies_subclass, test_losses):
    '''
    Plot line graphs for the accuracies and loss at every epochs for both training and testing.
    '''

    plt.clf()

    epochs = [x for x in range(num_epoch+1)]

    train_superclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":train_accuracies_superclass, "Mode":['train']*(num_epoch+1)})
    train_subclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":train_accuracies_subclass, "Mode":['train']*(num_epoch+1)})
    test_superclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":test_accuracies_superclass, "Mode":['test']*(num_epoch+1)})
    test_subclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":test_accuracies_subclass, "Mode":['test']*(num_epoch+1)})

    data_superclass = pd.concat([train_superclass_accuracy_df, test_superclass_accuracy_df])
    data_subclass = pd.concat([train_subclass_accuracy_df, test_subclass_accuracy_df])

    sns.tsplot(data=data_superclass, time='Epochs', value='Accuracy', unit="Mode")
    plt.title('Superclass Accuracy Graph')
    plt.savefig(path+f'accuracy_superclass_epoch.png')

    plt.clf()

    sns.tsplot(data=data_subclass, time='Epochs', value='Accuracy', unit="Mode")
    plt.title('Subclass Accuracy Graph')
    plt.savefig(path+f'accuracy_subclass_epoch.png')

    plt.clf()

    train_loss_df = pd.DataFrame({"Epochs":epochs, "Loss":train_losses, "Mode":['train']*(num_epoch+1)})
    test_loss_df = pd.DataFrame({"Epochs":epochs, "Loss":test_losses, "Mode":['test']*(num_epoch+1)})

    data = pd.concat([train_loss_df, test_loss_df])

    sns.tsplot(data=data, time='Epochs', value='Loss', unit="Mode")
    plt.title('Loss Graph')

    plt.savefig(path+f'loss_epoch.png')

    return None
//  [python]
def plot_loss_acc(path, num_epoch, train_accuracies_superclass, train_accuracies_subclass, train_losses,
                    test_accuracies_superclass, test_accuracies_subclass, test_losses):
    '''
    Plot line graphs for the accuracies and loss at every epochs for both training and testing.
    '''

    plt.clf()

    epochs = [x for x in range(num_epoch+1)]

    train_superclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":train_accuracies_superclass, "Mode":['train']*(num_epoch+1)})
    train_subclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":train_accuracies_subclass, "Mode":['train']*(num_epoch+1)})
    test_superclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":test_accuracies_superclass, "Mode":['test']*(num_epoch+1)})
    test_subclass_accuracy_df = pd.DataFrame({"Epochs":epochs, "Accuracy":test_accuracies_subclass, "Mode":['test']*(num_epoch+1)})

    data_superclass = pd.concat([train_superclass_accuracy_df, test_superclass_accuracy_df])
    data_subclass = pd.concat([train_subclass_accuracy_df, test_subclass_accuracy_df])

    sns.lineplot(data=data_superclass, x='Epochs', y='Accuracy', hue='Mode')
    plt.title('Superclass Accuracy Graph')
    plt.savefig(path+f'accuracy_superclass_epoch.png')

    plt.clf()

    sns.lineplot(data=data_subclass, x='Epochs', y='Accuracy', hue='Mode')
    plt.title('Subclass Accuracy Graph')
    plt.savefig(path+f'accuracy_subclass_epoch.png')

    plt.clf()

    train_loss_df = pd.DataFrame({"Epochs":epochs, "Loss":train_losses, "Mode":['train']*(num_epoch+1)})
    test_loss_df = pd.DataFrame({"Epochs":epochs, "Loss":test_losses, "Mode":['test']*(num_epoch+1)})

    data = pd.concat([train_loss_df, test_loss_df])

    sns.lineplot(data=data, x='Epochs', y='Loss', hue='Mode')
    plt.title('Loss Graph')

    plt.savefig(path+f'loss_epoch.png')

    return None
//  [python]
def plot2d_trajectories_samples(
        obs:  np.ndarray,
        gt:   np.ndarray,
        max_pos: np.ndarray,
        min_pos: np.ndarray) -> None:
    """plot 2d trajectories

    Args:
        obs (np.ndarray): (N_seqs, N_timesteps, [x, y])
        gt (np.ndarray): (N_seqs, N_timesteps, [x,y])
        pred (np.ndarray): (N_seqs, N_timesteps, N_trials, [x,y])
        img_path (Path): Path
    """

    N_seqs = len(gt)
    _, N_timesteps, N_dim = gt[0].shape

    f, ax = plt.subplots(1, 1)
    ax.set_aspect('equal', adjustable='box')
    ax.set_xlim(min_pos[0], max_pos[0])
    ax.set_ylim(min_pos[1], max_pos[1])

    for j in range(N_seqs):
        gt_vis = np.zeros([N_timesteps+1, N_dim])
        gt_vis[0] = obs[j][0, -1]
        gt_vis[1:] = gt[j][0]
        if j == 0:
            plt.plot(obs[j][0, :, 0], obs[j][0, :, 1], color='green',
                         marker='o', label="obs")
            plt.plot(gt_vis[:, 0], gt_vis[:, 1],
                         color='black', marker='o', label="GT")
        else:
            plt.plot(obs[j][0, :, 0], obs[j][0, :, 1], color='green',
                         marker='o')
            plt.plot(gt_vis[:, 0], gt_vis[:, 1],
                         color='black', marker='o')

    img_path = "gts.png"
    plt.axis('off')
    plt.savefig(img_path, bbox_inches='tight')
    plt.close()
//  [python]
def plot2d_trajectories_samples(
        obs:  np.ndarray,
        gt:   np.ndarray,
        max_pos: np.ndarray,
        min_pos: np.ndarray) -> None:
    """plot 2d trajectories

    Args:
        obs (np.ndarray): (N_seqs, N_timesteps, [x, y])
        gt (np.ndarray): (N_seqs, N_timesteps, [x,y])
        pred (np.ndarray): (N_seqs, N_timesteps, N_trials, [x,y])
        img_path (Path): Path
    """

    N_seqs = len(gt)
    _, N_timesteps, N_dim = gt[0].shape

    f, ax = plt.subplots(1, 1)
    ax.set_aspect('equal', adjustable='box')
    ax.set_xlim(min_pos[0], max_pos[0])
    ax.set_ylim(min_pos[1], max_pos[1])

    for j in range(N_seqs):
        gt_vis = np.zeros([N_timesteps+1, N_dim])
        gt_vis[0] = obs[j][0, -1]
        gt_vis[1:] = gt[j][0]
        if j == 0:
            sns.lineplot(x=obs[j][0, :, 0], y=obs[j][0, :, 1], color='green',
                         legend='brief', label="obs", marker='o')
            sns.lineplot(x=gt_vis[:, 0], y=gt_vis[:, 1],
                         color='black', legend='brief', label="GT", marker='o')
        else:
            sns.lineplot(x=obs[j][0, :, 0], y=obs[j][0, :, 1], color='green',
                         marker='o')
            sns.lineplot(x=gt_vis[:, 0], y=gt_vis[:, 1],
                         color='black', marker='o')

    img_path = "gts.png"
    plt.axis('off')
    plt.savefig(img_path, bbox_inches='tight')
    plt.close()
//  [python]
def plot_spread(df, ticker1, ticker2, idx, th, stop):

    px1 = df[ticker1].iloc[idx] / df[ticker1].iloc[idx[0]]
    px2 = df[ticker2].iloc[idx] / df[ticker2].iloc[idx[0]]

    sns.set(style='white')

    # Set plotting figure
    fig, ax = plt.subplots(2, 1, gridspec_kw={'height_ratios': [2, 1]})

    # Plot the 1st subplot
    ax[0].plot(px1, linewidth=1.2)
    ax[0].plot(px2, linewidth=1.2)
    ax[0].legend(loc='upper left')

    # Calculate the spread and other thresholds
    spread = df[ticker1].iloc[idx] - df[ticker2].iloc[idx]
    mean_spread = spread.mean()
    sell_th     = mean_spread + th
    buy_th      = mean_spread - th
    sell_stop   = mean_spread + stop
    buy_stop    = mean_spread - stop

    # Plot the 2nd subplot
    ax[1].plot(spread, color='#85929E', linewidth=1.2)
    ax[1].axhline(sell_th,   color='b', ls='--', linewidth=1, label='sell_th')
    ax[1].axhline(buy_th,    color='r', ls='--', linewidth=1, label='buy_th')
    ax[1].axhline(sell_stop, color='g', ls='--', linewidth=1, label='sell_stop')
    ax[1].axhline(buy_stop,  color='y', ls='--', linewidth=1, label='buy_stop')
    ax[1].fill_between(idx, sell_th, buy_th, facecolors='r', alpha=0.3)
    ax[1].legend(loc='upper left', labels=['Spread', 'sell_th', 'buy_th', 'sell_stop', 'buy_stop'], prop={'size':6.5})
//  [python]
def plot_spread(df, ticker1, ticker2, idx, th, stop):

    px1 = df[ticker1].iloc[idx] / df[ticker1].iloc[idx[0]]
    px2 = df[ticker2].iloc[idx] / df[ticker2].iloc[idx[0]]

    sns.set(style='white')

    # Set plotting figure
    fig, ax = plt.subplots(2, 1, gridspec_kw={'height_ratios': [2, 1]})

    # Plot the 1st subplot
    sns.lineplot(data=[px1, px2], linewidth=1.2, ax=ax[0])
    ax[0].legend(loc='upper left')

    # Calculate the spread and other thresholds
    spread = df[ticker1].iloc[idx] - df[ticker2].iloc[idx]
    mean_spread = spread.mean()
    sell_th     = mean_spread + th
    buy_th      = mean_spread - th
    sell_stop   = mean_spread + stop
    buy_stop    = mean_spread - stop

    # Plot the 2nd subplot
    sns.lineplot(data=spread, color='#85929E', ax=ax[1], linewidth=1.2)
    ax[1].axhline(sell_th,   color='b', ls='--', linewidth=1, label='sell_th')
    ax[1].axhline(buy_th,    color='r', ls='--', linewidth=1, label='buy_th')
    ax[1].axhline(sell_stop, color='g', ls='--', linewidth=1, label='sell_stop')
    ax[1].axhline(buy_stop,  color='y', ls='--', linewidth=1, label='buy_stop')
    ax[1].fill_between(idx, sell_th, buy_th, facecolors='r', alpha=0.3)
    ax[1].legend(loc='upper left', labels=['Spread', 'sell_th', 'buy_th', 'sell_stop', 'buy_stop'], prop={'size':6.5})
//  [python]
def plot2d_trajectories(self,
                            obs:  np.ndarray,
                            gt:   np.ndarray,
                            pred: np.ndarray,
                            index: Tuple,
                            max_pos: np.ndarray,
                            min_pos: np.ndarray) -> None:
        """plot 2d trajectories

        Args:
            obs (np.ndarray): (N_seqs, N_timesteps, [x, y])
            gt (np.ndarray): (N_seqs, N_timesteps, [x,y])
            pred (np.ndarray): (N_seqs, N_timesteps, N_trials, [x,y])
            img_path (Path): Path
        """

        N_seqs, N_timesteps, N_trials, N_dim = pred.shape
        gt_vis = np.zeros([N_seqs, N_timesteps+1, N_dim])
        gt_vis[:, 0] = obs[:, -1]
        gt_vis[:, 1:] = gt

        pred_vis = np.zeros([N_seqs, N_timesteps+1, N_trials, N_dim])
        # (num_seqs, num_dim) -> (num_seqs, 1, num_dim)
        pred_vis[:, 0] = obs[:, -1][:, None]
        pred_vis[:, 1:] = pred

        f, ax = plt.subplots(1, 1)
        ax.set_aspect('equal', adjustable='box')
        ax.set_xlim(min_pos[0], max_pos[0])
        ax.set_ylim(min_pos[1], max_pos[1])

        for j in range(N_seqs):
            plt.plot(obs[j, :, 0], obs[j, :, 1], color='black',
                         marker='o', label="obs")
            plt.plot(gt_vis[j, :, 0], gt_vis[j, :, 1],
                         color='blue', marker='o', label="GT")
            for i in range(pred.shape[2]):
                if i == 0:
                    plt.plot(pred_vis[j, :, i, 0], pred_vis[j, :, i, 1],
                                 color='green', marker='o', label="pred")
                else:
                    plt.plot(
                        pred_vis[j, :, i, 0], pred_vis[j, :, i, 1], color='green', marker='o')

        img_path = self.output_dir / \
            f"{index[0]}_{index[1]}_{index[2].strip('PEDESTRIAN/')}.png"
        plt.savefig(img_path)
        plt.close()
//  [python]
def plot2d_trajectories(self,
                            obs:  np.ndarray,
                            gt:   np.ndarray,
                            pred: np.ndarray,
                            index: Tuple,
                            max_pos: np.ndarray,
                            min_pos: np.ndarray) -> None:
        """plot 2d trajectories

        Args:
            obs (np.ndarray): (N_seqs, N_timesteps, [x, y])
            gt (np.ndarray): (N_seqs, N_timesteps, [x,y])
            pred (np.ndarray): (N_seqs, N_timesteps, N_trials, [x,y])
            img_path (Path): Path
        """

        N_seqs, N_timesteps, N_trials, N_dim = pred.shape
        gt_vis = np.zeros([N_seqs, N_timesteps+1, N_dim])
        gt_vis[:, 0] = obs[:, -1]
        gt_vis[:, 1:] = gt

        pred_vis = np.zeros([N_seqs, N_timesteps+1, N_trials, N_dim])
        # (num_seqs, num_dim) -> (num_seqs, 1, num_dim)
        pred_vis[:, 0] = obs[:, -1][:, None]
        pred_vis[:, 1:] = pred

        f, ax = plt.subplots(1, 1)
        ax.set_aspect('equal', adjustable='box')
        ax.set_xlim(min_pos[0], max_pos[0])
        ax.set_ylim(min_pos[1], max_pos[1])

        for j in range(N_seqs):
            sns.lineplot(x=obs[j, :, 0], y=obs[j, :, 1], color='black',
                         legend='brief', label="obs", marker='o')
            sns.lineplot(x=gt_vis[j, :, 0], y=gt_vis[j, :, 1],
                         color='blue', legend='brief', label="GT", marker='o')
            for i in range(pred.shape[2]):
                if i == 0:
                    sns.lineplot(x=pred_vis[j, :, i, 0], y=pred_vis[j, :, i, 1],
                                 color='green', legend='brief', label="pred", marker='o')
                else:
                    sns.lineplot(
                        x=pred_vis[j, :, i, 0], y=pred_vis[j, :, i, 1], color='green', marker='o')

        img_path = self.output_dir / \
            f"{index[0]}_{index[1]}_{index[2].strip('PEDESTRIAN/')}.png"
        plt.savefig(img_path)
        plt.close()
//  [python]
def _output_graph(self, agg_data: List[Sequence[Number]], num_runs: int):
    """Builds a graph of the results and outputs to a .png.

    Args:
      agg_data: 2d array of data to be graphed.
      num_runs: Number of columns of runs in the data.
    """
    # Build data frames
    columns = ['step']
    columns.extend([str(i) for i in range(num_runs)])
    # csv contains aggregate info that will get excluded in the pd.melt.
    columns.extend(['median', 'mean'])
    print(columns)
    df = pd.DataFrame(agg_data, columns=columns)
    logging.debug('Dataframes datatypes: %s', df.dtypes)
    new_pd = pd.melt(
        df,
        id_vars='step',
        value_vars=list(df.columns[1 : num_runs + 1]),
        var_name='run',
        value_name=self.yaxis_title,
    )
    logging.info('DataFrame to graph:\n%s', new_pd)
    # Build graph
    plt.figure(figsize=(10, 5))
    ax = sns.tsplot(
        data=new_pd, time='step', value=self.yaxis_title, unit='run', err_style=self.err_style
    )
    ax.set_title(self.title)
    ax.set(xlabel=self.xaxis_title)
    plt.ticklabel_format(style='plain', axis='x')
    graph_path = os.path.join(
        self.output_path, self.output_prefix + '_graph.png'
    )
    plt.savefig(graph_path)