Source code for pymoo.visualization.pcp

import numpy as np

from pymoo.docs import parse_doc_string
from pymoo.core.plot import Plot
from pymoo.util.misc import set_if_none, set_if_none_from_tuples
from pymoo.visualization.util import parse_bounds, normalize
from pymoo.visualization.matplotlib import plt


[docs] class PCP(Plot): def __init__(self, bounds=None, show_bounds=True, n_ticks=5, normalize_each_axis=True, bbox=False, **kwargs): """ Parallel Coordinate Plot Parameters ---------- bounds : {bounds} axis_style : {axis_style} labels : {labels} n_ticks : int Number of ticks to be shown on each parallel axis. show_bounds : bool Whether the value of the boundaries are shown in the plot or not. normalize_each_axis : bool Whether the values should be normalized either by bounds or implicitly. Other Parameters ---------------- figsize : {figsize} title : {title} legend : {legend} tight_layout : {tight_layout} cmap : {cmap} """ super().__init__(bounds=bounds, **kwargs) self.show_bounds = show_bounds self.n_ticks = n_ticks self.bbox = bbox self.normalize_each_axis = normalize_each_axis set_if_none_from_tuples(self.axis_style, ("color", "red"), ("linewidth", 2), ("alpha", 0.75)) def _do(self): # initial a figure with a single plot self.init_figure() # if no normalization of each axis the bounds are based on the overall min and max if not self.normalize_each_axis and self.bounds is None: _F = np.vstack([e[0] for e in self.to_plot]) self.bounds = [_F.min(), _F.max()] # normalize the input bounds = parse_bounds(self.bounds, self.n_dim) to_plot_norm, bounds = normalize(self.to_plot, bounds, return_bounds=True) # plot for each set the lines for k, (F, kwargs) in enumerate(to_plot_norm): _kwargs = kwargs.copy() set_if_none(_kwargs, "color", self.colors[k % len(self.colors)]) for i in range(len(F)): plt.plot(np.arange(F.shape[1]), F[i, :], **_kwargs) # Plot the parallel coordinate axes for i in range(self.n_dim): self.ax.axvline(i, **self.axis_style) bottom, top = -0.1, 1.075 margin_left = 0.08 if self.show_bounds: lower = self.ax.text(i - margin_left, bottom, self.func_number_to_text(bounds[0][i])) upper = self.ax.text(i - margin_left, top, self.func_number_to_text(bounds[1][i])) if self.bbox: lower.set_bbox(dict(facecolor='white', alpha=0.8)) upper.set_bbox(dict(facecolor='white', alpha=0.8)) if self.n_ticks is not None: n_length = 0.03 for y in np.linspace(0, 1, self.n_ticks): self.ax.hlines(y, i - n_length, i + n_length, **self.axis_style) # if bounds are shown, then move them to the bottom if self.show_bounds: self.ax.tick_params(axis='x', which='major', pad=25) self.ax.spines['right'].set_visible(False) self.ax.spines['left'].set_visible(False) self.ax.set_yticklabels([]) self.ax.set_yticks([]) self.ax.set_ylim((-0.05, 1.05)) self.ax.set_xticks(np.arange(self.n_dim)) self.ax.set_xticklabels(self.get_labels()) return self
parse_doc_string(PCP.__init__)