code: def box_plot_comparing_q(
      target_uncert_dicts_list: List[Dict[str, List[List[float]]]],
      uncertainty_type_tuple: List,
      model: List[str],
      x_axis_labels: List[str],
      x_label: str,
      y_label: str,
      num_bins_display: int,
      hatch_type: str,
      color: str,
      show_sample_info: str = "None",
      save_path: Optional[str] = None,
      y_lim: int = 120,
      convert_to_percent: bool = True,
      to_log: bool = False,
      show_individual_dots: bool = True,
  ) -> None:
      """
      Creates a box plot of data, using Q (# Bins) on the x-axis.
      Only compares 1 model & 1 uncertainty type using Q on the x-axis.
  
      Args:
          target_uncert_dicts_list (List[Dict[str, List[List[float]]]]):
              List of Dict of pandas dataframe for the data to dsiplay, 1 for each value for Q.
          uncertainty_type_tuple (Tuple[str, str]):
              Tuple describing the single uncertainty/error type to display.
          model (Tuple[str, str]):
              The model we are comparing over our values of Q.
          x_axis_labels (List[str]):
              List of strings for the x-axis labels, one for each bin.
          x_label (str):
              X-axis label.
          y_label (str):
              Y-axis label.
          num_bins_display (List[int]):
              List of values of Q (#bins) we are comparing on our x-axis.
          hatch_type (str):
              Hatch type for the box plot.
          color (str):
              color for the box plot.
          show_sample_info (str, optional):
              Whether or not to show sample info on the plot.
              Options are "None", "All", or "Average". Defaults to "None".
          save_path (str, optional):
              Path to save plot to. If None, displays on screen. Defaults to None.
          y_lim (int, optional):
              Y-axis limit of graph. Defaults to 120.
          convert_to_percent (bool, optional):
              Whether to turn data to percentages. Defaults to True.
          to_log (bool, optional):
              Whether to set the y-axis to logarithmic scale. Defaults to False.
          show_individual_dots (bool, optional):
              Whether to show individual data points. Defaults to True.
      """
  
      plt.style.use("fivethirtyeight")
  
      orders = []
      ax = plt.gca()
      ax.xaxis.grid(False)
  
      bin_label_locs = []
      all_rects = []
      outer_min_x_loc = 0.0
      inner_min_x_loc = 0.0
      middle_min_x_loc = 0.0
  
      circ_patches = []
  
      uncertainty_type = uncertainty_type_tuple[0][0]
      model_type = model[0]
  
      # Set legend
      circ11 = patches.Patch(
          hatch=hatch_type,
          facecolor=color,
          label=model_type + " " + uncertainty_type,
          edgecolor="black",
      )
      circ_patches.append(circ11)
  
      max_bin_height = 0
      all_sample_label_x_locs = []
      all_sample_percs = []
  
      for idx, q_value in enumerate(x_axis_labels):
          inbetween_locs = []
          target_uncert_dicts = target_uncert_dicts_list[idx]
  
          # Get key for the model and uncetainty type for data
          dict_key = [
              x
              for x in list(target_uncert_dicts.keys())
              if (model_type in x) and (uncertainty_type in x)
          ][0]
          model_data = target_uncert_dicts[dict_key]
          average_samples_per_bin = []
          # Loop through each bin and display the data
          for j in range(len(model_data)):
              all_b_data = [x for x in model_data[j] if x is not None]
  
              orders.append(model_type + uncertainty_type)
  
              width = 0.2 * (4 / 5) ** idx
  
              x_loc = [
                  (outer_min_x_loc + inner_min_x_loc + middle_min_x_loc)
              ]
              inbetween_locs.append(x_loc[0])
  
              # Turn data to percentages
              if convert_to_percent:
                  displayed_data = [(x) * 100 for x in all_b_data]
              else:
                  displayed_data = all_b_data
              rect = ax.boxplot(
                  displayed_data,
                  positions=x_loc,
                  sym="",
                  widths=width,
                  showmeans=True,
                  patch_artist=True,
              )
  
              max_bin_height = max(
                  max(rect["caps"][-1].get_ydata()), max_bin_height
              )
  
              if show_individual_dots:
                  # Add some random "jitter" to the x-axis
                  x = np.random.normal(
                      x_loc, 0.01, size=len(displayed_data)
                  )
                  ax.plot(
                      x,
                      displayed_data,
                      color="crimson",
                      marker=".",
                      linestyle="None",
                      alpha=0.2,
                  )
  
              # Set color, pattern, median line and mean marker.
              for r in rect["boxes"]:
                  r.set(color="black", linewidth=1)
                  r.set(facecolor=color)
                  r.set_hatch(hatch_type)
              for median in rect["medians"]:
                  median.set(color="crimson", linewidth=3)
  
              for mean in rect["means"]:
                  mean.set(
                      markerfacecolor="crimson",
                      markeredgecolor="black",
                      markersize=10,
                  )
  
              """If we are showing sample statistics, keep track of it and display after on top of biggest whisker."""
              if show_sample_info != "None":
                  flattened_model_data = [
                      x for xss in model_data for x in xss
                  ]
                  percent_size = np.round(
                      len(all_b_data) / len(flattened_model_data) * 100,
                      1,
                  )
                  average_samples_per_bin.append(percent_size)
  
                  if show_sample_info == "All":
                      """This adds the number of samples on top of the top whisker"""
                      (x_l, y), (x_r, _) = rect["caps"][-1].get_xydata()
                      x_line_center = (x_l + x_r) / 2
                      all_sample_label_x_locs.append(
                          [x_line_center, y + 0.5]
                      )
                      all_sample_percs.append(percent_size)
  
              all_rects.append(rect)
              inner_min_x_loc += 0.02 + width
  
          outer_min_x_loc += 0.2
          bin_label_locs.append(np.mean(inbetween_locs))
  
          """ Keep track of average sample statistics. Plot at the END so we know what the max height for all Qs are."""
          if show_sample_info == "Average":
              middle_x = np.mean(inbetween_locs)
              mean_perc = np.round(np.mean(average_samples_per_bin), 1)
              std_perc = np.round(np.std(average_samples_per_bin), 1)
              all_sample_label_x_locs.append(middle_x)
              all_sample_percs.append([mean_perc, std_perc])
  
      format_plot(
          ax,
          save_path,
          show_sample_info,
          to_log,
          circ_patches,
          y_lim,
          -0.1,
          convert_to_percent,
          x_label,
          y_label,
          30,
          25,
          bin_label_locs,
          x_axis_labels,
          num_bins_display,
          uncertainty_type_tuple,
          all_sample_percs,
          all_sample_label_x_locs,
          max_bin_height,
          comparing_q=True,
      )
  
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 6 for calling a global function with example usage: box_plot_comparing_q(target_uncert_dicts_list, uncertainty_type_tuple, model, x_axis_labels, x_label, y_label, num_bins_display, hatch_type, color, show_sample_info, save_path, y_lim, convert_to_percent, to_log, show_individual_dots) without return types