pymoo 0.6.1.5.dev0__cp310-cp310-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymoo might be problematic. Click here for more details.
- pymoo/__init__.py +3 -0
- pymoo/algorithms/__init__.py +0 -0
- pymoo/algorithms/base/__init__.py +0 -0
- pymoo/algorithms/base/bracket.py +38 -0
- pymoo/algorithms/base/genetic.py +109 -0
- pymoo/algorithms/base/line.py +62 -0
- pymoo/algorithms/base/local.py +39 -0
- pymoo/algorithms/base/meta.py +79 -0
- pymoo/algorithms/hyperparameters.py +89 -0
- pymoo/algorithms/moo/__init__.py +0 -0
- pymoo/algorithms/moo/age.py +310 -0
- pymoo/algorithms/moo/age2.py +194 -0
- pymoo/algorithms/moo/ctaea.py +298 -0
- pymoo/algorithms/moo/dnsga2.py +76 -0
- pymoo/algorithms/moo/kgb.py +446 -0
- pymoo/algorithms/moo/moead.py +183 -0
- pymoo/algorithms/moo/nsga2.py +113 -0
- pymoo/algorithms/moo/nsga3.py +358 -0
- pymoo/algorithms/moo/pinsga2.py +370 -0
- pymoo/algorithms/moo/rnsga2.py +188 -0
- pymoo/algorithms/moo/rnsga3.py +246 -0
- pymoo/algorithms/moo/rvea.py +214 -0
- pymoo/algorithms/moo/sms.py +195 -0
- pymoo/algorithms/moo/spea2.py +190 -0
- pymoo/algorithms/moo/unsga3.py +47 -0
- pymoo/algorithms/soo/__init__.py +0 -0
- pymoo/algorithms/soo/convex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
- pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
- pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
- pymoo/algorithms/soo/nonconvex/de.py +279 -0
- pymoo/algorithms/soo/nonconvex/direct.py +149 -0
- pymoo/algorithms/soo/nonconvex/es.py +203 -0
- pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
- pymoo/algorithms/soo/nonconvex/ga.py +93 -0
- pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
- pymoo/algorithms/soo/nonconvex/isres.py +74 -0
- pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
- pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
- pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
- pymoo/algorithms/soo/nonconvex/pso.py +399 -0
- pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
- pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
- pymoo/algorithms/soo/nonconvex/sres.py +56 -0
- pymoo/algorithms/soo/univariate/__init__.py +0 -0
- pymoo/algorithms/soo/univariate/backtracking.py +59 -0
- pymoo/algorithms/soo/univariate/exp.py +46 -0
- pymoo/algorithms/soo/univariate/golden.py +65 -0
- pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
- pymoo/algorithms/soo/univariate/wolfe.py +163 -0
- pymoo/config.py +33 -0
- pymoo/constraints/__init__.py +3 -0
- pymoo/constraints/adaptive.py +62 -0
- pymoo/constraints/as_obj.py +56 -0
- pymoo/constraints/as_penalty.py +41 -0
- pymoo/constraints/eps.py +26 -0
- pymoo/constraints/from_bounds.py +36 -0
- pymoo/core/__init__.py +0 -0
- pymoo/core/algorithm.py +394 -0
- pymoo/core/callback.py +38 -0
- pymoo/core/crossover.py +77 -0
- pymoo/core/decision_making.py +102 -0
- pymoo/core/decomposition.py +76 -0
- pymoo/core/duplicate.py +163 -0
- pymoo/core/evaluator.py +116 -0
- pymoo/core/indicator.py +34 -0
- pymoo/core/individual.py +784 -0
- pymoo/core/infill.py +64 -0
- pymoo/core/initialization.py +42 -0
- pymoo/core/mating.py +39 -0
- pymoo/core/meta.py +21 -0
- pymoo/core/mixed.py +165 -0
- pymoo/core/mutation.py +44 -0
- pymoo/core/operator.py +40 -0
- pymoo/core/parameters.py +134 -0
- pymoo/core/plot.py +210 -0
- pymoo/core/population.py +180 -0
- pymoo/core/problem.py +460 -0
- pymoo/core/recorder.py +99 -0
- pymoo/core/repair.py +23 -0
- pymoo/core/replacement.py +96 -0
- pymoo/core/result.py +52 -0
- pymoo/core/sampling.py +43 -0
- pymoo/core/selection.py +61 -0
- pymoo/core/solution.py +10 -0
- pymoo/core/survival.py +103 -0
- pymoo/core/termination.py +70 -0
- pymoo/core/variable.py +399 -0
- pymoo/cython/__init__.py +0 -0
- pymoo/cython/calc_perpendicular_distance.cpython-310-darwin.so +0 -0
- pymoo/cython/calc_perpendicular_distance.pyx +67 -0
- pymoo/cython/decomposition.cpython-310-darwin.so +0 -0
- pymoo/cython/decomposition.pyx +165 -0
- pymoo/cython/hv.cpython-310-darwin.so +0 -0
- pymoo/cython/hv.pyx +18 -0
- pymoo/cython/info.cpython-310-darwin.so +0 -0
- pymoo/cython/info.pyx +5 -0
- pymoo/cython/mnn.cpython-310-darwin.so +0 -0
- pymoo/cython/mnn.pyx +273 -0
- pymoo/cython/non_dominated_sorting.cpython-310-darwin.so +0 -0
- pymoo/cython/non_dominated_sorting.pyx +645 -0
- pymoo/cython/pruning_cd.cpython-310-darwin.so +0 -0
- pymoo/cython/pruning_cd.pyx +197 -0
- pymoo/cython/stochastic_ranking.cpython-310-darwin.so +0 -0
- pymoo/cython/stochastic_ranking.pyx +49 -0
- pymoo/cython/utils.pxd +129 -0
- pymoo/cython/vendor/__init__.py +0 -0
- pymoo/cython/vendor/hypervolume.cpp +1621 -0
- pymoo/cython/vendor/hypervolume.h +63 -0
- pymoo/decomposition/__init__.py +0 -0
- pymoo/decomposition/aasf.py +24 -0
- pymoo/decomposition/asf.py +10 -0
- pymoo/decomposition/pbi.py +13 -0
- pymoo/decomposition/perp_dist.py +13 -0
- pymoo/decomposition/tchebicheff.py +11 -0
- pymoo/decomposition/util.py +13 -0
- pymoo/decomposition/weighted_sum.py +8 -0
- pymoo/docs.py +187 -0
- pymoo/experimental/__init__.py +0 -0
- pymoo/experimental/algorithms/__init__.py +0 -0
- pymoo/experimental/algorithms/gde3.py +57 -0
- pymoo/gradient/__init__.py +21 -0
- pymoo/gradient/automatic.py +57 -0
- pymoo/gradient/grad_autograd.py +105 -0
- pymoo/gradient/grad_complex.py +35 -0
- pymoo/gradient/grad_jax.py +51 -0
- pymoo/gradient/toolbox/__init__.py +6 -0
- pymoo/indicators/__init__.py +0 -0
- pymoo/indicators/distance_indicator.py +55 -0
- pymoo/indicators/gd.py +7 -0
- pymoo/indicators/gd_plus.py +7 -0
- pymoo/indicators/hv/__init__.py +63 -0
- pymoo/indicators/hv/exact.py +71 -0
- pymoo/indicators/hv/exact_2d.py +102 -0
- pymoo/indicators/hv/monte_carlo.py +74 -0
- pymoo/indicators/igd.py +7 -0
- pymoo/indicators/igd_plus.py +7 -0
- pymoo/indicators/kktpm.py +151 -0
- pymoo/indicators/migd.py +55 -0
- pymoo/indicators/rmetric.py +203 -0
- pymoo/indicators/spacing.py +52 -0
- pymoo/mcdm/__init__.py +0 -0
- pymoo/mcdm/compromise_programming.py +19 -0
- pymoo/mcdm/high_tradeoff.py +40 -0
- pymoo/mcdm/pseudo_weights.py +32 -0
- pymoo/operators/__init__.py +0 -0
- pymoo/operators/control.py +187 -0
- pymoo/operators/crossover/__init__.py +0 -0
- pymoo/operators/crossover/binx.py +45 -0
- pymoo/operators/crossover/dex.py +122 -0
- pymoo/operators/crossover/erx.py +162 -0
- pymoo/operators/crossover/expx.py +51 -0
- pymoo/operators/crossover/hux.py +37 -0
- pymoo/operators/crossover/nox.py +13 -0
- pymoo/operators/crossover/ox.py +84 -0
- pymoo/operators/crossover/pcx.py +82 -0
- pymoo/operators/crossover/pntx.py +49 -0
- pymoo/operators/crossover/sbx.py +125 -0
- pymoo/operators/crossover/spx.py +5 -0
- pymoo/operators/crossover/ux.py +20 -0
- pymoo/operators/mutation/__init__.py +0 -0
- pymoo/operators/mutation/bitflip.py +17 -0
- pymoo/operators/mutation/gauss.py +58 -0
- pymoo/operators/mutation/inversion.py +42 -0
- pymoo/operators/mutation/nom.py +7 -0
- pymoo/operators/mutation/pm.py +94 -0
- pymoo/operators/mutation/rm.py +23 -0
- pymoo/operators/repair/__init__.py +0 -0
- pymoo/operators/repair/bounce_back.py +32 -0
- pymoo/operators/repair/bounds_repair.py +95 -0
- pymoo/operators/repair/inverse_penalty.py +89 -0
- pymoo/operators/repair/rounding.py +18 -0
- pymoo/operators/repair/to_bound.py +31 -0
- pymoo/operators/repair/vtype.py +11 -0
- pymoo/operators/sampling/__init__.py +0 -0
- pymoo/operators/sampling/lhs.py +73 -0
- pymoo/operators/sampling/rnd.py +50 -0
- pymoo/operators/selection/__init__.py +0 -0
- pymoo/operators/selection/rnd.py +72 -0
- pymoo/operators/selection/tournament.py +76 -0
- pymoo/operators/survival/__init__.py +0 -0
- pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
- pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
- pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
- pymoo/optimize.py +72 -0
- pymoo/problems/__init__.py +157 -0
- pymoo/problems/dyn.py +47 -0
- pymoo/problems/dynamic/__init__.py +0 -0
- pymoo/problems/dynamic/cec2015.py +108 -0
- pymoo/problems/dynamic/df.py +452 -0
- pymoo/problems/dynamic/misc.py +167 -0
- pymoo/problems/functional.py +48 -0
- pymoo/problems/many/__init__.py +5 -0
- pymoo/problems/many/cdtlz.py +159 -0
- pymoo/problems/many/dcdtlz.py +88 -0
- pymoo/problems/many/dtlz.py +264 -0
- pymoo/problems/many/wfg.py +550 -0
- pymoo/problems/multi/__init__.py +14 -0
- pymoo/problems/multi/bnh.py +34 -0
- pymoo/problems/multi/carside.py +48 -0
- pymoo/problems/multi/clutch.py +104 -0
- pymoo/problems/multi/csi.py +55 -0
- pymoo/problems/multi/ctp.py +198 -0
- pymoo/problems/multi/dascmop.py +213 -0
- pymoo/problems/multi/kursawe.py +25 -0
- pymoo/problems/multi/modact.py +68 -0
- pymoo/problems/multi/mw.py +400 -0
- pymoo/problems/multi/omnitest.py +48 -0
- pymoo/problems/multi/osy.py +32 -0
- pymoo/problems/multi/srn.py +28 -0
- pymoo/problems/multi/sympart.py +94 -0
- pymoo/problems/multi/tnk.py +24 -0
- pymoo/problems/multi/truss2d.py +83 -0
- pymoo/problems/multi/welded_beam.py +41 -0
- pymoo/problems/multi/wrm.py +36 -0
- pymoo/problems/multi/zdt.py +151 -0
- pymoo/problems/multi_to_single.py +22 -0
- pymoo/problems/single/__init__.py +12 -0
- pymoo/problems/single/ackley.py +24 -0
- pymoo/problems/single/cantilevered_beam.py +34 -0
- pymoo/problems/single/flowshop_scheduling.py +112 -0
- pymoo/problems/single/g.py +874 -0
- pymoo/problems/single/griewank.py +18 -0
- pymoo/problems/single/himmelblau.py +15 -0
- pymoo/problems/single/knapsack.py +48 -0
- pymoo/problems/single/mopta08.py +26 -0
- pymoo/problems/single/multimodal.py +20 -0
- pymoo/problems/single/pressure_vessel.py +30 -0
- pymoo/problems/single/rastrigin.py +20 -0
- pymoo/problems/single/rosenbrock.py +22 -0
- pymoo/problems/single/schwefel.py +18 -0
- pymoo/problems/single/simple.py +13 -0
- pymoo/problems/single/sphere.py +19 -0
- pymoo/problems/single/traveling_salesman.py +79 -0
- pymoo/problems/single/zakharov.py +19 -0
- pymoo/problems/static.py +14 -0
- pymoo/problems/util.py +42 -0
- pymoo/problems/zero_to_one.py +27 -0
- pymoo/termination/__init__.py +23 -0
- pymoo/termination/collection.py +12 -0
- pymoo/termination/cv.py +48 -0
- pymoo/termination/default.py +45 -0
- pymoo/termination/delta.py +64 -0
- pymoo/termination/fmin.py +16 -0
- pymoo/termination/ftol.py +144 -0
- pymoo/termination/indicator.py +49 -0
- pymoo/termination/max_eval.py +14 -0
- pymoo/termination/max_gen.py +15 -0
- pymoo/termination/max_time.py +20 -0
- pymoo/termination/robust.py +34 -0
- pymoo/termination/xtol.py +33 -0
- pymoo/util/__init__.py +0 -0
- pymoo/util/archive.py +150 -0
- pymoo/util/cache.py +29 -0
- pymoo/util/clearing.py +82 -0
- pymoo/util/display/__init__.py +0 -0
- pymoo/util/display/column.py +52 -0
- pymoo/util/display/display.py +34 -0
- pymoo/util/display/multi.py +96 -0
- pymoo/util/display/output.py +53 -0
- pymoo/util/display/progress.py +54 -0
- pymoo/util/display/single.py +67 -0
- pymoo/util/dominator.py +67 -0
- pymoo/util/function_loader.py +129 -0
- pymoo/util/hv.py +23 -0
- pymoo/util/matlab_engine.py +39 -0
- pymoo/util/misc.py +460 -0
- pymoo/util/mnn.py +70 -0
- pymoo/util/nds/__init__.py +0 -0
- pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
- pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
- pymoo/util/nds/fast_non_dominated_sort.py +70 -0
- pymoo/util/nds/naive_non_dominated_sort.py +36 -0
- pymoo/util/nds/non_dominated_sorting.py +67 -0
- pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
- pymoo/util/normalization.py +312 -0
- pymoo/util/optimum.py +42 -0
- pymoo/util/plotting.py +177 -0
- pymoo/util/pruning_cd.py +89 -0
- pymoo/util/randomized_argsort.py +60 -0
- pymoo/util/ref_dirs/__init__.py +24 -0
- pymoo/util/ref_dirs/construction.py +88 -0
- pymoo/util/ref_dirs/das_dennis.py +52 -0
- pymoo/util/ref_dirs/energy.py +319 -0
- pymoo/util/ref_dirs/energy_layer.py +119 -0
- pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
- pymoo/util/ref_dirs/incremental.py +68 -0
- pymoo/util/ref_dirs/misc.py +128 -0
- pymoo/util/ref_dirs/optimizer.py +59 -0
- pymoo/util/ref_dirs/performance.py +162 -0
- pymoo/util/ref_dirs/reduction.py +85 -0
- pymoo/util/ref_dirs/sample_and_map.py +24 -0
- pymoo/util/reference_direction.py +260 -0
- pymoo/util/remote.py +55 -0
- pymoo/util/roulette.py +27 -0
- pymoo/util/running_metric.py +128 -0
- pymoo/util/sliding_window.py +25 -0
- pymoo/util/stochastic_ranking.py +32 -0
- pymoo/util/value_functions.py +719 -0
- pymoo/util/vectors.py +40 -0
- pymoo/util/vf_dominator.py +99 -0
- pymoo/vendor/__init__.py +0 -0
- pymoo/vendor/cec2018.py +398 -0
- pymoo/vendor/gta.py +617 -0
- pymoo/vendor/hv.py +267 -0
- pymoo/vendor/vendor_cmaes.py +412 -0
- pymoo/vendor/vendor_coco.py +81 -0
- pymoo/vendor/vendor_scipy.py +232 -0
- pymoo/version.py +1 -0
- pymoo/visualization/__init__.py +8 -0
- pymoo/visualization/fitness_landscape.py +127 -0
- pymoo/visualization/heatmap.py +123 -0
- pymoo/visualization/pcp.py +120 -0
- pymoo/visualization/petal.py +91 -0
- pymoo/visualization/radar.py +108 -0
- pymoo/visualization/radviz.py +68 -0
- pymoo/visualization/scatter.py +150 -0
- pymoo/visualization/star_coordinate.py +75 -0
- pymoo/visualization/util.py +123 -0
- pymoo/visualization/video/__init__.py +0 -0
- pymoo/visualization/video/callback_video.py +82 -0
- pymoo/visualization/video/one_var_one_obj.py +57 -0
- pymoo/visualization/video/two_var_one_obj.py +62 -0
- pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
- pymoo-0.6.1.5.dev0.dist-info/RECORD +328 -0
- pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -0
- pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
- pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.docs import parse_doc_string
|
|
4
|
+
from pymoo.core.plot import Plot
|
|
5
|
+
from pymoo.util.misc import set_if_none
|
|
6
|
+
from pymoo.visualization.util import get_circle_points, plot_axes_lines, \
|
|
7
|
+
plot_axis_labels, plot_circle, plot_polygon, parse_bounds, normalize, equal_axis, no_ticks
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Petal(Plot):
|
|
11
|
+
|
|
12
|
+
def __init__(self,
|
|
13
|
+
bounds=None,
|
|
14
|
+
**kwargs):
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
Petal Diagram
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------------
|
|
22
|
+
bounds : tuple
|
|
23
|
+
The boundaries for each objective. Necessary to be provided for this plot!
|
|
24
|
+
axis_style : {axis_style}
|
|
25
|
+
reverse : bool
|
|
26
|
+
Default false. Otherwise, larger area means smaller value.
|
|
27
|
+
|
|
28
|
+
Other Parameters
|
|
29
|
+
----------------
|
|
30
|
+
|
|
31
|
+
figsize : {figsize}
|
|
32
|
+
title : {title}
|
|
33
|
+
legend : {legend}
|
|
34
|
+
tight_layout : {tight_layout}
|
|
35
|
+
cmap : {cmap}
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
super().__init__(bounds=bounds, **kwargs)
|
|
40
|
+
|
|
41
|
+
if bounds is None:
|
|
42
|
+
raise Exception("Boundaries must be provided for Petal Width. Otherwise, no trade-offs can be calculated.")
|
|
43
|
+
|
|
44
|
+
set_if_none(self.axis_style, "color", "black")
|
|
45
|
+
set_if_none(self.axis_style, "linewidth", 2)
|
|
46
|
+
set_if_none(self.axis_style, "alpha", 0.5)
|
|
47
|
+
|
|
48
|
+
def _plot(self, ax, F):
|
|
49
|
+
|
|
50
|
+
# equal axis length and no ticks
|
|
51
|
+
equal_axis(ax)
|
|
52
|
+
no_ticks(ax)
|
|
53
|
+
|
|
54
|
+
V = get_circle_points(len(F))
|
|
55
|
+
|
|
56
|
+
# sections to plot
|
|
57
|
+
sections = np.linspace(0, 2 * np.pi, self.n_dim + 1)
|
|
58
|
+
|
|
59
|
+
t = [(sections[i] + sections[i + 1]) / 2 for i in range(len(sections) - 1)]
|
|
60
|
+
endpoints = np.column_stack([np.cos(t), np.sin(t)])
|
|
61
|
+
plot_axis_labels(ax, endpoints, self.get_labels(), **self.axis_label_style)
|
|
62
|
+
|
|
63
|
+
center = np.zeros(2)
|
|
64
|
+
|
|
65
|
+
for i in range(len(sections) - 1):
|
|
66
|
+
t = np.linspace(sections[i], sections[i + 1], 100)
|
|
67
|
+
v = np.column_stack([np.cos(t), np.sin(t)])
|
|
68
|
+
|
|
69
|
+
P = np.row_stack([center, F[i] * v])
|
|
70
|
+
plot_polygon(ax, P, color=self.colors[i])
|
|
71
|
+
|
|
72
|
+
# draw the outer circle
|
|
73
|
+
plot_circle(ax, **self.axis_style)
|
|
74
|
+
plot_axes_lines(ax, V, **self.axis_style)
|
|
75
|
+
|
|
76
|
+
def _do(self):
|
|
77
|
+
|
|
78
|
+
n_rows = len(self.to_plot)
|
|
79
|
+
n_cols = max([len(e[0]) for e in self.to_plot])
|
|
80
|
+
self.init_figure(n_rows=n_rows, n_cols=n_cols, force_axes_as_matrix=True)
|
|
81
|
+
|
|
82
|
+
# normalize the input
|
|
83
|
+
bounds = parse_bounds(self.bounds, self.n_dim)
|
|
84
|
+
to_plot_norm = normalize(self.to_plot, bounds, reverse=self.reverse)
|
|
85
|
+
|
|
86
|
+
for k, (F, kwargs) in enumerate(to_plot_norm):
|
|
87
|
+
for j, _F in enumerate(F):
|
|
88
|
+
self._plot(self.ax[k, j], _F)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
parse_doc_string(Petal.__init__)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.docs import parse_doc_string
|
|
4
|
+
from pymoo.core.plot import Plot
|
|
5
|
+
from pymoo.util.misc import set_if_none_from_tuples
|
|
6
|
+
from pymoo.visualization.util import plot_axes_lines, plot_axis_labels, plot_polygon, get_circle_points, \
|
|
7
|
+
plot_radar_line, equal_axis, no_ticks, parse_bounds, normalize
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Radar(Plot):
|
|
11
|
+
|
|
12
|
+
def __init__(self,
|
|
13
|
+
normalize_each_objective=True,
|
|
14
|
+
n_partitions=3,
|
|
15
|
+
point_style={},
|
|
16
|
+
**kwargs):
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
Radar Plot
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------------
|
|
23
|
+
normalize_each_objective : bool
|
|
24
|
+
Whether each objective is normalized. Otherwise, the inner and outer bound is plotted.
|
|
25
|
+
point_style : dict
|
|
26
|
+
The style being used to visualize the points
|
|
27
|
+
n_partitions : int
|
|
28
|
+
Number of partitions to show in the radar.
|
|
29
|
+
reverse : {reverse}
|
|
30
|
+
axis_style : {axis_style}
|
|
31
|
+
labels : {labels}
|
|
32
|
+
|
|
33
|
+
Other Parameters
|
|
34
|
+
----------------
|
|
35
|
+
figsize : {figsize}
|
|
36
|
+
title : {title}
|
|
37
|
+
legend : {legend}
|
|
38
|
+
tight_layout : {tight_layout}
|
|
39
|
+
cmap : {cmap}
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
super().__init__(**kwargs)
|
|
43
|
+
self.normalize_each_objective = normalize_each_objective
|
|
44
|
+
self.n_partitions = n_partitions
|
|
45
|
+
|
|
46
|
+
self.point_style = point_style
|
|
47
|
+
set_if_none_from_tuples(self.point_style, ("s", 15))
|
|
48
|
+
|
|
49
|
+
set_if_none_from_tuples(self.axis_style, ("color", "black"), ("linewidth", 0.5), ("alpha", 0.75))
|
|
50
|
+
|
|
51
|
+
def _plot(self, ax, _F, inner, outer, kwargs):
|
|
52
|
+
|
|
53
|
+
set_if_none_from_tuples(kwargs, ("alpha", 0.5))
|
|
54
|
+
|
|
55
|
+
# equal axis length and no ticks
|
|
56
|
+
equal_axis(ax)
|
|
57
|
+
no_ticks(ax)
|
|
58
|
+
|
|
59
|
+
# draw the axis lines and labels
|
|
60
|
+
plot_axes_lines(ax, outer, extend_factor=1.0, **self.axis_style)
|
|
61
|
+
plot_axis_labels(ax, outer, self.get_labels(), margin=0.015, **self.axis_label_style)
|
|
62
|
+
|
|
63
|
+
# plot the outer radar line and the inner polygon
|
|
64
|
+
plot_radar_line(ax, outer, **self.axis_style)
|
|
65
|
+
plot_polygon(ax, inner)
|
|
66
|
+
|
|
67
|
+
# find the corresponding point
|
|
68
|
+
_F = inner + _F[:, None] * (outer - inner)
|
|
69
|
+
|
|
70
|
+
# plot the points and no polygon
|
|
71
|
+
ax.scatter(_F[:, 0], _F[:, 1], **self.point_style)
|
|
72
|
+
plot_polygon(ax, _F, **kwargs)
|
|
73
|
+
|
|
74
|
+
def _do(self):
|
|
75
|
+
|
|
76
|
+
if self.bounds is None:
|
|
77
|
+
raise Exception("The boundaries must be provided.")
|
|
78
|
+
|
|
79
|
+
_F = np.row_stack([e[0] for e in self.to_plot])
|
|
80
|
+
if np.any(_F < self.bounds[0]) or np.any(_F > self.bounds[1]):
|
|
81
|
+
raise Exception(
|
|
82
|
+
"Points out of the boundaries exist! Please make sure the boundaries are indeed boundaries.")
|
|
83
|
+
|
|
84
|
+
n_rows = len(self.to_plot)
|
|
85
|
+
n_cols = max([len(e[0]) for e in self.to_plot])
|
|
86
|
+
self.init_figure(n_rows=n_rows, n_cols=n_cols, force_axes_as_matrix=True)
|
|
87
|
+
|
|
88
|
+
# normalize the input
|
|
89
|
+
bounds = parse_bounds(self.bounds, self.n_dim)
|
|
90
|
+
to_plot_norm = normalize(self.to_plot, bounds, reverse=self.reverse)
|
|
91
|
+
|
|
92
|
+
# get the endpoints of circle
|
|
93
|
+
V = get_circle_points(self.n_dim)
|
|
94
|
+
|
|
95
|
+
if self.normalize_each_objective:
|
|
96
|
+
inner = np.zeros((self.n_dim, 1)) * V
|
|
97
|
+
outer = np.ones((self.n_dim, 1)) * V
|
|
98
|
+
else:
|
|
99
|
+
inner = bounds[[0]].T * V
|
|
100
|
+
outer = (bounds[[1]].T * V) / bounds[1].max()
|
|
101
|
+
|
|
102
|
+
for k, (F, kwargs) in enumerate(to_plot_norm):
|
|
103
|
+
|
|
104
|
+
for j, _F in enumerate(F):
|
|
105
|
+
self._plot(self.ax[k, j], _F, inner, outer, kwargs)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
parse_doc_string(Radar.__init__)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from pymoo.docs import parse_doc_string
|
|
2
|
+
from pymoo.core.plot import Plot
|
|
3
|
+
from pymoo.util.misc import set_if_none_from_tuples
|
|
4
|
+
from pymoo.visualization.util import plot_circle, plot_radar_line, plot_axis_labels, equal_axis, no_ticks, \
|
|
5
|
+
get_uniform_points_around_circle
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Radviz(Plot):
|
|
9
|
+
|
|
10
|
+
def __init__(self, endpoint_style={}, **kwargs):
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
Radviz Plot
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------------
|
|
17
|
+
|
|
18
|
+
axis_style : {axis_style}
|
|
19
|
+
endpoint_style : dict
|
|
20
|
+
Endpoints are drawn at each extreme point of an objective. This style can be modified.
|
|
21
|
+
labels : {labels}
|
|
22
|
+
|
|
23
|
+
Other Parameters
|
|
24
|
+
----------------
|
|
25
|
+
|
|
26
|
+
figsize : {figsize}
|
|
27
|
+
title : {title}
|
|
28
|
+
legend : {legend}
|
|
29
|
+
tight_layout : {tight_layout}
|
|
30
|
+
cmap : {cmap}
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
super().__init__(**kwargs)
|
|
35
|
+
|
|
36
|
+
# set the default axis style
|
|
37
|
+
set_if_none_from_tuples(self.axis_style, ("color", "black"), ("linewidth", 1), ("alpha", 0.75))
|
|
38
|
+
|
|
39
|
+
self.endpoint_style = endpoint_style
|
|
40
|
+
set_if_none_from_tuples(self.endpoint_style, ("color", "black"), ("s", 70), ("alpha", 0.3))
|
|
41
|
+
|
|
42
|
+
def _do(self):
|
|
43
|
+
|
|
44
|
+
# initial a figure with a single plot
|
|
45
|
+
self.init_figure()
|
|
46
|
+
|
|
47
|
+
# equal axis length and no ticks
|
|
48
|
+
equal_axis(self.ax)
|
|
49
|
+
no_ticks(self.ax)
|
|
50
|
+
|
|
51
|
+
V = get_uniform_points_around_circle(self.n_dim)
|
|
52
|
+
plot_axis_labels(self.ax, V, self.get_labels(), **self.axis_label_style)
|
|
53
|
+
|
|
54
|
+
# draw the outer circle and radar lines
|
|
55
|
+
plot_circle(self.ax, **self.axis_style)
|
|
56
|
+
plot_radar_line(self.ax, V, **self.axis_style)
|
|
57
|
+
|
|
58
|
+
# draw the endpoints of each objective
|
|
59
|
+
if self.endpoint_style:
|
|
60
|
+
self.ax.scatter(V[:, 0], V[:, 1], **self.endpoint_style)
|
|
61
|
+
|
|
62
|
+
# plot all the points
|
|
63
|
+
for k, (F, kwargs) in enumerate(self.to_plot):
|
|
64
|
+
N = (F[..., None] * V).sum(axis=1) / F.sum(axis=1)[:, None]
|
|
65
|
+
self.ax.scatter(N[:, 0], N[:, 1], **kwargs)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
parse_doc_string(Radviz.__init__)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.core.plot import Plot
|
|
4
|
+
from pymoo.docs import parse_doc_string
|
|
5
|
+
from pymoo.util.misc import set_if_none
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def plot_1d(sc):
|
|
9
|
+
sc.init_figure()
|
|
10
|
+
labels = sc.get_labels()
|
|
11
|
+
ax = sc.ax
|
|
12
|
+
|
|
13
|
+
for k, (F, kwargs) in enumerate(sc.to_plot):
|
|
14
|
+
func = getattr(ax, kwargs.pop("mode"))
|
|
15
|
+
func(F, np.zeros_like(F), **kwargs)
|
|
16
|
+
ax.set_xlabel(labels[0])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def plot_2d(sc):
|
|
20
|
+
sc.init_figure()
|
|
21
|
+
labels = sc.get_labels()
|
|
22
|
+
ax = sc.ax
|
|
23
|
+
|
|
24
|
+
for k, (F, kwargs) in enumerate(sc.to_plot):
|
|
25
|
+
func = getattr(ax, kwargs.pop("mode"))
|
|
26
|
+
func(F[:, 0], F[:, 1], **kwargs)
|
|
27
|
+
ax.set_xlabel(labels[0])
|
|
28
|
+
ax.set_ylabel(labels[1])
|
|
29
|
+
|
|
30
|
+
return sc
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def plot_3d(sc, angle):
|
|
34
|
+
sc.init_figure(plot_3D=True)
|
|
35
|
+
labels = sc.get_labels()
|
|
36
|
+
ax = sc.ax
|
|
37
|
+
|
|
38
|
+
for k, (F, kwargs) in enumerate(sc.to_plot):
|
|
39
|
+
|
|
40
|
+
# here alo `plot_trisurf` is allowed
|
|
41
|
+
func = getattr(ax, kwargs.pop("mode"))
|
|
42
|
+
func(F[:, 0], F[:, 1], F[:, 2], **kwargs)
|
|
43
|
+
|
|
44
|
+
ax.xaxis.pane.fill = False
|
|
45
|
+
ax.yaxis.pane.fill = False
|
|
46
|
+
ax.zaxis.pane.fill = False
|
|
47
|
+
|
|
48
|
+
ax.set_xlabel(labels[0])
|
|
49
|
+
ax.set_ylabel(labels[1])
|
|
50
|
+
ax.set_zlabel(labels[2])
|
|
51
|
+
|
|
52
|
+
if sc.angle is not None:
|
|
53
|
+
ax.view_init(*angle)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def plot_pairwise(sc):
|
|
57
|
+
sc.init_figure(n_rows=sc.n_dim, n_cols=sc.n_dim)
|
|
58
|
+
labels = sc.get_labels()
|
|
59
|
+
|
|
60
|
+
for k, (F, kwargs) in enumerate(sc.to_plot):
|
|
61
|
+
|
|
62
|
+
assert F.shape[1] >= 2, "A pairwise sc plot needs at least two dimensions."
|
|
63
|
+
mode = kwargs.pop("mode")
|
|
64
|
+
|
|
65
|
+
for i in range(sc.n_dim):
|
|
66
|
+
for j in range(sc.n_dim):
|
|
67
|
+
|
|
68
|
+
ax = sc.ax[i, j]
|
|
69
|
+
func = getattr(ax, mode)
|
|
70
|
+
|
|
71
|
+
if i != j:
|
|
72
|
+
func(F[:, i], F[:, j], **kwargs)
|
|
73
|
+
ax.set_xlabel(labels[i])
|
|
74
|
+
ax.set_ylabel(labels[j])
|
|
75
|
+
else:
|
|
76
|
+
func(0, 0, s=1, color="white")
|
|
77
|
+
ax.set_xticks([])
|
|
78
|
+
ax.set_yticks([])
|
|
79
|
+
ax.text(0, 0, labels[i], ha='center', va='center', fontsize=20)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Scatter(Plot):
|
|
83
|
+
|
|
84
|
+
def __init__(self,
|
|
85
|
+
plot_3d=True,
|
|
86
|
+
angle=(45, 45),
|
|
87
|
+
**kwargs):
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
Scatter Plot
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------------
|
|
94
|
+
|
|
95
|
+
axis_style : {axis_style}
|
|
96
|
+
labels : {labels}
|
|
97
|
+
|
|
98
|
+
Other Parameters
|
|
99
|
+
----------------
|
|
100
|
+
|
|
101
|
+
figsize : {figsize}
|
|
102
|
+
title : {title}
|
|
103
|
+
legend : {legend}
|
|
104
|
+
tight_layout : {tight_layout}
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
super().__init__(**kwargs)
|
|
109
|
+
self.angle = angle
|
|
110
|
+
self.plot_3d = plot_3d
|
|
111
|
+
|
|
112
|
+
def _do(self):
|
|
113
|
+
|
|
114
|
+
# set some default values
|
|
115
|
+
to_plot = []
|
|
116
|
+
for k, (F, v) in enumerate(self.to_plot):
|
|
117
|
+
v = dict(v)
|
|
118
|
+
set_if_none(v, "color", self.colors[k % len(self.colors)])
|
|
119
|
+
set_if_none(v, "alpha", 1.0)
|
|
120
|
+
|
|
121
|
+
# this is added to have compatibility to an old version
|
|
122
|
+
# should be removed when the documentation is updated
|
|
123
|
+
if "plot_type" in v:
|
|
124
|
+
name = v.pop("plot_type")
|
|
125
|
+
|
|
126
|
+
if name == "line":
|
|
127
|
+
name = "plot"
|
|
128
|
+
elif name == "surface":
|
|
129
|
+
name = "plot_trisurf"
|
|
130
|
+
|
|
131
|
+
v["mode"] = name
|
|
132
|
+
set_if_none(v, "mode", "scatter")
|
|
133
|
+
|
|
134
|
+
to_plot.append([F, v])
|
|
135
|
+
|
|
136
|
+
self.to_plot = to_plot
|
|
137
|
+
|
|
138
|
+
if self.n_dim == 1:
|
|
139
|
+
plot_1d(self)
|
|
140
|
+
elif self.n_dim == 2:
|
|
141
|
+
plot_2d(self)
|
|
142
|
+
elif self.n_dim == 3 and self.plot_3d:
|
|
143
|
+
plot_3d(self, self.angle)
|
|
144
|
+
else:
|
|
145
|
+
plot_pairwise(self)
|
|
146
|
+
|
|
147
|
+
return self
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
parse_doc_string(Scatter.__init__)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pymoo.visualization.util import plot_axes_arrow, plot_axis_labels, equal_axis, no_ticks, parse_bounds, \
|
|
4
|
+
normalize, get_uniform_points_around_circle
|
|
5
|
+
from pymoo.docs import parse_doc_string
|
|
6
|
+
from pymoo.core.plot import Plot
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class StarCoordinate(Plot):
|
|
10
|
+
|
|
11
|
+
def __init__(self,
|
|
12
|
+
axis_extension=1.03,
|
|
13
|
+
**kwargs):
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
Star Coordinate Plot
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------------
|
|
20
|
+
|
|
21
|
+
axis_style : {axis_style}
|
|
22
|
+
labels : {labels}
|
|
23
|
+
endpoint_style : dict
|
|
24
|
+
Endpoints are drawn at each extreme point of an objective. This style can be modified.
|
|
25
|
+
|
|
26
|
+
Other Parameters
|
|
27
|
+
----------------
|
|
28
|
+
|
|
29
|
+
figsize : {figsize}
|
|
30
|
+
title : {title}
|
|
31
|
+
legend : {legend}
|
|
32
|
+
tight_layout : {tight_layout}
|
|
33
|
+
cmap : {cmap}
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
super().__init__(**kwargs)
|
|
37
|
+
|
|
38
|
+
self.axis_extension = axis_extension
|
|
39
|
+
|
|
40
|
+
if "arrow_style" not in kwargs:
|
|
41
|
+
self.arrow_style = {
|
|
42
|
+
"head_width": 0.02,
|
|
43
|
+
"head_length": 0.01
|
|
44
|
+
}
|
|
45
|
+
else:
|
|
46
|
+
self.arrow_style = kwargs["arrow_style"]
|
|
47
|
+
|
|
48
|
+
def _do(self):
|
|
49
|
+
|
|
50
|
+
# initial a figure with a single plot
|
|
51
|
+
self.init_figure()
|
|
52
|
+
|
|
53
|
+
# equal axis length and no ticks
|
|
54
|
+
equal_axis(self.ax)
|
|
55
|
+
no_ticks(self.ax)
|
|
56
|
+
|
|
57
|
+
# determine the overall scale of points
|
|
58
|
+
_F = np.row_stack([e[0] for e in self.to_plot])
|
|
59
|
+
_min, _max = _F.min(axis=0), _F.max(axis=0)
|
|
60
|
+
|
|
61
|
+
V = get_uniform_points_around_circle(self.n_dim)
|
|
62
|
+
|
|
63
|
+
plot_axes_arrow(self.ax, V, extend_factor=self.axis_extension, **{**self.axis_style, **self.arrow_style})
|
|
64
|
+
plot_axis_labels(self.ax, V, self.get_labels(), **self.axis_label_style)
|
|
65
|
+
|
|
66
|
+
# normalize in range for this plot - here no implicit normalization as in radviz
|
|
67
|
+
bounds = parse_bounds(self.bounds, self.n_dim)
|
|
68
|
+
to_plot_norm = normalize(self.to_plot, bounds)
|
|
69
|
+
|
|
70
|
+
for k, (F, kwargs) in enumerate(to_plot_norm):
|
|
71
|
+
N = (F[..., None] * V).sum(axis=1)
|
|
72
|
+
self.ax.scatter(N[:, 0], N[:, 1], **kwargs)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
parse_doc_string(StarCoordinate.__init__)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from matplotlib import patches
|
|
5
|
+
from matplotlib.collections import PatchCollection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_circle_points(n_points):
|
|
9
|
+
t = np.linspace(0, 2 * np.pi, n_points, endpoint=False)
|
|
10
|
+
return np.column_stack([np.cos(t), np.sin(t)])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def default_number_to_text(val):
|
|
14
|
+
if val > 1e3:
|
|
15
|
+
return "{:.2e}".format(val)
|
|
16
|
+
else:
|
|
17
|
+
return "{:.2f}".format(val)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def in_notebook():
|
|
21
|
+
return 'ipykernel' in sys.modules
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_uniform_points_around_circle(n):
|
|
25
|
+
t = 2 * np.pi * np.arange(n) / n
|
|
26
|
+
s = np.column_stack([np.cos(t), np.sin(t)])
|
|
27
|
+
return s
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def plot_circle(ax, center=0, radius=1, **kwargs):
|
|
31
|
+
P = get_circle_points(5000)
|
|
32
|
+
P = (P + center) * radius
|
|
33
|
+
ax.plot(P[:, 0], P[:, 1], **kwargs)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def plot_radar_line(ax, x, **kwargs):
|
|
37
|
+
x = np.row_stack([x, x[0]])
|
|
38
|
+
ax.plot(x[:, 0], x[:, 1], **kwargs)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def plot_axes_arrow(ax, X, extend_factor=1.0, **kwargs):
|
|
42
|
+
for (x, y) in X:
|
|
43
|
+
ax.arrow(0, 0, x * extend_factor, y * extend_factor, **kwargs)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def plot_axes_lines(ax, X, extend_factor=1.0, **kwargs):
|
|
47
|
+
for (x, y) in X:
|
|
48
|
+
ax.plot([0, x * extend_factor], [0, y * extend_factor], **kwargs)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def plot_polygon(ax, x, **kwargs):
|
|
52
|
+
ax.add_collection(PatchCollection([patches.Polygon(x, closed=True)], **kwargs))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def plot_axis_labels(ax, endpoints, labels, margin=0.035, size='small', **kwargs):
|
|
56
|
+
for k in range(len(labels)):
|
|
57
|
+
xy = endpoints[k]
|
|
58
|
+
|
|
59
|
+
if xy[0] < 0.0:
|
|
60
|
+
x = xy[0] - margin
|
|
61
|
+
ha = "right"
|
|
62
|
+
else:
|
|
63
|
+
x = xy[0] + margin
|
|
64
|
+
ha = "left"
|
|
65
|
+
|
|
66
|
+
if xy[1] < 0.0:
|
|
67
|
+
y = xy[1] - margin
|
|
68
|
+
va = "top"
|
|
69
|
+
else:
|
|
70
|
+
y = xy[1] + margin
|
|
71
|
+
va = "bottom"
|
|
72
|
+
|
|
73
|
+
ax.text(x, y, labels[k], ha=ha, va=va, size=size, **kwargs)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def equal_axis(ax):
|
|
77
|
+
ax.set_xlim([-1.1, 1.1])
|
|
78
|
+
ax.set_ylim([-1.1, 1.1])
|
|
79
|
+
ax.axis('equal')
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def no_ticks(ax):
|
|
83
|
+
ax.set_yticks([])
|
|
84
|
+
ax.set_xticks([])
|
|
85
|
+
ax.set_frame_on(False)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def normalize(data, bounds, reverse=False, return_bounds=False):
|
|
89
|
+
from pymoo.util.normalization import normalize as _normalize
|
|
90
|
+
|
|
91
|
+
_F = np.row_stack([e[0] for e in data])
|
|
92
|
+
if bounds is None:
|
|
93
|
+
bounds = (_F.min(axis=0), _F.max(axis=0))
|
|
94
|
+
|
|
95
|
+
to_plot = []
|
|
96
|
+
for k in range(len(data)):
|
|
97
|
+
F = _normalize(data[k][0], bounds[0], bounds[1])
|
|
98
|
+
|
|
99
|
+
if reverse:
|
|
100
|
+
F = 1 - F
|
|
101
|
+
|
|
102
|
+
to_plot.append([F, data[k][1]])
|
|
103
|
+
|
|
104
|
+
if return_bounds:
|
|
105
|
+
return to_plot, bounds
|
|
106
|
+
else:
|
|
107
|
+
return to_plot
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def parse_bounds(bounds, n_dim):
|
|
111
|
+
if bounds is not None:
|
|
112
|
+
bounds = np.array(bounds, dtype=float)
|
|
113
|
+
if bounds.ndim == 1:
|
|
114
|
+
bounds = bounds[None, :].repeat(n_dim, axis=0).T
|
|
115
|
+
return bounds
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def radviz_pandas(F):
|
|
119
|
+
import pandas as pd
|
|
120
|
+
df = pd.DataFrame([x for x in F], columns=["X%s" % k for k in range(F.shape[1])])
|
|
121
|
+
df["class"] = "Points"
|
|
122
|
+
return pd.plotting.radviz(df, "class")
|
|
123
|
+
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
|
|
3
|
+
from pymoo.core.callback import Callback
|
|
4
|
+
from pymoo.visualization.scatter import Scatter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AnimationCallback(Callback):
|
|
8
|
+
|
|
9
|
+
def __init__(self,
|
|
10
|
+
do_show=False,
|
|
11
|
+
do_close=True,
|
|
12
|
+
nth_gen=1,
|
|
13
|
+
dpi=None,
|
|
14
|
+
recorder=None,
|
|
15
|
+
fname=None,
|
|
16
|
+
exception_if_not_applicable=True):
|
|
17
|
+
|
|
18
|
+
super().__init__()
|
|
19
|
+
self.nth_gen = nth_gen
|
|
20
|
+
self.do_show = do_show
|
|
21
|
+
self.do_close = do_close
|
|
22
|
+
self.exception_if_not_applicable = exception_if_not_applicable
|
|
23
|
+
|
|
24
|
+
self.recorder = recorder
|
|
25
|
+
if self.recorder is None and fname is not None:
|
|
26
|
+
try:
|
|
27
|
+
from pyrecorder.recorder import Recorder
|
|
28
|
+
from pyrecorder.writers.video import Video
|
|
29
|
+
from pyrecorder.converters.matplotlib import Matplotlib
|
|
30
|
+
self.recorder = Recorder(Video(fname), converter=Matplotlib(dpi=dpi))
|
|
31
|
+
except:
|
|
32
|
+
raise Exception("Please install or update pyrecorder for animation support: pip install -U pyrecorder")
|
|
33
|
+
|
|
34
|
+
def update(self, algorithm):
|
|
35
|
+
if algorithm.n_gen == 1 or algorithm.n_gen % self.nth_gen == 0:
|
|
36
|
+
try:
|
|
37
|
+
|
|
38
|
+
figure = self.do(algorithm.problem, algorithm)
|
|
39
|
+
|
|
40
|
+
if self.do_show:
|
|
41
|
+
if figure is not None:
|
|
42
|
+
figure.show()
|
|
43
|
+
else:
|
|
44
|
+
plt.show()
|
|
45
|
+
|
|
46
|
+
if self.recorder is not None:
|
|
47
|
+
self.recorder.record(fig=figure)
|
|
48
|
+
|
|
49
|
+
if self.do_close:
|
|
50
|
+
plt.close(fig=figure)
|
|
51
|
+
|
|
52
|
+
return figure
|
|
53
|
+
|
|
54
|
+
except Exception as ex:
|
|
55
|
+
if self.exception_if_not_applicable:
|
|
56
|
+
raise ex
|
|
57
|
+
|
|
58
|
+
def do(self, problem, algorithm, **kwargs):
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ObjectiveSpaceAnimation(AnimationCallback):
|
|
63
|
+
|
|
64
|
+
def __init__(self, recorder=None, **kwargs):
|
|
65
|
+
if recorder is None:
|
|
66
|
+
from pyrecorder.recorder import Recorder
|
|
67
|
+
from pyrecorder.writers.streamer import Streamer
|
|
68
|
+
recorder = Recorder(Streamer())
|
|
69
|
+
super().__init__(recorder=recorder, **kwargs)
|
|
70
|
+
|
|
71
|
+
def update(self, algorithm):
|
|
72
|
+
F = algorithm.opt.get("F")
|
|
73
|
+
pf = algorithm.problem.pareto_front()
|
|
74
|
+
|
|
75
|
+
sc = Scatter()
|
|
76
|
+
sc.add(F)
|
|
77
|
+
if pf is not None:
|
|
78
|
+
sc.add(pf, plot_type="line", color="black", alpha=0.7)
|
|
79
|
+
sc.do()
|
|
80
|
+
|
|
81
|
+
self.recorder.record()
|
|
82
|
+
|