jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def print_barplots(samples_d1, samples_d2, name_samples_d1, name_samples_d2, fontsize=48):
    sns.set_context("paper")
    sns.set_style("whitegrid")
    #sns.set_style("whitegrid", {'axes.grid' : False})
    training_method = []
    participants_index = []
    accuracies = []
    for i in range(len(samples_d2)):
        accuracies.append(samples_d2[i])
        training_method.append(name_samples_d2)
        participants_index.append(i)
    for i in range(len(samples_d1)):
        accuracies.append(samples_d1[i])
        training_method.append(name_samples_d1)
        participants_index.append(i)
    df = pd.DataFrame({"Training Method": training_method, "Accuracy": accuracies,
                       "Participant": participants_index})

    sns.set(font_scale=3.5)
    with sns.axes_style("whitegrid"):
        g = sns.factorplot(x="Participant", y="Accuracy", hue="Training Method", ci="sd", data=df, kind="bar")
        g.despine(left=True)
        plt.title("Accuracy per participant in respect to the training method")
        plt.show()
//  [python]
def print_barplots(samples_d1, samples_d2, name_samples_d1, name_samples_d2, fontsize=48):
    sns.set_context("paper")
    sns.set_style("whitegrid")
    #sns.set_style("whitegrid", {'axes.grid' : False})
    training_method = []
    participants_index = []
    accuracies = []
    for i in range(len(samples_d2)):
        accuracies.append(samples_d2[i])
        training_method.append(name_samples_d2)
        participants_index.append(i)
    for i in range(len(samples_d1)):
        accuracies.append(samples_d1[i])
        training_method.append(name_samples_d1)
        participants_index.append(i)
    df = pd.DataFrame({"Training Method": training_method, "Accuracy": accuracies,
                       "Participant": participants_index})

    sns.set(font_scale=3.5)
    with sns.axes_style("whitegrid"):
        sns.catplot(x="Participant", y="Accuracy", hue="Training Method", ci="sd", data=df, legend_out=True, kind="bar")
    plt.title("Accuracy per participant in respect to the training method")
    plt.show()
//  [python]
def qualifier_impact_pattern(
    log_level: str,
    input_root: pathlib.Path,
    buffer_path: pathlib.Path,
    output_path: pathlib.Path,
    minimum_frequency: int,
    force: bool,
    aggregate: bool,
):
    """Plot improvement grouped by pattern."""
    logging.basicConfig(level=log_level)
    df = _buffered_collation(
        input_root=input_root,
        buffer_path=buffer_path,
        force=force,
        minimum_frequency=minimum_frequency,
    )
    # pre-aggregate
    if aggregate:
        df = df.groupby(
            by=["pattern", "relation_id", "metric"],
        ).agg(dict(value="mean")).reset_index()
    df = df.rename(columns=dict(value="Improvement"))
    df["metric"] = df["metric"].apply(METRICS.get)
    grid = seaborn.factorplot(
        data=df,
        x="pattern",
        y="Improvement",
        col="metric",
        kind="box",
        size=4,
        aspect=1 / scipy.constants.golden_ratio,
    )
    grid.set_xticklabels(rotation=90)
    for ax in grid.axes.flat:
        ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1))

    output_path = output_path.expanduser().resolve()
    output_path.parent.mkdir(exist_ok=True, parents=True)
    grid.savefig(output_path)
    logger.info(f"Saved to {output_path.as_uri()}")
//  [python]
def qualifier_impact_pattern(
    log_level: str,
    input_root: pathlib.Path,
    buffer_path: pathlib.Path,
    output_path: pathlib.Path,
    minimum_frequency: int,
    force: bool,
    aggregate: bool,
):
    """Plot improvement grouped by pattern."""
    logging.basicConfig(level=log_level)
    df = _buffered_collation(
        input_root=input_root,
        buffer_path=buffer_path,
        force=force,
        minimum_frequency=minimum_frequency,
    )
    # pre-aggregate
    if aggregate:
        df = df.groupby(
            by=["pattern", "relation_id", "metric"],
        ).agg(dict(value="mean")).reset_index()
    df = df.rename(columns=dict(value="Improvement"))
    df["metric"] = df["metric"].apply(METRICS.get)
    grid = seaborn.catplot(
        data=df,
        x="pattern",
        y="Improvement",
        col="metric",
        kind="box",
        height=4,
        aspect=1 / scipy.constants.golden_ratio,
    )
    grid.set_xticklabels(rotation=90)
    for ax in grid.axes.flat:
        ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1))

    output_path = output_path.expanduser().resolve()
    output_path.parent.mkdir(exist_ok=True, parents=True)
    grid.savefig(output_path)
    logger.info(f"Saved to {output_path.as_uri()}")
//  [python]
def qualifier_impact_scatter(
    log_level: str,
    input_root: pathlib.Path,
    buffer_path: pathlib.Path,
    output_path: pathlib.Path,
    minimum_frequency: int,
    force: bool,
):
    """Plot relation-specific improvement."""
    logging.basicConfig(level=log_level)
    df = _buffered_collation(
        input_root=input_root,
        buffer_path=buffer_path,
        force=force,
        minimum_frequency=minimum_frequency,
    )

    output_path = output_path.expanduser().resolve()
    output_path.parent.mkdir(parents=True, exist_ok=True)

    # metric-specific
    for metric, group in df.groupby(by="metric"):
        metric = METRICS.get(str(metric), metric)
        group = group.rename(columns=dict(value=metric))
        relation_order = group.groupby(
            by="relation_id",
        ).agg(
            {metric: "mean"},
        ).sort_values(by=metric).reset_index()["relation_id"].reset_index()

        group_tmp = pandas.merge(group, relation_order, on="relation_id")
        grid = seaborn.stripplot(
            data=group_tmp,
            x="index",
            hue="pattern",
            jitter=0,
            y=metric,
            s=2.0,
            dodge=True,
            # order=...
        )
        grid = grid.get_figure()
        grid.savefig(output_path.with_stem(stem=f"{output_path.stem}_{metric}"))
//  [python]
def qualifier_impact_scatter(
    log_level: str,
    input_root: pathlib.Path,
    buffer_path: pathlib.Path,
    output_path: pathlib.Path,
    minimum_frequency: int,
    force: bool,
):
    """Plot relation-specific improvement."""
    logging.basicConfig(level=log_level)
    df = _buffered_collation(
        input_root=input_root,
        buffer_path=buffer_path,
        force=force,
        minimum_frequency=minimum_frequency,
    )

    output_path = output_path.expanduser().resolve()
    output_path.parent.mkdir(parents=True, exist_ok=True)

    # metric-specific
    for metric, group in df.groupby(by="metric"):
        metric = METRICS.get(str(metric), metric)
        group = group.rename(columns=dict(value=metric))
        relation_order = group.groupby(
            by="relation_id",
        ).agg(
            {metric: "mean"},
        ).sort_values(by=metric).reset_index()["relation_id"].reset_index()

        group_tmp = pandas.merge(group, relation_order, on="relation_id")
        grid = seaborn.catplot(
            data=group_tmp,
            x="index",
            hue="pattern",
            jitter=0,
            y=metric,
            s=2.0,
            dodge=True,
            # order=...
        )
        grid.ax.grid()
        grid.savefig(output_path.with_stem(stem=f"{output_path.stem}_{metric}"))
//  [python]
def plot_barcode_match_fraction(matches, suffix=""):
    """
    Matches should be a dict with values as boolean vectors
    """
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [sum(x) for x in matches.values()],
            [x.shape[0] for x in matches.values()]
        ],
        index=['correct', 'total'], columns=matches.keys())

    d.loc['correct', 'both'] = np.array([x for x in matches.values()]).all(axis=0).sum()
    d.loc['total', 'both'] = list(matches.values())[0].shape[0]
    d.loc["fraction of exact match", :] = d.loc['correct'] / d.loc['total']

    g = sns.FacetGrid(d.reset_index().melt(id_vars="index"), col="index", sharey=False, height=3, aspect=1)
    g.map(sns.barplot, "variable", "value")
    g.fig.savefig(
        args.output_prefix + f"barcode_matching.barplot.{suffix}.svg"
        .replace("..", "."),
        dpi=300, bbox_inches="tight")
//  [python]
def plot_barcode_match_fraction(matches, suffix=""):
    """
    Matches should be a dict with values as boolean vectors
    """
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [sum(x) for x in matches.values()],
            [x.shape[0] for x in matches.values()]
        ],
        index=['correct', 'total'], columns=matches.keys())

    d.loc['correct', 'both'] = np.array([x for x in matches.values()]).all(axis=0).sum()
    d.loc['total', 'both'] = list(matches.values())[0].shape[0]
    d.loc["fraction of exact match", :] = d.loc['correct'] / d.loc['total']

    grid = sns.catplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable", y="value", col="index",
        sharey=False, kind="bar", height=3, aspect=1)
    grid.fig.savefig(
        args.output_prefix + f"barcode_matching.barplot.{suffix}.svg"
        .replace("..", "."),
        dpi=300, bbox_inches="tight")
//  [python]
def plot_umi_match_fraction(umi, matches, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [sum(umi.loc[x]) for x in matches.values()],
            [umi.sum() for x in matches.values()]
        ],
        index=['correct', 'total'], columns=matches.keys())
    d.loc["fraction of exact match", :] = d.loc['correct'] / d.loc['total']

    g = sns.FacetGrid(d.reset_index().melt(id_vars="index"), col="index", sharey=False)
    g.map(sns.barplot, "variable", "value")
    g.fig.savefig(
        args.output_prefix + f"umi_matching.barplot.{suffix}.svg"
        .replace("..", "."),
        dpi=300, bbox_inches="tight")
//  [python]
def plot_umi_match_fraction(umi, matches, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [sum(umi.loc[x]) for x in matches.values()],
            [umi.sum() for x in matches.values()]
        ],
        index=['correct', 'total'], columns=matches.keys())
    d.loc["fraction of exact match", :] = d.loc['correct'] / d.loc['total']

    grid = sns.catplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable", y="value", col="index",
        sharey=False, kind="bar", height=3, aspect=1)
    grid.fig.savefig(
        args.output_prefix + f"umi_matching.barplot.{suffix}.svg"
        .replace("..", "."),
        dpi=300, bbox_inches="tight")
//  [python]
def coin_boxplot(
    pred: str = config.log_returns_pred,
    time_frame: str = "1d",
    forecasting_model="ARIMA",
):
    # Read the data
    rmse_df = read_rmse_csv(pred, time_frame=time_frame)
    vol_df = read_volatility_csv(time_frame=time_frame)

    # Add rmse to vol_df
    vol_df["rmse"] = rmse_df[forecasting_model]

    # Explode the lists into individual rows
    df_exploded = (
        vol_df.apply(pd.Series.explode).reset_index().rename(columns={"index": "Coin"})
    )

    # Create the multi-level boxplot using Seaborn
    g = sns.factorplot(
        x="train_volatility_class",
        y="rmse",
        hue="test_volatility_class",
        col="Coin",
        kind="box",
        data=df_exploded,
        palette="Set3",
        size=6,
        aspect=1,
        col_wrap=6,
        order=["low", "normal", "high"],
    )

    # Add labels and title
    g.fig.subplots_adjust(top=0.9)
    g.fig.suptitle(
        f"Boxplot of RMSE by Volatility Class During Training and Testing, Grouped by Coin. Forecasting Model: {forecasting_model}"
    )

    # Show the plot
    plt.show()
//  [python]
def coin_boxplot(
    pred: str = config.log_returns_pred,
    time_frame: str = "1d",
    forecasting_model="ARIMA",
):
    # Read the data
    rmse_df = read_rmse_csv(pred, time_frame=time_frame)
    vol_df = read_volatility_csv(time_frame=time_frame)

    # Add rmse to vol_df
    vol_df["rmse"] = rmse_df[forecasting_model]

    # Explode the lists into individual rows
    df_exploded = (
        vol_df.apply(pd.Series.explode).reset_index().rename(columns={"index": "Coin"})
    )

    # Create the multi-level boxplot using Seaborn
    g = sns.catplot(
        x="train_volatility_class",
        y="rmse",
        hue="test_volatility_class",
        col="Coin",
        kind="box",
        data=df_exploded,
        palette="Set3",
        height=6,
        aspect=1,
        col_wrap=6,
        order=["low", "normal", "high"],
    )

    # Add labels and title
    g.fig.subplots_adjust(top=0.9)
    g.fig.suptitle(
        f"Boxplot of RMSE by Volatility Class During Training and Testing, Grouped by Coin. Forecasting Model: {forecasting_model}"
    )

    # Show the plot
    plt.show()
//  [python]
sns.set_theme(style="ticks")
exercise = sns.load_dataset("exercise")
g = sns.factorplot(x="time", y="pulse", hue="kind", data=exercise)
//  [python]
sns.set_theme(style="ticks")
exercise = sns.load_dataset("exercise")
g = sns.catplot(x="time", y="pulse", hue="kind", data=exercise)
//  [python]
def plot_metrics_vs_matchers(
    df,
    odir,
    _plot_kwargs,
    _kwargs_legend,
    ylim=(0, 1),
    sname=None,
    title=None,
    palette=None,
):
    _matchers = set(df["matcher"])
    _order = [
        matcher_map.get(_matcher) for _matcher in matcher_map if _matcher in _matchers
    ]

    # plot results
    g = sns.catplot(
        x="matcher_label",
        y="score",
        hue="metric_label",
        order=_order,
        data=df,
        palette=palette,
        **_plot_kwargs,
    )
    plt.legend(**_kwargs_legend)

    if title is not None:
        plt.title(title, loc="left", pad=25)

    # separate NLD and sample level scores
    sep = [
        ["nld-sample", "nld-event"],
        ["sample", "plurality-voting", "majority-voting"],
    ]
    _kwargs_sep = {"colors": "darkgray", "linestyles": "dashed"}
    sep = [[matcher_map.get(_matcher) for _matcher in _sep] for _sep in sep]
    pos = map(lambda x: [_order.index(_x) for _x in x if _x in _order], sep)
    for _pos in pos:
        if len(_pos):
            plt.vlines(max(_pos) + 0.5, *ylim, **_kwargs_sep)

    _format_matcher_metric_plot(ylim=ylim)

    if sname is not None:
        # save plots
        plt.savefig(os.path.join(odir, f"{sname}.eps"))

        # save png
        odir_png = os.path.join(odir, "png")
        mkpath(odir_png)
        plt.savefig(os.path.join(odir_png, f"{sname}.png"))

        plt.close()

        # save results
        odir_data = os.path.join(odir, "data")
        mkpath(odir_data)

        df_aggr = df.groupby(["metric_label", "matcher_label"], as_index=False).mean()
        df_aggr.to_csv(os.path.join(odir_data, f"{sname}.csv"), index=False)
//  [python]
def plot_metrics_vs_matchers(
    df,
    odir,
    _plot_kwargs,
    _kwargs_legend,
    ylim=(0, 1),
    sname=None,
    title=None,
    palette=None,
):
    _matchers = set(df["matcher"])
    _order = [
        matcher_map.get(_matcher) for _matcher in matcher_map if _matcher in _matchers
    ]

    # plot results
    sns.catplot(
        x="matcher_label",
        y="score",
        hue="metric_label",
        order=_order,
        data=df,
        palette=palette,
        **_plot_kwargs,
    )
    plt.legend(**_kwargs_legend)

    if title is not None:
        plt.title(title, loc="left", pad=25)

    # separate NLD and sample level scores
    sep = [
        ["nld-sample", "nld-event"],
        ["sample", "plurality-voting", "majority-voting"],
    ]
    _kwargs_sep = {"colors": "darkgray", "linestyles": "dashed"}
    sep = [[matcher_map.get(_matcher) for _matcher in _sep] for _sep in sep]
    pos = map(lambda x: [_order.index(_x) for _x in x if _x in _order], sep)
    for _pos in pos:
        if len(_pos):
            plt.vlines(max(_pos) + 0.5, *ylim, **_kwargs_sep)

    _format_matcher_metric_plot(ylim=ylim)

    if sname is not None:
        # save plots
        plt.savefig(os.path.join(odir, f"{sname}.eps"))

        # save png
        odir_png = os.path.join(odir, "png")
        mkpath(odir_png)
        plt.savefig(os.path.join(odir_png, f"{sname}.png"))

        plt.close()

        # save results
        odir_data = os.path.join(odir, "data")
        mkpath(odir_data)

        df_aggr = df.groupby(["metric_label", "matcher_label"], as_index=False).mean()
        df_aggr.to_csv(os.path.join(odir_data, f"{sname}.csv"), index=False)
//  [python]
def main(wrap: bool = False):
    melted_df = pd.read_csv(MELTED_PATH, sep="\t")
    melted_df.loc[:, "model"] = melted_df["model"].map(MODEL_TITLES)
    melted_df.loc[:, "dataset"] = melted_df["dataset"].map(DATASET_TITLES)
    _plot_summary(melted_df)

    for base_metric_key, metadata in METRICS.items():
        metrics = metadata["metrics"]
        df = melted_df[melted_df["variable"].isin(metrics)].copy()
        metric_order = [f"{order} ({short})" for order, short in zip(ORDER, metadata["short"])]
        df.loc[:, "variable"] = df["variable"].map(dict(zip(metrics, metric_order)))
        grid: sns.FacetGrid = sns.FacetGrid(
            data=df,
            col="variable",
            col_order=metric_order,
            col_wrap=2 if wrap else None,
            hue="dataset",
            hue_order=DATASET_ORDER,
            sharey=False,
            # facet_kws=dict(sharey=False),
        )
        grid.map(sns.barplot, "model", "value")
        # TODO calculate this
        has_negative_z = metadata.get("has_negative_z", False)
        # grid.set_xticklabels(rotation=30, ha="right")
        for key, ax in grid.axes_dict.items():
            if key.startswith("z-Adjusted Metric"):
                if has_negative_z:
                    ax.set_yscale("symlog")
                else:
                    ax.set_yscale("log")
            elif key.startswith("Adjusted Index"):
                ax.set_ylim([-0.1, 1])
            else:  # base metric
                if "base_ylim" in metadata:
                    ax.set_ylim(metadata["base_ylim"])
                if "base_yscale" in metadata:
                    ax.set_yscale(metadata["base_yscale"])
        grid.set_ylabels(label=metadata["base_title"])
        grid.set_xlabels(label="")
        grid.set_titles(col_template="{col_name}", size=13)
        if wrap:
            sns.move_legend(grid, "upper left", bbox_to_anchor=(0.425, 0.40), title="Dataset")
        grid.tight_layout()
        chart_path_stub = CHARTS_DIRECTORY.joinpath(f"{base_metric_key}_plot")
        grid.savefig(chart_path_stub.with_suffix(".pdf"))
        grid.savefig(chart_path_stub.with_suffix(".svg"))
        grid.savefig(chart_path_stub.with_suffix(".png"), dpi=300)
        plt.close(grid.fig)
//  [python]
def main(wrap: bool = False):
    melted_df = pd.read_csv(MELTED_PATH, sep="\t")
    melted_df.loc[:, "model"] = melted_df["model"].map(MODEL_TITLES)
    melted_df.loc[:, "dataset"] = melted_df["dataset"].map(DATASET_TITLES)
    _plot_summary(melted_df)

    for base_metric_key, metadata in METRICS.items():
        metrics = metadata["metrics"]
        df = melted_df[melted_df["variable"].isin(metrics)].copy()
        metric_order = [f"{order} ({short})" for order, short in zip(ORDER, metadata["short"])]
        df.loc[:, "variable"] = df["variable"].map(dict(zip(metrics, metric_order)))
        grid: sns.FacetGrid = sns.catplot(
            data=df,
            x="model",
            y="value",
            col="variable",
            col_order=metric_order,
            col_wrap=2 if wrap else None,
            # hue="model",
            hue="dataset",
            hue_order=DATASET_ORDER,
            sharey=False,
            # facet_kws=dict(sharey=False),
            kind="bar",
            height=2.4,
            aspect=scipy.constants.golden,
        )
        # TODO calculate this
        has_negative_z = metadata.get("has_negative_z", False)
        # grid.set_xticklabels(rotation=30, ha="right")
        for key, ax in grid.axes_dict.items():
            if key.startswith("z-Adjusted Metric"):
                if has_negative_z:
                    ax.set_yscale("symlog")
                else:
                    ax.set_yscale("log")
            elif key.startswith("Adjusted Index"):
                ax.set_ylim([-0.1, 1])
            else:  # base metric
                if "base_ylim" in metadata:
                    ax.set_ylim(metadata["base_ylim"])
                if "base_yscale" in metadata:
                    ax.set_yscale(metadata["base_yscale"])
        grid.set_ylabels(label=metadata["base_title"])
        grid.set_xlabels(label="")
        grid.set_titles(col_template="{col_name}", size=13)
        if wrap:
            sns.move_legend(grid, "upper left", bbox_to_anchor=(0.425, 0.40), title="Dataset")
        grid.tight_layout()
        chart_path_stub = CHARTS_DIRECTORY.joinpath(f"{base_metric_key}_plot")
        grid.savefig(chart_path_stub.with_suffix(".pdf"))
        grid.savefig(chart_path_stub.with_suffix(".svg"))
        grid.savefig(chart_path_stub.with_suffix(".png"), dpi=300)
        plt.close(grid.fig)
//  [python]
sns.set_context('talk')

probs2 = pd.melt(probs, id_vars=["Years"], var_name="Category", value_vars=["Low", "Medium", "High"])

rename = {'Low': '1', 'Medium': '2-3', 'High': '4-5'}
for key in rename.keys():
    ind = probs2.loc[:, "Category"] == key
    probs2.loc[ind, "Category"] = rename[key]
ax = sns.factorplot(x="Category", y="value", hue="Years", kind="bar", data=probs2)
//  [python]
sns.set_context('talk')



probs2 = pd.melt(probs, id_vars=["Years"], var_name="Category", value_vars=["Low", "Medium", "High"])

rename = {'Low': '1', 'Medium': '2-3', 'High': '4-5'}
for key in rename.keys():
    ind = probs2.loc[:, "Category"] == key
    probs2.loc[ind, "Category"] = rename[key]
ax = sns.catplot(x="Category", y="value", hue="Years", kind="bar", data=probs2)
//  [python]
def plot_metrics_full(df, x, y, col, row, hue, name, hue_order = model_names):
    d = df[df['Model'] != 'Monolithic']
    g = sns.factorplot(data=d, x=x, y=y, col=col, row=row, hue=hue,
                kind='bar', order=['Small', 'Medium', 'Large'],
                hue_order=hue_order, alpha=0.9, saturation=0.8)

    g.set_xlabels(x, size=24)
    g.set_ylabels(y, size=24)
    g.set_titles("Rules = {col_name}", size=24)

    g.set_xticklabels(size=20)
    g.set_yticklabels(size=20)

    for i, ax in enumerate(g.axes[0]):
        if i != 2:
            ax.set_xlabel('', fontsize=24)

    for ax in g.axes[0]:
        for index, label in enumerate(ax.get_yticklabels()):
            if index % 2 == 0:
                label.set_visible(False)
            else:
                label.set_visible(True)

    if row != None:
        for i, ax in enumerate(g.axes[1]):
            if i != 2:
                ax.set_xlabel('', fontsize=24)

        sns.move_legend(
            g,
            loc=(0.23, -0.075),
            ncol=4,
            title=None,
            frameon=False,
            fontsize=24,
            borderpad=3
        )
    else:
        sns.move_legend(
            g,
            loc=(0.23, -0.13),
            ncol=4,
            title=None,
            frameon=False,
            fontsize=24,
            borderpad=3
        )

    plt.savefig(name, bbox_inches='tight')
    plt.close()
//  [python]
def plot_metrics_full(df, x, y, col, row, hue, name, hue_order = model_names):
    d = df[df['Model'] != 'Monolithic']
    g = sns.catplot(data=d, x=x, y=y, col=col, row=row, hue=hue,
                kind='bar', order=['Small', 'Medium', 'Large'],
                hue_order=hue_order, alpha=0.9, saturation=0.8)

    g.set_xlabels(x, size=24)
    g.set_ylabels(y, size=24)
    g.set_titles("Rules = {col_name}", size=24)

    g.set_xticklabels(size=20)
    g.set_yticklabels(size=20)

    for i, ax in enumerate(g.axes[0]):
        if i != 2:
            ax.set_xlabel('', fontsize=24)

    for ax in g.axes[0]:
        for index, label in enumerate(ax.get_yticklabels()):
            if index % 2 == 0:
                label.set_visible(False)
            else:
                label.set_visible(True)

    if row != None:
        for i, ax in enumerate(g.axes[1]):
            if i != 2:
                ax.set_xlabel('', fontsize=24)

        sns.move_legend(
            g,
            loc=(0.23, -0.075),
            ncol=4,
            title=None,
            frameon=False,
            fontsize=24,
            borderpad=3
        )
    else:
        sns.move_legend(
            g,
            loc=(0.23, -0.13),
            ncol=4,
            title=None,
            frameon=False,
            fontsize=24,
            borderpad=3
        )

    plt.savefig(name, bbox_inches='tight')
    plt.close()
//  [python]
def plot_ratios_clip_range(res_df, actor_lr=0.0005, num_epochs=20, num_samples=100):
    res_df = res_df[res_df['learning_rate'] == actor_lr]
    res_df = res_df[res_df['num_epochs'] == num_epochs]

    all_items = []
    clip_range = res_df['clip_range']
    ratios = res_df['ratios']
    for i in range(len(clip_range)):
        ratio_list = ratios.iloc[i].split(' ')
        ratio_list = [float(s) for s in ratio_list]
        # randomly sample 100 points
        ratio_list = np.random.choice(ratio_list, num_samples, replace=False)
        for j in ratio_list:
            r = clip_range.iloc[i]
            all_items.append({'clip_range': r, 'ratio': j})
    
    df_ratios = pd.DataFrame(all_items)
    sns_plot = sns.stripplot(x="clip_range", y="ratio", jitter=True, s=2, data=df_ratios)

    sns_plot.set(xlim=(0, 1.0), xlabel='Clipping range', ylabel='Ratio distribution')
    sns_plot.set_xticklabels(['0.1', '0.2', '0.3', '0.4', '0.5', 'No clipping'])
    sns_plot.savefig('figures/ratios_with_clip_range_epoch_%d.pdf'%num_epochs)
//  [python]
def plot_ratios_clip_range(res_df, actor_lr=0.0005, num_epochs=20, num_samples=100):
    res_df = res_df[res_df['learning_rate'] == actor_lr]
    res_df = res_df[res_df['num_epochs'] == num_epochs]

    all_items = []
    clip_range = res_df['clip_range']
    ratios = res_df['ratios']
    for i in range(len(clip_range)):
        ratio_list = ratios.iloc[i].split(' ')
        ratio_list = [float(s) for s in ratio_list]
        # randomly sample 100 points
        ratio_list = np.random.choice(ratio_list, num_samples, replace=False)
        for j in ratio_list:
            r = clip_range.iloc[i]
            all_items.append({'clip_range': r, 'ratio': j})
    
    df_ratios = pd.DataFrame(all_items)
    sns_plot = sns.catplot(x="clip_range", y="ratio", jitter=True, s=2, data=df_ratios)

    sns_plot.set(xlim=(0, 1.0), xlabel='Clipping range', ylabel='Ratio distribution')
    sns_plot.set_xticklabels(['0.1', '0.2', '0.3', '0.4', '0.5', 'No clipping'])
    sns_plot.savefig('figures/ratios_with_clip_range_epoch_%d.pdf'%num_epochs)
//  [python]
def make_chart(name, series, dtype):
    FLOOR_DATE = datetime(1960, 1, 1)
    CEILING_DATE = datetime.today()
    img = BytesIO()
    # Setting figure sizes in seaborn is a bit weird:
    # https://stackoverflow.com/a/23973562/559140
    if is_categorical_dtype(dtype):
        sns.set_style("ticks")
        sns.countplot(
            x=name, data=series.to_frame(),
        )
        plt.xticks(rotation=45)
    elif is_bool_dtype(dtype):
        sns.set_style("ticks")
        sns.countplot(x=name, data=series.to_frame())
        plt.xticks(rotation=45)
    elif is_datetime64_dtype(dtype):
        # Early dates are dummy values; I don't know what late dates
        # are but presumably just dud data
        series = series[(series > FLOOR_DATE) & (series <= CEILING_DATE)]
        # Set bin numbers appropriate to the time window
        delta = series.max() - series.min()
        if delta.days <= 31:
            bins = delta.days
        elif delta.days <= 365 * 10:
            bins = delta.days / 31
        else:
            bins = delta.days / 365
        if bins < 1:
            bins = 1
        fig = plt.figure(figsize=(5, 2))
        ax = fig.add_subplot(111)
        series.hist(bins=int(bins), ax=ax)
        plt.xticks(rotation=45, ha="right")
    elif is_numeric_dtype(dtype):
        # Trim percentiles and negatives which are usually bad data
        series = series[
            (series < np.percentile(series, 95))
            & (series > np.percentile(series, 5))
            & (series > 0)
        ]
        fig = plt.figure(figsize=(5, 2))
        ax = fig.add_subplot(111)
        sns.distplot(series, kde=False, ax=ax)
        plt.xticks(rotation=45)
    else:
        raise ValueError()

    plt.savefig(img, transparent=True, bbox_inches="tight")
    img.seek(0)
    plt.close()
    return base64.b64encode(img.read()).decode("UTF-8")
//  [python]
def make_chart(name, series, dtype):
    FLOOR_DATE = datetime(1960, 1, 1)
    CEILING_DATE = datetime.today()
    img = BytesIO()
    # Setting figure sizes in seaborn is a bit weird:
    # https://stackoverflow.com/a/23973562/559140
    if is_categorical_dtype(dtype):
        sns.set_style("ticks")
        sns.catplot(
            x=name, data=series.to_frame(), kind="count", height=3, aspect=3 / 2
        )
        plt.xticks(rotation=45)
    elif is_bool_dtype(dtype):
        sns.set_style("ticks")
        sns.catplot(x=name, data=series.to_frame(), kind="count", height=2, aspect=1)
        plt.xticks(rotation=45)
    elif is_datetime64_dtype(dtype):
        # Early dates are dummy values; I don't know what late dates
        # are but presumably just dud data
        series = series[(series > FLOOR_DATE) & (series <= CEILING_DATE)]
        # Set bin numbers appropriate to the time window
        delta = series.max() - series.min()
        if delta.days <= 31:
            bins = delta.days
        elif delta.days <= 365 * 10:
            bins = delta.days / 31
        else:
            bins = delta.days / 365
        if bins < 1:
            bins = 1
        fig = plt.figure(figsize=(5, 2))
        ax = fig.add_subplot(111)
        series.hist(bins=int(bins), ax=ax)
        plt.xticks(rotation=45, ha="right")
    elif is_numeric_dtype(dtype):
        # Trim percentiles and negatives which are usually bad data
        series = series[
            (series < np.percentile(series, 95))
            & (series > np.percentile(series, 5))
            & (series > 0)
        ]
        fig = plt.figure(figsize=(5, 2))
        ax = fig.add_subplot(111)
        sns.distplot(series, kde=False, ax=ax)
        plt.xticks(rotation=45)
    else:
        raise ValueError()

    plt.savefig(img, transparent=True, bbox_inches="tight")
    img.seek(0)
    plt.close()
    return base64.b64encode(img.read()).decode("UTF-8")
//  [python]
def plot_multi_boxplot(df, measure='fmax', out_pref="test", title="", ax=None, **kwargs):
    algs = df['Algorithm'].unique()
    try:
        # If there are algorithms which don't have a set shape or color, this will fail
        curr_palette = [alg_colors[alg] for alg in algs]
        curr_markers = [alg_shapes[alg] for alg in algs]
    except KeyError:
        curr_palette = my_palette
        curr_markers = my_shapes 

    if kwargs['for_paper'] is True:
        sns.set_style("darkgrid", {
            'xtick.top': True, 'xtick.bottom': True, #'xtick.color': '.3',
            #'grid.color': '.3', 'axes.labelcolor': '.15',
            #'axes.edgecolor': '.3',
            'axes.spines.bottom': True, 'axes.spines.left': True,
            'axes.spines.right': True, 'axes.spines.top': True,})
    #df['Algorithm'] = df['Algorithm'].astype(str)
    df['Algorithm'] = df['Algorithm'].astype(str)
    df = df[['Algorithm', measure, 'plot_exp_name']]
    x = "Algorithm"
    y = measure
    orient = 'v'
    if kwargs.get('horizontal'):
        y = "Algorithm"
        x = measure
        orient = 'h'
    g = sns.FacetGrid(df, col='plot_exp_name', col_wrap=5, height=4, aspect=1, palette=curr_palette)
    g.map(sns.boxplot, x, y, orient=orient, fliersize=1)
    # Fix the ax subtitle
    for ax in g.fig.axes:
        ax.set_title(ax.get_title().replace('plot_exp_name = ',''))
        ax.set_xticks(list(range(len(algs))))
        ax.set_xticklabels(algs)
    # put less space between the plots
    g.fig.subplots_adjust(hspace=.05)
    g.set(xticks=np.arange(0,11)*0.1)
    if kwargs['for_paper'] is True:
        g.set_ylabels("")
        g.set_titles("")
        g.fig.tight_layout()
        xlabel = measure_map.get(measure, measure.upper())
        g.set_xlabels(xlabel)

    if out_pref is not None:
        out_file = "%s%s-multi-boxplot.pdf" % (out_pref, measure)
        savefig(out_file, **kwargs)
//  [python]
def plot_multi_boxplot(df, measure='fmax', out_pref="test", title="", ax=None, **kwargs):
    algs = df['Algorithm'].unique()
    try:
        # If there are algorithms which don't have a set shape or color, this will fail
        curr_palette = [alg_colors[alg] for alg in algs]
        curr_markers = [alg_shapes[alg] for alg in algs]
    except KeyError:
        curr_palette = my_palette
        curr_markers = my_shapes 

    if kwargs['for_paper'] is True:
        sns.set_style("darkgrid", {
            'xtick.top': True, 'xtick.bottom': True, #'xtick.color': '.3',
            #'grid.color': '.3', 'axes.labelcolor': '.15',
            #'axes.edgecolor': '.3',
            'axes.spines.bottom': True, 'axes.spines.left': True,
            'axes.spines.right': True, 'axes.spines.top': True,})
    #df['Algorithm'] = df['Algorithm'].astype(str)
    df['Algorithm'] = df['Algorithm'].astype(str)
    df = df[['Algorithm', measure, 'plot_exp_name']]
    x = "Algorithm"
    y = measure
    orient = 'v'
    if kwargs.get('horizontal'):
        y = "Algorithm"
        x = measure
        orient = 'h'
    g = sns.catplot(x=x, y=y, data=df,  # hue='Algorithm',
                    col='plot_exp_name', col_wrap=5, #row='plot_exp_name',  
                    height=4, aspect=1, palette=curr_palette, 
                    orient=orient,
                    fliersize=1,  
                    kind='box',)
                    #kind="violin", cut=0, inner='quartile',)
    # Fix the ax subtitle
    for ax in g.fig.axes:
        ax.set_title(ax.get_title().replace('plot_exp_name = ',''))
        ax.set_xticks(list(range(len(algs))))
        ax.set_xticklabels(algs)
    # put less space between the plots
    g.fig.subplots_adjust(hspace=.05)
    g.set(xticks=np.arange(0,11)*0.1)
    if kwargs['for_paper'] is True:
        g.set_ylabels("")
        g.set_titles("")
        g.fig.tight_layout()
        xlabel = measure_map.get(measure, measure.upper())
        g.set_xlabels(xlabel)

    if out_pref is not None:
        out_file = "%s%s-multi-boxplot.pdf" % (out_pref, measure)
        savefig(out_file, **kwargs)
//  [python]
def plot_barcode_match_fraction(r1, r2, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [[r1.sum(), r2.sum(), (r1 & r2).sum()], [r1.shape[0]] * 3],
        index=["correct", "total"],
        columns=["r1", "r2", "both"],
    )
    d.loc["fraction of exact match", :] = d.loc["correct"] / d.loc["total"]

    grid = sns.factorplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable",
        y="value",
        col="index",
        sharey=False,
        kind="bar",
        size=3,
        aspect=1,
    )
    grid.fig.savefig(
        args.output_prefix
        + f"barcode_matching.barplot.{suffix}.svg".replace("..", "."),
        dpi=300,
        bbox_inches="tight",
    )
//  [python]
def plot_barcode_match_fraction(r1, r2, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [[r1.sum(), r2.sum(), (r1 & r2).sum()], [r1.shape[0]] * 3],
        index=["correct", "total"],
        columns=["r1", "r2", "both"],
    )
    d.loc["fraction of exact match", :] = d.loc["correct"] / d.loc["total"]

    grid = sns.catplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable",
        y="value",
        col="index",
        sharey=False,
        kind="bar",
        height=3,
        aspect=1,
    )
    grid.fig.savefig(
        args.output_prefix
        + f"barcode_matching.barplot.{suffix}.svg".replace("..", "."),
        dpi=300,
        bbox_inches="tight",
    )
//  [python]
def plot_umi_match_fraction(umi, r1_match, r2_match, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [umi.loc[r1_match].sum(), umi.sum()],
            [umi.loc[r2_match].sum(), umi.sum()],
        ],
        index=["correct", "total"],
        columns=["r1", "r2"],
    )
    d.loc["fraction of exact match", :] = d.loc["correct"] / d.loc["total"]

    grid = sns.factorplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable",
        y="value",
        col="index",
        sharey=False,
        kind="bar",
        size=3,
        aspect=1,
    )
    grid.fig.savefig(
        args.output_prefix
        + f"umi_matching.barplot.{suffix}.svg".replace("..", "."),
        dpi=300,
        bbox_inches="tight",
    )
//  [python]
def plot_umi_match_fraction(umi, r1_match, r2_match, suffix=""):
    print(f"# {time.asctime()} - Plotting fraction of correct barcodes.")

    d = pd.DataFrame(
        [
            [umi.loc[r1_match].sum(), umi.sum()],
            [umi.loc[r2_match].sum(), umi.sum()],
        ],
        index=["correct", "total"],
        columns=["r1", "r2"],
    )
    d.loc["fraction of exact match", :] = d.loc["correct"] / d.loc["total"]

    grid = sns.catplot(
        data=d.reset_index().melt(id_vars="index"),
        x="variable",
        y="value",
        col="index",
        sharey=False,
        kind="bar",
        height=3,
        aspect=1,
    )
    grid.fig.savefig(
        args.output_prefix
        + f"umi_matching.barplot.{suffix}.svg".replace("..", "."),
        dpi=300,
        bbox_inches="tight",
    )
//  [python]
def _plot(datafile, outfile):
    """Plotting logic."""
    # Mfr PartNumber,GBWP (kHz),Supply Current (uA),GBWP/uA,min_voltage,max_voltage
    logger.info("Plotting from {}...".format(datafile))

    data = pd.read_csv(datafile, skipinitialspace=True, thousands=",")

    fig, ax = plt.subplots(figsize=(7, 5))
    plot = sns.pointplot(
        x="latency",
        y="filesize",
        hue="kind",
        data=data,
    )

    sns.despine(bottom=True, left=True)
    plot.set(xlabel="motion-to-photon latency (ms)")
    plot.set(ylabel="percent of normal filseize")
    plot.legend(title="technique")
    #  plot.set(xlim=(0, 100))
    plot.set(ylim=(0, 100))
    pp = PdfPages(outfile)
    pp.savefig(plot.figure.tight_layout())
    pp.close()
    run(["pdfcrop", outfile, outfile], stdout=DEVNULL, check=True)
    logger.info(f"Plot saved to {outfile}")
//  [python]
def _plot(datafile, outfile):
    """Plotting logic."""
    # Mfr PartNumber,GBWP (kHz),Supply Current (uA),GBWP/uA,min_voltage,max_voltage
    logger.info("Plotting from {}...".format(datafile))

    data = pd.read_csv(datafile, skipinitialspace=True, thousands=",")

    fig, ax = plt.subplots(figsize=(7, 5))
    plot = sns.catplot(
        x="latency",
        y="filesize",
        hue="kind",
        kind="point",
        data=data,
    )

    sns.despine(bottom=True, left=True)
    plot.set(xlabel="motion-to-photon latency (ms)")
    plot.set(ylabel="percent of normal filseize")
    plot._legend.set_title("technique")
    #  plot.set(xlim=(0, 100))
    plot.set(ylim=(0, 100))
    pp = PdfPages(outfile)
    pp.savefig(plot.fig.tight_layout())
    pp.close()
    run(["pdfcrop", outfile, outfile], stdout=DEVNULL, check=True)
    logger.info(f"Plot saved to {outfile}")
//  [python]
def plot_violin(data: pd.DataFrame, out_filename: str) -> None:
    plt.gcf().clear()
    g = sns.violinplot(x="model_type", y="P(correct|context)",
                hue="correct", col="condition",
                data=data, split=False,
                scale="count", inner="box")
    #plt.tight_layout()
    plt.savefig(f"{out_filename}.png")
    plt.savefig(f"{out_filename}.eps")
//  [python]
def plot_violin(data: pd.DataFrame, out_filename: str) -> None:
    plt.gcf().clear()
    g = sns.catplot(x="model_type", y="P(correct|context)",
                hue="correct", col="condition",
                data=data, kind="violin", split=False,
                height=4, aspect=.7, palette="Pastel1", scale="count", inner="box")
    #plt.tight_layout()
    plt.savefig(f"{out_filename}.png")
    plt.savefig(f"{out_filename}.eps")
//  [python]
def plot_donor_vs_acceptor(df: pd.DataFrame, 
                           metric: str,
                           fname: str,
                           title: str):

    """
    Plot performance of individual tools on intronic variants
    associated with splicing donor vs splicing acceptors

    :param pd.DataFrame data: Df with stats for each tool
    :pararm str metric: Metric to rank tools
    :param str fname: Output file
    :param str title: Title of the plot
    """
    fig, ax = plt.subplots()
    plt.rcParams.update({'font.size': 10}) 
   
    if len(df['Splice site'].unique().tolist()) == 1:
        df = df.sort_values(metric, ascending=False)
        g = sns.barplot(data=df, 
                        x=metric, 
                        y="Tool",
                        hue="Splice site",
                        palette={'Donor': 'darkred', 'Acceptor': 'skyblue'}, 
                        edgecolor='k',
                        alpha=.8)

        g.despine(left=True)

    # If both donors and acceptors    
    else:
        sns.stripplot(x=metric, y="Tool", hue='Splice site', linewidth=1, size=10, data=df)
        sns.boxplot(x=metric, y="Tool", data=df, color='white')
   
    plt.legend(loc="upper right",
               bbox_to_anchor=(1.1, 1),
               borderaxespad=0,
               prop=dict(size=8))
    plt.title(title) 
    plt.ylabel('')
    plt.xlim(0, 1)
    plt.tight_layout()
    plt.savefig(fname, bbox_inches='tight')
    plt.close()
//  [python]
def plot_donor_vs_acceptor(df: pd.DataFrame, 
                           metric: str,
                           fname: str,
                           title: str):

    """
    Plot performance of individual tools on intronic variants
    associated with splicing donor vs splicing acceptors

    :param pd.DataFrame data: Df with stats for each tool
    :pararm str metric: Metric to rank tools
    :param str fname: Output file
    :param str title: Title of the plot
    """
    fig, ax = plt.subplots()
    plt.rcParams.update({'font.size': 10}) 
   
    if len(df['Splice site'].unique().tolist()) == 1:
        df = df.sort_values(metric, ascending=False)
        g = sns.catplot(data=df, 
                        kind="bar",
                        x=metric, 
                        y="Tool",
                        hue="Splice site",
                        palette={'Donor': 'darkred', 'Acceptor': 'skyblue'}, 
                        edgecolor='k',
                        legend_out=True,
                        alpha=.8, 
                        aspect=.8,
                        height=8)

        g.despine(left=True)

    # If both donors and acceptors    
    else:
        sns.stripplot(x=metric, y="Tool", hue='Splice site', linewidth=1, size=10, data=df)
        sns.boxplot(x=metric, y="Tool", data=df, color='white')
   
    plt.legend(loc="upper right",
               bbox_to_anchor=(1.1, 1),
               borderaxespad=0,
               prop=dict(size=8))
    plt.title(title) 
    plt.ylabel('')
    plt.xlim(0, 1)
    plt.tight_layout()
    plt.savefig(fname, bbox_inches='tight')
    plt.close()
//  [python]
def catplot(**kwargs: Any) -> Any:
    # kwargs.setdefault("palette", "Greys")
    g = sns.factorplot(**kwargs)
    g.despine(top=False, right=False)
    plt.autoscale()
    plt.subplots_adjust(top=0.98)
    return g
//  [python]
def catplot(**kwargs: Any) -> Any:
    # kwargs.setdefault("palette", "Greys")
    g = sns.catplot(**kwargs)
    g.despine(top=False, right=False)
    plt.autoscale()
    plt.subplots_adjust(top=0.98)
    return g
//  [python]
def cat_plot(df, y, y_label):
    g = sns.factorplot(x="volume_target", y=y, hue="control_type", data=df,
                    height=6, kind="bar", palette="muted", legend=False)
    g.despine(left=True)
    g.set_ylabels(y_label)
    plt.legend(title="control_type", loc="lower right", frameon=True)
    plt.show()
//  [python]
def cat_plot(df, y, y_label):
    g = sns.catplot(x="volume_target", y=y, hue="control_type", data=df,
                    height=6, kind="bar", palette="muted", legend=False)
    g.despine(left=True)
    g.set_ylabels(y_label)
    plt.legend(title="control_type", loc="lower right", frameon=True)
    plt.show()
//  [python]
def draw_cat_plot():
    # Create DataFrame for cat plot using `pd.melt` using just the values from 'cholesterol', 'gluc', 'smoke', 'alco', 'active', and 'overweight'.
    df_cat = pd.melt(df, id_vars=['cardio'], value_vars=['cholesterol', 'gluc', 'smoke', 'alco', 'active', 'overweight'])

    # Group and reformat the data to split it by 'cardio'. Show the counts of each feature. You will have to rename one of the collumns for the catplot to work correctly.
    df_cat = df_cat.groupby(['cardio', 'variable', 'value'])['value'].count().to_frame()
    df_cat.rename(columns={'value': 'total'}, inplace=True)
    df_cat.reset_index(inplace=True)

    # Draw the catplot with 'sns.catplot()'
    catplot = sns.factorplot(x='variable', y='total', hue='value', col='cardio', kind='bar', data=df_cat)
    fig = catplot.fig

    # Do not modify the next two lines
    fig.savefig('catplot.png')
    return fig
//  [python]
def draw_cat_plot():
    # Create DataFrame for cat plot using `pd.melt` using just the values from 'cholesterol', 'gluc', 'smoke', 'alco', 'active', and 'overweight'.
    df_cat = pd.melt(df, id_vars=['cardio'], value_vars=['cholesterol', 'gluc', 'smoke', 'alco', 'active', 'overweight'])

    # Group and reformat the data to split it by 'cardio'. Show the counts of each feature. You will have to rename one of the collumns for the catplot to work correctly.
    df_cat = df_cat.groupby(['cardio', 'variable', 'value'])['value'].count().to_frame()
    df_cat.rename(columns={'value': 'total'}, inplace=True)
    df_cat.reset_index(inplace=True)

    # Draw the catplot with 'sns.catplot()'
    catplot = sns.catplot(x='variable', y='total', hue='value', col='cardio', kind='bar', data=df_cat)
    fig = catplot.fig

    # Do not modify the next two lines
    fig.savefig('catplot.png')
    return fig
//  [python]
def plot_pain_against_rating(data):
    
    """Plot average pain against rating (from diary) """
    
    sns.set(style="darkgrid")
    r=sns.swarmplot(x="rating_encoded", y="average_pain", data=data);
    r.set(xticklabels=["not great","ups and downs","ok","pretty good","good","great"])
    
    plt.show()
//  [python]
def plot_pain_against_rating(data):
    
    """Plot average pain against rating (from diary) """
    
    sns.set(style="darkgrid")
    r=sns.catplot(x="rating_encoded", y="average_pain", kind="swarm", data=data);
    r.set(xticklabels=["not great","ups and downs","ok","pretty good","good","great"])
    
    plt.show()