class_docstr: Creates a fight plot out of the given dataframe, by iterating over all cases with fixed category variables.
  
  Parameters
  ----------
  winrates_df: pd.DataFrame
      winrate data as a dataframe
docstr: Creates a fight plot win rate data out of the given run dataframe,
  by iterating over all cases with fixed category variables.
  
  Parameters
  ----------
  df: pd.DataFrame
      run data
  categories: list
      List of variables to fix for obtaining similar run conditions
  num_rows: int
      number of rows to plot (best algorithms)
  complete_runs_only: bool
      if we want a plot with only algorithms which have run on all settings
docstr_tok: ["Creates","a","fight","plot","win","rate","data","out","of","the","given","run","dataframe",",","by","iterating","over","all","cases","with","fixed","category","variables",".","Parameters","--","--","--","--","--","df",":","pd.DataFrame","run","data","categories",":","list","List","of","variables","to","fix","for","obtaining","similar","run","conditions","num_rows",":","int","number","of","rows","to","plot","(","best","algorithms",")","complete_runs_only",":","bool","if","we","want","a","plot","with","only","algorithms","which","have","run","on","all","settings"]
code: def winrates_from_selection(
      df: utils.Selector,
      categories: tp.List[str],
      num_rows: int = 5,
      num_cols: int = 350,
      complete_runs_only: bool = False,
  ) -> pd.DataFrame:
      """Creates a fight plot win rate data out of the given run dataframe,
      by iterating over all cases with fixed category variables.
  
      Parameters
      ----------
      df: pd.DataFrame
          run data
      categories: list
          List of variables to fix for obtaining similar run conditions
      num_rows: int
          number of rows to plot (best algorithms)
      complete_runs_only: bool
          if we want a plot with only algorithms which have run on all settings
      """
      all_optimizers = list(
          df.unique("optimizer_name")
      )  # optimizers for which no run exists are not shown
      num_rows = min(num_rows, len(all_optimizers))
      # iterate on all sub cases
      victories, total = aggregate_winners(
          df, categories, all_optimizers
      )
      if complete_runs_only:
          max_num = max(
              [int(2 * victories.loc[n, n]) for n in all_optimizers]
          )
          new_all_optimizers = [
              n
              for n in all_optimizers
              if int(2 * victories.loc[n, n]) == max_num
          ]
          if len(new_all_optimizers) > 0:
              df = df[df["optimizer_name"].isin(new_all_optimizers)]
              victories, total = aggregate_winners(
                  df, categories, new_all_optimizers
              )
      # subcases = df.unique(categories)
      # for k, subcase in enumerate(subcases):  # TODO linearize this (precompute all subcases)? requires memory
      #     # print(subcase)
      #     subdf = df.select(**dict(zip(categories, subcase)))
      #     victories += _make_winners_df(subdf, all_optimizers)
      #     if k > 1000:
      #         break
      winrates = _make_sorted_winrates_df(victories)
      mean_win = winrates.mean(axis=1)
      winrates.fillna(0.5)  # unplayed
      sorted_names = winrates.index
      # number of subcases actually computed is twice self-victories
      sorted_names = [
          "{} ({}/{})".format(n, int(2 * victories.loc[n, n]), total)
          for n in sorted_names
      ]
      num_names = len(sorted_names)
      sorted_names = [
          sorted_names[i] for i in range(min(num_cols, num_names))
      ]
      data = np.array(winrates.iloc[:num_rows, : len(sorted_names)])
      # pylint: disable=anomalous-backslash-in-string
      best_names = [
          (
              f"{name} ({i+1}/{num_names}:{100 * val:2.1f}% +- {25 * np.sqrt(val*(1-val)/int(2 * victories.loc[name, name])):2.1f})"
          ).replace("Search", "")
          for i, (name, val) in enumerate(
              zip(mean_win.index[:num_rows], mean_win)
          )
      ]
      return pd.DataFrame(
          index=best_names, columns=sorted_names, data=data
      )
  
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 2 for calling the FightPlotter obj's underlying member method code with example usage: obj.winrates_from_selection(df, categories, num_rows, num_cols, complete_runs_only) and returns: pd