Source code for glennopt.helpers.post_processing

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
from tqdm import trange
from typing import List

from ..base import Individual
from .convert_to_ndarray import convert_to_ndarray
from .nsga_functions import non_dominated_sorting

[docs]def get_best(individuals:List[Individual],pop_size:int): """Gets the best individual vs Pop. Some populations won't generate a better design but the best design will always be carried to the next population for crossover + mutation Important: Call this function with inputs from ``individuals = ns.read_calculation_folder()`` Args: individuals (List[Individual]): Takes in a list of the individuals pop_size (int): population size i.e. how many individuals Returns: (tuple): tuple containing: **objectives** (List[Parameter]): numpy array of best objective values for each population. For multi-objective problems use best fronts for better representation of design space **pop_folders** (List[int]): this is a list of populations **best_fronts** (List[List[Individual]]): List of individuals contained in best fronts, empty list if single objective """ best_individuals,best_fronts = get_pop_best(individuals) objectives = list() nobjectives = len(individuals[0][0].objectives) keys = list(best_individuals.keys()) for i in range(len(individuals)): key = keys[i] temp_objectives = list() if i == 0: for o in range(nobjectives): temp_objectives.append(best_individuals[key][o].objectives[o]) else: for o in range(nobjectives): if best_individuals[key][o].objectives[o] < objectives[-1][o]: temp_objectives.append(best_individuals[key][o].objectives[o]) else: temp_objectives.append(objectives[-1][o]) objectives.append(temp_objectives) # Read calculation folder best_fronts = list() if nobjectives>1: rolling_best = list() for i in trange(len(individuals), desc='Running Non-dimensional sorting'): pop_individuals = individuals[i] rolling_best.extend(pop_individuals) best_fronts.append(non_dominated_sorting(rolling_best,len(pop_individuals),True)) if (len(rolling_best)>pop_size): rolling_best = rolling_best[-pop_size:] # Keep only the pop_size pop_folders = keys return convert_to_ndarray(objectives), pop_folders, best_fronts # First front
[docs]def get_pop_best(individuals:List[Individual]): ''' Gets the best individuals from each population (not rolling best) typically you would use opt.read_calculation_folder() where opt is an object representing your nsga3 or sode class. Note: Important: Call this function with inputs from `individuals = ns.read_calculation_folder()` Returns: (tuple): tuple containing: **best_individuals** (List[Dict[str,List[Individual]]]): this is an array of individuals that are best at each objective | [ | POP001: [best_individual_objective1, best_individual,objective2, best_individual,objective3], best_individual_compromise | POP002: [best_individual_objective1, best_individual,objective2, best_individual,objective3], best_individual_compromise | POP003: [best_individual_objective1, best_individual,objective2, best_individual,objective3], best_individual_compromise | ] **comp_individuals** (List[Individual]): this is an array of individuals that is the best compromise between all the objectives ''' # Read calculation folder # (Compromise Target) At the minimum index of each objective what are the values of the other objectives nobjectives = len(individuals[0][0].objectives) best_fronts = list() best_individuals = dict() for pop_individuals in individuals: pop = pop_individuals[0].population if nobjectives>1: best_fronts.append(non_dominated_sorting(pop_individuals,len(pop_individuals),True)) for ind in pop_individuals: if pop not in best_individuals.keys(): # Prepopulate best_individuals[pop] = list() for o in range(nobjectives): best_individuals[pop].append(ind) else: # Compare for o in range(nobjectives): # Checks for the best objective current_best = best_individuals[pop][o].objectives[o] if ind.objectives[o]<current_best: best_individuals[pop][o] = ind return best_individuals, best_fronts
[docs]def plot_pareto(best_fronts,pop,objective1_index,objective2_index): ''' ''' fig,ax = plt.subplots() colors = cm.rainbow(np.linspace(0, 1, len(best_fronts))) indx = 0 legend_labels = [] # Scan the pandas file, grab objectives for each population for ind_list in best_fronts: obj1_data = [] obj2_data = [] c=colors[indx] for ind in ind_list: obj1_data.append(ind.objectives[objective1_index]) obj2_data.append(ind.objectives[objective2_index]) # Plot the gathered data ax.scatter(obj1_data, obj2_data, color=c, s=10,alpha=0.5) legend_labels.append(pop[indx]) indx+=1 ax.set_xlabel(obj1_name) ax.set_ylabel(obj2_name) if xlim is not None: ax.set_xlim(xlim[0],xlim[1]) if ylim is not None: ax.set_ylim(ylim[0],ylim[1]) ax.legend(legend_labels) fig.canvas.draw() fig.canvas.flush_events() plt.show()