nmoo.plotting.delta_f
ΔF plots
1""" 2ΔF plots 3""" 4__docformat__ = "google" 5 6from itertools import product 7from math import sqrt 8from pathlib import Path 9from typing import Dict 10 11import numpy as np 12import pandas as pd 13import seaborn as sns 14from loguru import logger as logging 15from pymoo.core.problem import Problem 16 17from nmoo.benchmark import Benchmark 18 19 20def _load_problem_data( 21 file_path: Path, ground_problem: Problem 22) -> pd.DataFrame: 23 """ 24 Loads a problem history and annotates it with true F values. 25 """ 26 history = np.load(file_path) 27 d1, d2 = pd.DataFrame(), pd.DataFrame() 28 d1["_batch"] = d2["_batch"] = history["_batch"] 29 d1["type"], d2["type"] = "approx.", "true" 30 out: Dict[str, np.ndarray] = {} 31 ground_problem._evaluate(history["X"], out) 32 d1["F0"], d1["F1"] = history["F"][:, 0], history["F"][:, 1] 33 d2["F0"], d2["F1"] = out["F"][:, 0], out["F"][:, 1] 34 history.close() 35 return pd.concat([d1, d2], ignore_index=True) 36 37 38def generate_delta_F_plots( 39 benchmark: Benchmark, 40 n_generations: int = 10, 41) -> None: 42 """ 43 Generate all ΔF plots for a given benchmark, and save them as jpg image in 44 the benchmark's output directory. The naming pattern is the same as in 45 `nmoo.wrapped_problem.WrappedProblem.dump_all_histories`, except the files 46 end with the `.jpg` extension instead of `.npz`. 47 48 <center> 49 <img src="https://github.com/altaris/noisy-moo/raw/main/imgs/generate_delta_F_plots.png" 50 alt="Example"/> 51 </center> 52 53 A ΔF plot show the predicted value of a denoised noisy problem (in blue) 54 against the true value of the base problem (in orange). In addition, the 55 Pareto front is plotted in red. This kind of plot is only possible in a 56 synthetic setting. 57 58 Args: 59 n_generations (int): Number of generation to plot. 60 61 Warning: 62 The ground pymoo problem must have a `pareto_front()` method that 63 returns an actual array. 64 """ 65 if not benchmark._dump_histories: 66 raise RuntimeError( 67 "The benchmark must have 'dump_histories=True' set when " 68 "constructed." 69 ) 70 everything = product( 71 benchmark._algorithms.keys(), 72 [(k, v["problem"]) for k, v in benchmark._problems.items()], 73 range(1, benchmark._n_runs + 1), 74 ) 75 for an, (pn, p), r in everything: 76 if p.n_obj != 2: 77 logging.warning( 78 "Problem {} has {} objectives, but exactly 2 is needed for " 79 "plotting", 80 pn, 81 p.n_obj, 82 ) 83 continue 84 ground_problem = p.ground_problem() 85 # TODO: What if the ground_problem does not have a Pareto front? 86 pareto_front = ground_problem.pareto_front() 87 for li, l in enumerate(p.all_layers()): 88 file_stem = f"{pn}.{an}.{r}.{li + 1}-{l._name}" 89 df = _load_problem_data( 90 benchmark._output_dir_path / (file_stem + ".npz"), 91 ground_problem, 92 ) 93 grid = sns.FacetGrid( 94 df[ 95 df._batch.isin( 96 np.linspace( 97 1, df._batch.max(), n_generations, dtype=int 98 ) 99 ) 100 ], 101 col="_batch", 102 col_wrap=int(sqrt(n_generations)), 103 ) 104 grid.map_dataframe( 105 sns.scatterplot, x="F0", y="F1", style="type", hue="type" 106 ) 107 grid.add_legend() 108 if pareto_front.shape[0]: 109 for ax in grid.axes: 110 ax.plot(pareto_front[:, 0], pareto_front[:, 1], "--r") 111 grid.savefig(benchmark._output_dir_path / (file_stem + ".jpg"))
39def generate_delta_F_plots( 40 benchmark: Benchmark, 41 n_generations: int = 10, 42) -> None: 43 """ 44 Generate all ΔF plots for a given benchmark, and save them as jpg image in 45 the benchmark's output directory. The naming pattern is the same as in 46 `nmoo.wrapped_problem.WrappedProblem.dump_all_histories`, except the files 47 end with the `.jpg` extension instead of `.npz`. 48 49 <center> 50 <img src="https://github.com/altaris/noisy-moo/raw/main/imgs/generate_delta_F_plots.png" 51 alt="Example"/> 52 </center> 53 54 A ΔF plot show the predicted value of a denoised noisy problem (in blue) 55 against the true value of the base problem (in orange). In addition, the 56 Pareto front is plotted in red. This kind of plot is only possible in a 57 synthetic setting. 58 59 Args: 60 n_generations (int): Number of generation to plot. 61 62 Warning: 63 The ground pymoo problem must have a `pareto_front()` method that 64 returns an actual array. 65 """ 66 if not benchmark._dump_histories: 67 raise RuntimeError( 68 "The benchmark must have 'dump_histories=True' set when " 69 "constructed." 70 ) 71 everything = product( 72 benchmark._algorithms.keys(), 73 [(k, v["problem"]) for k, v in benchmark._problems.items()], 74 range(1, benchmark._n_runs + 1), 75 ) 76 for an, (pn, p), r in everything: 77 if p.n_obj != 2: 78 logging.warning( 79 "Problem {} has {} objectives, but exactly 2 is needed for " 80 "plotting", 81 pn, 82 p.n_obj, 83 ) 84 continue 85 ground_problem = p.ground_problem() 86 # TODO: What if the ground_problem does not have a Pareto front? 87 pareto_front = ground_problem.pareto_front() 88 for li, l in enumerate(p.all_layers()): 89 file_stem = f"{pn}.{an}.{r}.{li + 1}-{l._name}" 90 df = _load_problem_data( 91 benchmark._output_dir_path / (file_stem + ".npz"), 92 ground_problem, 93 ) 94 grid = sns.FacetGrid( 95 df[ 96 df._batch.isin( 97 np.linspace( 98 1, df._batch.max(), n_generations, dtype=int 99 ) 100 ) 101 ], 102 col="_batch", 103 col_wrap=int(sqrt(n_generations)), 104 ) 105 grid.map_dataframe( 106 sns.scatterplot, x="F0", y="F1", style="type", hue="type" 107 ) 108 grid.add_legend() 109 if pareto_front.shape[0]: 110 for ax in grid.axes: 111 ax.plot(pareto_front[:, 0], pareto_front[:, 1], "--r") 112 grid.savefig(benchmark._output_dir_path / (file_stem + ".jpg"))
Generate all ΔF plots for a given benchmark, and save them as jpg image in
the benchmark's output directory. The naming pattern is the same as in
nmoo.wrapped_problem.WrappedProblem.dump_all_histories
, except the files
end with the .jpg
extension instead of .npz
.

A ΔF plot show the predicted value of a denoised noisy problem (in blue) against the true value of the base problem (in orange). In addition, the Pareto front is plotted in red. This kind of plot is only possible in a synthetic setting.
Arguments:
- n_generations (int): Number of generation to plot.
Warning:
The ground pymoo problem must have a
pareto_front()
method that returns an actual array.