nmoo.plotting.performance_indicators
Performance indicators plotting
1""" 2Performance indicators plotting 3""" 4__docformat__ = "google" 5 6from typing import Iterable, Optional 7 8import seaborn as sns 9 10from nmoo.benchmark import Benchmark 11 12 13# TODO: replace the benchmark argument by a benchmark_or_results_file_path, and 14# retrieve the relevant benchmark specifications from the csv file. 15def plot_performance_indicators( 16 benchmark: Benchmark, 17 row: Optional[str] = None, 18 *, 19 algorithms: Optional[Iterable[str]] = None, 20 performance_indicators: Optional[Iterable[str]] = None, 21 problems: Optional[Iterable[str]] = None, 22 legend: bool = True, 23 x: str = "n_gen", 24 logscale: bool = False, 25) -> sns.FacetGrid: 26 """ 27 Plots all performance indicators in a grid of line plots. 28 29 <center> 30 <img src="https://github.com/altaris/noisy-moo/raw/main/imgs/plot_performance_indicators.png" 31 alt="Example"/> 32 </center> 33 34 The columns of this grid correspond to the performance indicators, whereas 35 the rows can be set to correspond to either `n_run`, `problem` or 36 `algorithm`. For example, if `row="algorithm"` (as is the case above), then 37 each row will correspond to an algorithm, whereas `n_run` and `problem` 38 will be compounded in the line plots. If left to `None`, then `n_run`, 39 `problem` and `algorithm` will all be compounded together. 40 41 Note: 42 If you have the benchmark definition, the `benchmark.csv` file, but do 43 not want to rerun the benchmark, you can use the following trick: 44 45 benchmark = Benchmark(...) # Benchmark specification 46 benchmark._results = pd.read_csv(path_to_benchmark_csv) # Inject results 47 plot_performance_indicators(benchmark, ...) # Plot 48 49 Args: 50 benckmark: A (ran) benchmark object. 51 row (Optional[str]): See above. 52 algorithms (Optional[Iterable[str]]): List of algorithms to plot, 53 defaults to all. 54 performance_indicators (Optional[Iterable[str]]): List of performance 55 indicators to plot, defaults to all. 56 problems (Optional[Iterable[str]]): List of problems to plot, defaults 57 to all. 58 legend (bool): Wether to display the legend. Defaults to `True`. 59 logscale (bool): Wether to have a logarithmic y scale. Defaults to 60 `False`. 61 x (str): Column for the x axis. Should be among `n_gen` (the default), 62 `n_eval`, or `timedelta`. 63 """ 64 if algorithms is None: 65 algorithms = benchmark._algorithms.keys() 66 if performance_indicators is None: 67 performance_indicators = benchmark._performance_indicators 68 if problems is None: 69 problems = benchmark._problems.keys() 70 df = benchmark._results[ 71 ["algorithm", "n_eval", "n_gen", "n_run", "problem", "timedelta"] 72 + ["perf_" + pi for pi in performance_indicators] 73 ] 74 df = df[(df.algorithm.isin(algorithms)) & (df.problem.isin(problems))] 75 df.rename( 76 columns={f"perf_{pi}": pi for pi in performance_indicators}, 77 inplace=True, 78 ) 79 df = df.melt( 80 id_vars=[ 81 c for c in df.columns if c not in benchmark._performance_indicators 82 ], 83 var_name="pi", 84 ) 85 grid = sns.FacetGrid(df, col="pi", row=row, sharey=False) 86 if row == "algorithm": 87 grid.map_dataframe(sns.lineplot, x=x, y="value", hue="problem") 88 elif row == "problem": 89 grid.map_dataframe(sns.lineplot, x=x, y="value", hue="algorithm") 90 else: 91 grid.map_dataframe( 92 sns.lineplot, x=x, y="value", hue="algorithm", style="problem" 93 ) 94 if legend: 95 grid.add_legend() 96 if logscale: 97 grid.set(yscale="log") 98 return grid
def
plot_performance_indicators( benchmark: nmoo.benchmark.Benchmark, row: Union[str, NoneType] = None, *, algorithms: Union[Iterable[str], NoneType] = None, performance_indicators: Union[Iterable[str], NoneType] = None, problems: Union[Iterable[str], NoneType] = None, legend: bool = True, x: str = 'n_gen', logscale: bool = False) -> seaborn.axisgrid.FacetGrid:
16def plot_performance_indicators( 17 benchmark: Benchmark, 18 row: Optional[str] = None, 19 *, 20 algorithms: Optional[Iterable[str]] = None, 21 performance_indicators: Optional[Iterable[str]] = None, 22 problems: Optional[Iterable[str]] = None, 23 legend: bool = True, 24 x: str = "n_gen", 25 logscale: bool = False, 26) -> sns.FacetGrid: 27 """ 28 Plots all performance indicators in a grid of line plots. 29 30 <center> 31 <img src="https://github.com/altaris/noisy-moo/raw/main/imgs/plot_performance_indicators.png" 32 alt="Example"/> 33 </center> 34 35 The columns of this grid correspond to the performance indicators, whereas 36 the rows can be set to correspond to either `n_run`, `problem` or 37 `algorithm`. For example, if `row="algorithm"` (as is the case above), then 38 each row will correspond to an algorithm, whereas `n_run` and `problem` 39 will be compounded in the line plots. If left to `None`, then `n_run`, 40 `problem` and `algorithm` will all be compounded together. 41 42 Note: 43 If you have the benchmark definition, the `benchmark.csv` file, but do 44 not want to rerun the benchmark, you can use the following trick: 45 46 benchmark = Benchmark(...) # Benchmark specification 47 benchmark._results = pd.read_csv(path_to_benchmark_csv) # Inject results 48 plot_performance_indicators(benchmark, ...) # Plot 49 50 Args: 51 benckmark: A (ran) benchmark object. 52 row (Optional[str]): See above. 53 algorithms (Optional[Iterable[str]]): List of algorithms to plot, 54 defaults to all. 55 performance_indicators (Optional[Iterable[str]]): List of performance 56 indicators to plot, defaults to all. 57 problems (Optional[Iterable[str]]): List of problems to plot, defaults 58 to all. 59 legend (bool): Wether to display the legend. Defaults to `True`. 60 logscale (bool): Wether to have a logarithmic y scale. Defaults to 61 `False`. 62 x (str): Column for the x axis. Should be among `n_gen` (the default), 63 `n_eval`, or `timedelta`. 64 """ 65 if algorithms is None: 66 algorithms = benchmark._algorithms.keys() 67 if performance_indicators is None: 68 performance_indicators = benchmark._performance_indicators 69 if problems is None: 70 problems = benchmark._problems.keys() 71 df = benchmark._results[ 72 ["algorithm", "n_eval", "n_gen", "n_run", "problem", "timedelta"] 73 + ["perf_" + pi for pi in performance_indicators] 74 ] 75 df = df[(df.algorithm.isin(algorithms)) & (df.problem.isin(problems))] 76 df.rename( 77 columns={f"perf_{pi}": pi for pi in performance_indicators}, 78 inplace=True, 79 ) 80 df = df.melt( 81 id_vars=[ 82 c for c in df.columns if c not in benchmark._performance_indicators 83 ], 84 var_name="pi", 85 ) 86 grid = sns.FacetGrid(df, col="pi", row=row, sharey=False) 87 if row == "algorithm": 88 grid.map_dataframe(sns.lineplot, x=x, y="value", hue="problem") 89 elif row == "problem": 90 grid.map_dataframe(sns.lineplot, x=x, y="value", hue="algorithm") 91 else: 92 grid.map_dataframe( 93 sns.lineplot, x=x, y="value", hue="algorithm", style="problem" 94 ) 95 if legend: 96 grid.add_legend() 97 if logscale: 98 grid.set(yscale="log") 99 return grid
Plots all performance indicators in a grid of line plots.

The columns of this grid correspond to the performance indicators, whereas
the rows can be set to correspond to either n_run
, problem
or
algorithm
. For example, if row="algorithm"
(as is the case above), then
each row will correspond to an algorithm, whereas n_run
and problem
will be compounded in the line plots. If left to None
, then n_run
,
problem
and algorithm
will all be compounded together.
Note:
If you have the benchmark definition, the
benchmark.csv
file, but do not want to rerun the benchmark, you can use the following trick:benchmark = Benchmark(...) # Benchmark specification benchmark._results = pd.read_csv(path_to_benchmark_csv) # Inject results plot_performance_indicators(benchmark, ...) # Plot
Arguments:
- benckmark: A (ran) benchmark object.
- row (Optional[str]): See above.
- algorithms (Optional[Iterable[str]]): List of algorithms to plot, defaults to all.
- performance_indicators (Optional[Iterable[str]]): List of performance indicators to plot, defaults to all.
- problems (Optional[Iterable[str]]): List of problems to plot, defaults to all.
- legend (bool): Wether to display the legend. Defaults to
True
. - logscale (bool): Wether to have a logarithmic y scale. Defaults to
False
. - x (str): Column for the x axis. Should be among
n_gen
(the default),n_eval
, ortimedelta
.