//  [python]
def generate_report_labeled(
        df_metrics,
        keypoint_names,
        model_names,
        save_dir,
        format="pdf",
        box_kwargs={},
        scatter_kwargs={},
        savefig_kwargs={}
):

    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    # parse inputs
    box_kwargs_default = {
        "plot_type": "boxen",
        "plot_scale": "log",
        "data_type": "test",
    }
    box_kwargs = update_kwargs_dict_with_defaults(box_kwargs, box_kwargs_default)

    scatter_kwargs_default = {
        "plot_scale": "log",
        "data_type": "test",
        "model_0": "model_0",
        "model_1": "model_1",
    }
    scatter_kwargs = update_kwargs_dict_with_defaults(scatter_kwargs, scatter_kwargs_default)

    metrics_to_plot = df_metrics.keys()

    # ---------------------------------------------------
    # plot metrics for all models (catplot)
    # ---------------------------------------------------
    for metric_to_plot in metrics_to_plot:

        df_filtered = df_metrics[metric_to_plot][
            df_metrics[metric_to_plot].set == box_kwargs["data_type"]]
        n_frames_per_dtype = df_filtered.shape[0] // len(df_filtered.model_name.unique())

        y_label = get_y_label(metric_to_plot)

        # plot ALL data
        n_cols = 3
        df_box = get_df_box(df_filtered, keypoint_names, model_names)
        sns.set_context("paper")
        title = "All keypoints (%i %s frames)" % (n_frames_per_dtype, box_kwargs["data_type"])
        fig_box = sns.catplot(
            x="model_name", y="value", col="keypoint", col_wrap=n_cols, sharey=False,
            kind=box_kwargs["plot_type"], data=df_box, height=2)
        fig_box.set_axis_labels("Model Name", y_label)
        fig_box.set_xticklabels(rotation=45, ha="right")
        fig_box.set(yscale=box_kwargs["plot_scale"])
        fig_box.fig.subplots_adjust(top=0.94)
        fig_box.fig.suptitle(title)
        save_file = os.path.join(save_dir, "barplot-all_%s.%s" % (metric_to_plot, format))
        plt.savefig(save_file, dpi=300, format=format, **savefig_kwargs)

        # plot mean data
        keypoint_to_plot = "mean"
        title = 'Mean keypoints (%i %s frames)' % (n_frames_per_dtype, box_kwargs["data_type"])
        log_y = False if box_kwargs["plot_scale"] == "linear" else True
        make_seaborn_catplot(
            x="model_name", y=keypoint_to_plot, data=df_filtered, x_label="Model Name",
            y_label=y_label, title=title, log_y=log_y, plot_type=box_kwargs["plot_type"])
        save_file = os.path.join(save_dir, "barplot-mean_%s.%s" % (metric_to_plot, format))
        plt.savefig(save_file, dpi=300, format=format, **savefig_kwargs)

    # ---------------------------------------------------
    # plot metrics for a pair of models (scatterplot)
    # ---------------------------------------------------
    for metric_to_plot in metrics_to_plot:

        model_0 = scatter_kwargs["model_0"]
        model_1 = scatter_kwargs["model_1"]

        df_tmp0 = df_metrics[metric_to_plot][df_metrics[metric_to_plot].model_name == model_0]
        df_tmp1 = df_metrics[metric_to_plot][df_metrics[metric_to_plot].model_name == model_1]

        y_label = get_y_label(metric_to_plot)

        # ---------------
        # plot ALL data
        # ---------------
        n_cols = 3
        df_scatter = get_df_scatter(
            df_tmp0, df_tmp1, scatter_kwargs["data_type"], [model_0, model_1], keypoint_names)
        title = "All keypoints (%i %s frames)" % (n_frames_per_dtype, scatter_kwargs["data_type"])
        fig_scatter = make_plotly_scatterplot(
            model_0=model_0, model_1=model_1, df=df_scatter,
            metric_name=y_label, title=title,
            axes_scale=scatter_kwargs["plot_scale"],
            facet_col="keypoint", n_cols=n_cols,
            fig_height=300 * np.ceil(len(keypoint_names) / n_cols), fig_width=900,
        )
        save_file = os.path.join(save_dir, "scatterplot-all_%s.%s" % (metric_to_plot, format))
        fig_scatter.write_image(save_file)

        # ---------------
        # plot mean data
        # ---------------
        keypoint_to_plot = "mean"
        df_scatter = pd.DataFrame({
            model_0: df_tmp0[keypoint_to_plot][df_tmp0.set == scatter_kwargs["data_type"]],
            model_1: df_tmp1[keypoint_to_plot][df_tmp1.set == scatter_kwargs["data_type"]],
        })
        fig_scatter = make_plotly_scatterplot(
            model_0=model_0, model_1=model_1, df=df_scatter,
            metric_name=y_label, title=title,
            axes_scale=scatter_kwargs["plot_scale"],
            fig_height=500, fig_width=500,
        )
        save_file = os.path.join(save_dir, "scatterplot-mean_%s.%s" % (metric_to_plot, format))
        fig_scatter.write_image(save_file)