code: def create_plots(
      df: pd.DataFrame,
      output_folder: tp.PathLike,
      max_combsize: int = 1,
      xpaxis: str = "budget",
      competencemaps: bool = False,
      nomanyxp: bool = False,
  ) -> None:
      """Saves all representing plots to the provided folder
  
      Parameters
      ----------
      df: pd.DataFrame
          the experiment data
      output_folder: PathLike
          path of the folder where the plots should be saved
      max_combsize: int
          maximum number of parameters to fix (combinations) when creating experiment plots
      xpaxis: str
          x-axis for xp plots (either budget or pseudotime)
      """
      assert xpaxis in ["budget", "pseudotime"]
      df = remove_errors(df)
      df.loc[:, "loss"] = pd.to_numeric(df.loc[:, "loss"])
      df = df.loc[
          :, [x for x in df.columns if not x.startswith("info/")]
      ]
      # Normalization of types.
      for col in df.columns:
          if "max_irr" in col:
              df[col] = df[col].round(decimals=4)
          if col in (
              "budget",
              "num_workers",
              "dimension",
              "useful_dimensions",
              "num_blocks",
              "block_dimension",
              "num_objectives",
          ):
              try:
                  df[col] = df[col].astype(float).astype(int)
              except Exception as e1:
                  try:
                      for i in range(len(df[col])):
                          float(df[col][i])
                  except Exception as e2:
                      assert (
                          False
                      ), f"Fails at row {i+2}, Exceptions: {e1}, {e2}"
          elif col != "loss":
              df[col] = df[col].astype(str)
              df[col] = df[col].replace(r"\.[0]*$", "", regex=True)
              try:
                  df.loc[:, col] = pd.to_numeric(df.loc[:, col])
              except:
                  pass
      if "num_objectives" in df.columns:
          df = df[
              df.num_objectives != 0
          ]  # the optimization did not even start
      # If we have a descriptor "instrum_str",
      # we assume that it describes the instrumentation as a string,
      # that we should include the various instrumentations as distinct curves in the same plot.
      # So we concat it at the end of the optimizer name, and we remove "parametrization"
      # from the descriptor.
      if "instrum_str" in set(df.columns):
          df.loc[:, "optimizer_name"] = (
              df.loc[:, "optimizer_name"] + df.loc[:, "instrum_str"]
          )
          df = df.drop(columns="instrum_str")
          df = df.drop(columns="dimension")
          if "parametrization" in set(df.columns):
              df = df.drop(columns="parametrization")
          if "instrumentation" in set(df.columns):
              df = df.drop(columns="instrumentation")
      df = utils.Selector(
          df.fillna("N-A")
      )  # remove NaN in non score values
      assert not any(
          "Unnamed: " in x for x in df.columns
      ), f"Remove the unnamed index column:  {df.columns}"
      assert (
          "error " not in df.columns
      ), f"Remove error rows before plotting"
      required = {
          "optimizer_name",
          "budget",
          "loss",
          "elapsed_time",
          "elapsed_budget",
      }
      missing = required - set(df.columns)
      assert not missing, f"Missing fields: {missing}"
      output_folder = Path(output_folder)
      os.makedirs(output_folder, exist_ok=True)
      # check which descriptors do vary
      descriptors = sorted(
          set(df.columns)
          - (required | {"instrum_str", "seed", "pseudotime"})
      )  # all other columns are descriptors
      to_drop = [x for x in descriptors if len(df.unique(x)) == 1]
      df = utils.Selector(
          df.loc[:, [x for x in df.columns if x not in to_drop]]
      )
      # now those should be actual interesting descriptors
      all_descriptors = sorted(
          set(df.columns)
          - (required | {"instrum_str", "seed", "pseudotime"})
      )
      print(f"Descriptors: {all_descriptors}")
      print("# Fight plots")
      #
      # fight plot
      # choice of the combination variables to fix
      fight_descriptors = all_descriptors + [
          "budget"
      ]  # budget can be used as a descriptor for fight plots
      combinable = [
          x for x in fight_descriptors if len(df.unique(x)) > 1
      ]  # should be all now
      # We remove descriptors which have only one value for each budget.
      descriptors = []
      for d in all_descriptors:
          acceptable = False
          for b in df.budget.unique():
              if len(df.loc[df["budget"] == b][d].unique()) > 1:
                  acceptable = True
                  break
          if acceptable:
              descriptors += [d]
      num_rows = 6
  
      # For the competence map case we must consider pairs of attributes, hence maxcomb_size >= 2.
      # A competence map shows for each value of each of two attributes which algorithm was best.
      if competencemaps:
          max_combsize = max(max_combsize, 2)
      for fixed in list(
          itertools.chain.from_iterable(
              itertools.combinations(combinable, order)
              for order in range(max_combsize + 1)
          )
      ):
          orders = [len(c) for c in df.unique(fixed)]
          if orders:
              assert min(orders) == max(orders)
              order = min(orders)
          else:
              order = 0
          best_algo: tp.List[tp.List[str]] = []
          if (
              competencemaps and order == 2
          ):  # With order 2 we can create a competence map.
              print("\n#trying to competence-map")
              if all(
                  [len(c) > 1 for c in df.unique(fixed)]
              ):  # Let us try if data are adapted to competence maps.
                  # This is not always the case, as some attribute1/value1 + attribute2/value2 might be empty
                  # (typically when attribute1 and attribute2 are correlated).
                  try:
                      xindices = sorted(
                          set(c[0] for c in df.unique(fixed))
                      )
                  except TypeError:
                      xindices = list(
                          set(c[0] for c in df.unique(fixed))
                      )
                  try:
                      yindices = sorted(
                          set(c[1] for c in df.unique(fixed))
                      )
                  except TypeError:
                      yindices = list(
                          set(c[1] for c in df.unique(fixed))
                      )
                  for _ in range(len(xindices)):
                      best_algo += [[]]
                  for i in range(len(xindices)):
                      for _ in range(len(yindices)):
                          best_algo[i] += ["none"]
  
          # Let us loop over all combinations of variables.
          for case in df.unique(fixed) if fixed else [()]:
              print("\n# new case #", fixed, case)
              casedf = df.select(**dict(zip(fixed, case)))
              data_df = FightPlotter.winrates_from_selection(
                  casedf,
                  fight_descriptors,
                  num_rows=num_rows,
                  num_cols=350,
              )
              fplotter = FightPlotter(data_df)
              # Competence maps: we find out the best algorithm for each attribute1=valuei/attribute2=valuej.
              if order == 2 and competencemaps and best_algo:
                  print("\n#storing data for competence-map")
                  best_algo[xindices.index(case[0])][
                      yindices.index(case[1])
                  ] = fplotter.winrates.index[0]
              # save
              name = (
                  "fight_"
                  + ",".join(
                      "{}{}".format(x, y) for x, y in zip(fixed, case)
                  )
                  + ".png"
              )
              name = "fight_all.png" if name == "fight_.png" else name
              name = compactize(name)
              fullname = name
  
              if len(name) > 240:
                  hashcode = hashlib.md5(
                      bytes(name, "utf8")
                  ).hexdigest()
                  name = re.sub(r"\([^()]*\)", "", name)
                  mid = 120
                  name = name[:mid] + hashcode + name[-mid:]
              fplotter.save(str(output_folder / name), dpi=_DPI)
              # Second version, restricted to cases with all data available.
              data_df = FightPlotter.winrates_from_selection(
                  casedf,
                  fight_descriptors,
                  num_rows=num_rows,
                  complete_runs_only=True,
              )
              fplotter = FightPlotter(data_df)
              if name == "fight_all.png":
                  with open(
                      str(output_folder / name) + ".cp.txt", "w"
                  ) as f:
                      f.write(fullname)
                      f.write("ranking:\n")
                      global pure_algorithms
                      pure_algorithms = list(data_df.columns[:])
                      for i, algo in enumerate(data_df.columns[:158]):
                          f.write(f"  algo {i}: {algo}\n")
              if name == "fight_all.png":
                  fplotter.save(
                      str(output_folder / "fight_all_pure.png"),
                      dpi=_DPI,
                  )
              else:
                  fplotter.save(
                      str(output_folder / name) + "_pure.png", dpi=_DPI
                  )
                  print(
                      f"# {len(data_df.columns[:])}  {data_df.columns[:]}"
                  )
              if (
                  order == 2 and competencemaps and best_algo
              ):  # With order 2 we can create a competence map.
                  print("\n# Competence map")
                  name = (
                      "competencemap_"
                      + ",".join("{}".format(x) for x in fixed)
                      + ".tex"
                  )
                  export_table(
                      str(output_folder / name),
                      xindices,
                      yindices,
                      best_algo,
                  )
                  print("Competence map data:", fixed, case, best_algo)
  
      plt.close("all")
      # xp plots: for each experimental setup, we plot curves with budget in x-axis.
      # plot mean loss / budget for each optimizer for 1 context
      print("# Xp plots")
      name_style = NameStyle()  # keep the same style for each algorithm
      cases = df.unique(descriptors)
      if not cases:
          cases = [()]
      # Average normalized plot with everything.
      out_filepath = output_folder / "xpresults_all.png"
      data = XpPlotter.make_data(df, normalized_loss=True)
      xpplotter = XpPlotter(
          data,
          title=os.path.basename(output_folder),
          name_style=name_style,
          xaxis=xpaxis,
          pure_only=True,
      )
      xpplotter.save(out_filepath)
      # Now one xp plot per case.
      for case in cases:
          if nomanyxp:
              continue
          subdf = df.select_and_drop(**dict(zip(descriptors, case)))
          description = ",".join(
              "{}:{}".format(x, y) for x, y in zip(descriptors, case)
          )
          full_description = description
          description = compactize(description)
          if len(description) > 280:
              hash_ = hashlib.md5(
                  bytes(description, "utf8")
              ).hexdigest()
              description = (
                  description[:140] + hash_ + description[-140:]
              )
          out_filepath = output_folder / "xpresults{}{}.png".format(
              "_" if description else "", description.replace(":", "")
          )
          txt_out_filepath = (
              output_folder
              / "xpresults{}{}.leaderboard.txt".format(
                  "_" if description else "",
                  description.replace(":", ""),
              )
          )
          data = XpPlotter.make_data(subdf)
          try:
              xpplotter = XpPlotter(
                  data,
                  title=description,
                  name_style=name_style,
                  xaxis=xpaxis,
              )
          except Exception as e:  # pylint: disable=broad-except
              warnings.warn(
                  f"Bypassing error in xpplotter:\n{e}", RuntimeWarning
              )
          else:
              xpplotter.save(out_filepath)
              xpplotter.save_txt(
                  txt_out_filepath, data, full_description
              )
      plt.close("all")
  
imports: import os
  import re
  import string
  import hashlib
  import warnings
  import argparse
  import itertools
  from collections import defaultdict
  from pathlib import Path
  import numpy
  import pandas
  from matplotlib import pyplot
  from matplotlib.legend import Legend
  from matplotlib import cm
  from mpl_toolkits.axes_grid1 import make_axes_locatable
  import nevergrad.common.typing
  from .None import utils
  from .exporttable import export_table
label_desc: Use image node_id 9 for calling a global function with example usage: create_plots(df, output_folder, max_combsize, xpaxis, competencemaps, nomanyxp) without return types