code: def generate_fig_comparing_bins(
      data: Tuple,
      display_settings: Dict[str, Any],
  ) -> None:
      """
      Generate figures comparing localization error, error bounds accuracy, and Jaccard index for different binning
      configurations.
  
      Args:
          data (Tuple): A tuple containing various inputs needed to generate the figures. The tuple should include the following elements:
              - uncertainty_error_pair (Tuple[float, float]): A tuple representing the mean and standard deviation of
              the noise uncertainty used during training and evaluation.
              - model (str): The name of the model being evaluated.
              - dataset (str): The name of the dataset being used.
              - targets (List[int]): A list of target indices being evaluated.
              - all_values_q (List[int]): A list of integers representing the number of bins being used for each evaluation.
              - cmaps (List[str]): A list of colormap names to use for plotting.
              - all_fitted_save_paths (List[str]): A list of file paths where the binned data is stored.
              - save_folder (str): The directory where the figures should be saved.
              - save_file_preamble (str): The prefix to use for all figure file names.
              - combine_middle_bins (bool): Whether to combine the middle bins or not.
              - save_figures_bool (bool): Whether to save the generated figures or not. If false, shows instead.
              - samples_as_dots_bool (bool): Whether to show individual samples as dots in the box plots or not.
              - show_sample_info_mode (str): The mode for showing sample information in the box plots.
              - box_plot_error_lim (float): The y-axis limit for the error box plots.
              - show_individual_target_plots (bool): Whether to generate individual plots for each target.
              - interpret (bool): Whether the results are being interpreted.
              - num_folds (int): The number of cross-validation folds to use.
              - ind_targets_to_show (List[int]): A list of target indices to show in individual plots.
              - error_scaling_factor (float, optional): Scaling factor for error. Defaults to 1.0.
  
          display_settings: Dictionary containing the following keys:
              - 'hatch': String representing the type of hatch pattern to use in the plots.
              - 'color': String representing the color to use for the plots.
  
      Returns:
          None.
      """
  
      # Unpack data and logging settings
      [
          uncertainty_error_pair,
          model,
          dataset,
          targets,
          all_values_q,
          cmaps,
          all_fitted_save_paths,
          save_folder,
          save_file_preamble,
          combine_middle_bins,  # cfg["PIPELINE"]["COMBINE_MIDDLE_BINS"]
          save_figures_bool,  # cfg["OUTPUT"]["SAVE_FIGURES"]
          samples_as_dots_bool,  # cfg["BOXPLOT"]["SAMPLES_AS_DOTS"]
          show_sample_info_mode,  # cfg["BOXPLOT"]["SHOW_SAMPLE_INFO_MODE"]
          box_plot_error_lim,  # cfg["BOXPLOT"]["ERROR_LIM"]
          show_individual_target_plots,
          interpret,
          num_folds,
          ind_targets_to_show,
          error_scaling_factor,
      ] = data
  
      logger = logging.getLogger("qbin")
  
      hatch = display_settings["hatch"]
      color = display_settings["color"]
  
      # increse dimension of these for compatibility with future methods
      model_list = [model]
      uncertainty_error_pair_list = [uncertainty_error_pair]
  
      # If combining the middle bins we just have the 2 edge bins, and the combined middle ones.
  
      all_error_data = []
      all_error_target_sep = []
      all_bins_concat_targets_nosep_error = []
      all_bins_concat_targets_sep_foldwise_error = []
      all_bins_concat_targets_sep_all_error = []
      all_jaccard_data = []
      all_recall_data = []
      all_precision_data = []
      all_bins_concat_targets_sep_foldwise_jacc = []
      all_bins_concat_targets_sep_all_jacc = []
      all_bound_data = []
      all_bins_concat_targets_sep_foldwise_errorbound = []
      all_bins_concat_targets_sep_all_errorbound = []
  
      for idx, num_bins in enumerate(all_values_q):
          saved_bins_path_pre = all_fitted_save_paths[idx]
  
          (
              bins_all_targets,
              bins_targets_sep,
              bounds_all_targets,
              bounds_targets_sep,
          ) = generate_struct_for_qbin(
              model_list, targets, saved_bins_path_pre, dataset
          )
  
          # Get mean errors bin-wise, get all errors concatenated together bin-wise, and seperate by target.
          all_error_data_dict = get_mean_errors(
              bins_all_targets,
              uncertainty_error_pair_list,
              num_bins,
              targets,
              num_folds=num_folds,
              error_scaling_factor=error_scaling_factor,
              combine_middle_bins=combine_middle_bins,
          )
          all_error_data.append(
              all_error_data_dict["all mean error bins nosep"]
          )
          all_error_target_sep.append(
              all_error_data_dict["all mean error bins targets sep"]
          )
  
          all_bins_concat_targets_nosep_error.append(
              all_error_data_dict["all error concat bins targets nosep"]
          )  # shape is [num bins]
          all_bins_concat_targets_sep_foldwise_error.append(
              all_error_data_dict[
                  "all error concat bins targets sep foldwise"
              ]
          )  # shape is [num targets][num bins]
          all_bins_concat_targets_sep_all_error.append(
              all_error_data_dict[
                  "all error concat bins targets sep all"
              ]
          )  # same as all_bins_concat_targets_sep_foldwise but folds are flattened to a single list
  
          all_jaccard_data_dict = evaluate_jaccard(
              bins_all_targets,
              uncertainty_error_pair_list,
              num_bins,
              targets,
              num_folds=num_folds,
              combine_middle_bins=combine_middle_bins,
          )
          all_jaccard_data.append(all_jaccard_data_dict["Jaccard All"])
          all_recall_data.append(all_jaccard_data_dict["Recall All"])
          all_precision_data.append(
              all_jaccard_data_dict["Precision All"]
          )
          all_bins_concat_targets_sep_foldwise_jacc.append(
              all_jaccard_data_dict[
                  "all jacc concat bins targets sep foldwise"
              ]
          )  # shape is [num targets][num bins]
          all_bins_concat_targets_sep_all_jacc.append(
              all_jaccard_data_dict[
                  "all jacc concat bins targets sep all"
              ]
          )  # same as all_bins_concat_targets_sep_foldwise but folds are flattened to a single list
  
          bound_return_dict = evaluate_bounds(
              bounds_all_targets,
              bins_all_targets,
              uncertainty_error_pair_list,
              num_bins,
              targets,
              num_folds,
              combine_middle_bins=combine_middle_bins,
          )
  
          all_bound_data.append(bound_return_dict["Error Bounds All"])
          all_bins_concat_targets_sep_foldwise_errorbound.append(
              bound_return_dict[
                  "all errorbound concat bins targets sep foldwise"
              ]
          )  # shape is [num targets][num bins]
          all_bins_concat_targets_sep_all_errorbound.append(
              bound_return_dict[
                  "all errorbound concat bins targets sep all"
              ]
          )  # same as all_bins_concat_targets_sep_foldwise but folds are flattened to a single list
  
      if interpret:
          # If we have combined the middle bins, we are only displaying 3 bins (outer edges, and combined middle bins).
          if combine_middle_bins:
              num_bins_display = 3
          else:
              num_bins_display = num_bins
  
          # Set x_axis labels for following plots.
          x_axis_labels = [str(x) for x in all_values_q]
          save_location = None
  
          # get error bounds
  
          if display_settings["errors"]:
              # mean error concat for each bin
              logger.info("mean error concat all L")
              if save_figures_bool:
                  if samples_as_dots_bool:
                      dotted_addition = "_dotted"
                  else:
                      dotted_addition = "_undotted"
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble
                      + dotted_addition
                      + "_error_all_targets.pdf",
                  )
  
              box_plot_comparing_q(
                  all_bins_concat_targets_nosep_error,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Localization Error (mm)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=False,
                  show_sample_info=show_sample_info_mode,
                  show_individual_dots=samples_as_dots_bool,
                  y_lim=box_plot_error_lim,
                  to_log=True,
                  save_path=save_location,
              )
  
              if show_individual_target_plots:
                  # plot the concatentated errors for each target seperately. Must transpose the iteration.
                  for target_idx in targets:
                      target_data = [
                          x[target_idx]
                          for x in all_bins_concat_targets_sep_all_error
                      ]
  
                      if (
                          target_idx in ind_targets_to_show
                          or ind_targets_to_show == [-1]
                      ):
                          if save_figures_bool:
                              save_location = os.path.join(
                                  save_folder,
                                  save_file_preamble
                                  + dotted_addition
                                  + "_error_target_"
                                  + str(target_idx)
                                  + ".pdf",
                              )
  
                          logger.info(
                              "individual error for T%s", target_idx
                          )
                          box_plot_comparing_q(
                              target_data,
                              uncertainty_error_pair_list,
                              model_list,
                              hatch_type=hatch,
                              color=color,
                              x_axis_labels=x_axis_labels,
                              x_label="Q (# Bins)",
                              y_label="Localization Error (mm)",
                              num_bins_display=num_bins_display,
                              convert_to_percent=False,
                              show_sample_info=show_sample_info_mode,
                              show_individual_dots=samples_as_dots_bool,
                              y_lim=box_plot_error_lim,
                              to_log=True,
                              save_path=save_location,
                          )
  
              if save_figures_bool:
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble
                      + dotted_addition
                      + "mean_error_folds_all_targets.pdf",
                  )
              box_plot_comparing_q(
                  all_error_data,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Mean Error (mm)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=False,
                  show_sample_info="None",
                  show_individual_dots=False,
                  y_lim=box_plot_error_lim,
                  to_log=True,
                  save_path=save_location,
              )
  
          # Plot Error Bound Accuracy
  
          if display_settings["error_bounds"]:
              logger.info(" errorbound acc for all targets.")
              if save_figures_bool:
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble
                      + "_errorbound_all_targets.pdf",
                  )
  
              box_plot_comparing_q(
                  all_bound_data,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Error Bound Accuracy (%)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=True,
                  show_sample_info="None",
                  show_individual_dots=False,
                  y_lim=100,
                  save_path=save_location,
              )
  
              if show_individual_target_plots:
                  # plot the concatentated errors for each target seperately. Must transpose the iteration.
                  for target_idx in targets:
                      target_data = [
                          x[target_idx]
                          for x in all_bins_concat_targets_sep_all_errorbound
                      ]
  
                      if (
                          target_idx in ind_targets_to_show
                          or ind_targets_to_show == [-1]
                      ):
                          if save_figures_bool:
                              save_location = os.path.join(
                                  save_folder,
                                  save_file_preamble
                                  + "_errorbound_target_"
                                  + str(target_idx)
                                  + ".pdf",
                              )
  
                          logger.info(
                              "individual errorbound acc for T%s",
                              target_idx,
                          )
                          box_plot_comparing_q(
                              target_data,
                              uncertainty_error_pair_list,
                              model_list,
                              hatch_type=hatch,
                              color=color,
                              x_axis_labels=x_axis_labels,
                              x_label="Q (# Bins)",
                              y_label="Error Bound Accuracy (%)",
                              num_bins_display=num_bins_display,
                              convert_to_percent=True,
                              show_individual_dots=False,
                              y_lim=100,
                              save_path=save_location,
                          )
  
          # Plot Jaccard Index
          if display_settings["jaccard"]:
              logger.info("Plot jaccard for all targets.")
              if save_figures_bool:
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble + "_jaccard_all_targets.pdf",
                  )
  
              box_plot_comparing_q(
                  all_jaccard_data,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Jaccard Index (%)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=True,
                  show_individual_dots=False,
                  y_lim=70,
                  save_path=save_location,
              )
  
              # mean recall for each bin
              logger.info("Plot recall for all targets.")
  
              if save_figures_bool:
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble
                      + "_recall_jaccard_all_targets.pdf",
                  )
              box_plot_comparing_q(
                  all_recall_data,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Ground Truth Bin Recall (%)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=True,
                  show_individual_dots=False,
                  y_lim=120,
                  save_path=save_location,
              )
  
              # mean precision for each bin
              logger.info("Plot precision for all targets.")
  
              if save_figures_bool:
                  save_location = os.path.join(
                      save_folder,
                      save_file_preamble
                      + "_precision_jaccard_all_targets.pdf",
                  )
              box_plot_comparing_q(
                  all_precision_data,
                  uncertainty_error_pair_list,
                  model_list,
                  hatch_type=hatch,
                  color=color,
                  x_axis_labels=x_axis_labels,
                  x_label="Q (# Bins)",
                  y_label="Ground Truth Bin Precision (%)",
                  num_bins_display=num_bins_display,
                  convert_to_percent=True,
                  show_individual_dots=False,
                  y_lim=120,
                  save_path=save_location,
              )
  
              if show_individual_target_plots:
                  # plot the concatentated errors for each target seperately. Must transpose the iteration.
                  for target_idx in targets:
                      target_data = [
                          x[target_idx]
                          for x in all_bins_concat_targets_sep_all_jacc
                      ]
  
                      if (
                          target_idx in ind_targets_to_show
                          or ind_targets_to_show == [-1]
                      ):
                          if save_figures_bool:
                              save_location = os.path.join(
                                  save_folder,
                                  save_file_preamble
                                  + "jaccard_target_"
                                  + str(target_idx)
                                  + ".pdf",
                              )
  
                          logger.info(
                              "individual jaccard for T%s", target_idx
                          )
                          box_plot_comparing_q(
                              target_data,
                              uncertainty_error_pair_list,
                              model_list,
                              hatch_type=hatch,
                              color=color,
                              x_axis_labels=x_axis_labels,
                              x_label="Q (# Bins)",
                              y_label="Jaccard Index (%)",
                              num_bins_display=num_bins_display,
                              convert_to_percent=True,
                              show_individual_dots=False,
                              y_lim=70,
                              save_path=save_location,
                          )
  
imports: import logging
  import math
  import os
  from typing import Any, Dict, List, Optional, Tuple, Union
  import matplotlib.lines
  import matplotlib.patches
  import matplotlib.pyplot
  import matplotlib.ticker
  import numpy
  import pandas
  import pwlf
  from matplotlib.ticker import ScalarFormatter
  from scipy import stats
  from sklearn.isotonic import IsotonicRegression
  from kale.evaluate.similarity_metrics import evaluate_correlations
  from kale.evaluate.uncertainty_metrics import evaluate_bounds, evaluate_jaccard, get_mean_errors
  from kale.prepdata.tabular_transform import generate_struct_for_qbin
  from kale.utils.save_xlsx import generate_summary_df
label_desc: Use image node_id 9 for calling a global function with example usage: generate_fig_comparing_bins(data, display_settings) without return types