def plot_hypervolumes(hyperv, # type: Dict[AnyStr, Optional[int, float, List[List[int], List[float]]]] ws, # type: AnyStr cn=False, # type: bool # Deprecated! Please use plot_cfg=PlotConfig instead. plot_cfg=None # type: Optional[PlotConfig] ): # type: (...) -> bool """Plot hypervolume of multiple optimization methods Args: hyperv: Dict, key is method name and value is generation IDs list and hypervolumes list Optionally, key-values of 'bottom' and 'top' are allowed. ws: Full path of the destination directory cn: (Optional) Use Chinese. Deprecated! plot_cfg: (Optional) Plot settings for matplotlib """ if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = plot_cfg.font_name generation_str = (u'进化代数' if plot_cfg.plot_cn else 'Generation') hyperv_str = (u'Hypervolume 指数' if plot_cfg.plot_cn else 'Hypervolume index') # Line styles: https://matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html linestyles = ['-', '--', '-.', ':'] # plot accumulate pop size fig, ax = plt.subplots(figsize=(9, 8)) mark_idx = 0 for method, gen_hyperv in viewitems(hyperv): if not isinstance(gen_hyperv, list): continue xdata = gen_hyperv[0] ydata = gen_hyperv[1] plt.plot(xdata, ydata, linestyle=linestyles[mark_idx], color='black', label=method, linewidth=2) mark_idx += 1 plt.legend(fontsize=plot_cfg.legend_fsize, loc=4) xaxis = plt.gca().xaxis yaxis = plt.gca().yaxis for xticklabel in xaxis.get_ticklabels(): xticklabel.set_fontsize(plot_cfg.tick_fsize) for yticklabel in yaxis.get_ticklabels(): yticklabel.set_fontsize(plot_cfg.tick_fsize) plt.xlabel(generation_str, fontsize=plot_cfg.axislabel_fsize) plt.ylabel(hyperv_str, fontsize=plot_cfg.axislabel_fsize) ax.set_xlim(left=0, right=ax.get_xlim()[1] + 2) if 'bottom' in hyperv: ax.set_ylim(bottom=hyperv['bottom']) if 'top' in hyperv: ax.set_ylim(top=hyperv['top']) plt.tight_layout() save_png_eps(plt, ws, 'hypervolume', plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close() return True
def plot_hypervolumes(hyperv, ws, cn=False): # type: (Dict[AnyStr, Optional[int, float, List[List[int], List[float]]]], AnyStr, bool) -> bool """Plot hypervolume of multiple optimization methods Args: hyperv: Dict, key is method name and value is generation IDs list and hypervolumes list Optionally, key-values of 'bottom' and 'top' are allowed. ws: Full path of the destination directory cn: (Optional) Use Chinese """ plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = 'Palatino Linotype' # 'Times New Roman' generation_str = 'Generation' hyperv_str = 'Hypervolume index' if cn: plt.rcParams['font.family'] = 'SimSun' # 宋体 generation_str = u'进化代数' hyperv_str = u'Hypervolume 指数' # Line styles: https://matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html linestyles = ['-', '--', '-.', ':'] # plot accumulate pop size fig, ax = plt.subplots(figsize=(9, 8)) mark_idx = 0 for method, gen_hyperv in viewitems(hyperv): if not isinstance(gen_hyperv, list): continue xdata = gen_hyperv[0] ydata = gen_hyperv[1] plt.plot(xdata, ydata, linestyle=linestyles[mark_idx], color='black', label=method, linewidth=2) mark_idx += 1 plt.legend(fontsize=16, loc=4) xaxis = plt.gca().xaxis yaxis = plt.gca().yaxis for xlebal in xaxis.get_ticklabels(): xlebal.set_fontsize(20) for ylebal in yaxis.get_ticklabels(): ylebal.set_fontsize(20) plt.xlabel(generation_str, fontsize=20) plt.ylabel(hyperv_str, fontsize=20) ax.set_xlim(left=0, right=ax.get_xlim()[1] + 2) if 'bottom' in hyperv: ax.set_ylim(bottom=hyperv['bottom']) if 'top' in hyperv: ax.set_ylim(top=hyperv['top']) plt.tight_layout() save_png_eps(plt, ws, 'hypervolume') # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close() return True
def plot_2d_scatter(xlist, # type: List[float] # X coordinates ylist, # type: List[float] # Y coordinates title, # type: AnyStr # Main title of the figure xlabel, # type: AnyStr # X-axis label ylabel, # type: AnyStr # Y-axis label ws, # type: AnyStr # Full path of the destination directory filename, # type: AnyStr # File name without suffix (e.g., jpg, eps) subtitle='', # type: AnyStr # Subtitle cn=False, # type: bool # Use Chinese or not. Deprecated! xmin=None, # type: Optional[float] # Left min X value xmax=None, # type: Optional[float] # Right max X value xstep=None, # type: Optional[float] # X interval ymin=None, # type: Optional[float] # Bottom min Y value ymax=None, # type: Optional[float] # Up max Y value ystep=None, # type: Optional[float] # Y interval plot_cfg=None # type: Optional[PlotConfig] ): # type: (...) -> None """Scatter plot of 2D points. Todo: The size of the point may be vary with the number of points. """ if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['font.family'] = plot_cfg.font_name plt.figure() plt.title('%s\n' % title, color='red', fontsize=plot_cfg.title_fsize) plt.xlabel(xlabel, fontsize=plot_cfg.axislabel_fsize) plt.ylabel(ylabel, fontsize=plot_cfg.axislabel_fsize) plt.scatter(xlist, ylist, c='r', alpha=0.8, s=12) if xmax is not None: plt.xlim(right=xmax) if xmin is not None: plt.xlim(left=xmin) if xstep is not None: xmin, xmax = plt.xlim() plt.xticks(numpy.arange(xmin, xmax + xstep * 0.99, step=xstep), fontsize=plot_cfg.tick_fsize) if ymax is not None: plt.ylim(top=ymax) if ymin is not None: plt.ylim(bottom=ymin) if ystep is not None: ymin, ymax = plt.ylim() plt.yticks(numpy.arange(ymin, ymax + ystep * 0.99, step=ystep), fontsize=plot_cfg.tick_fsize) if subtitle != '': plt.title(subtitle, color='green', fontsize=plot_cfg.label_fsize, loc='right') plt.tight_layout() save_png_eps(plt, ws, filename, plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def plot_morris(self): """Save plot as png(300 dpi) and eps (vector).""" if not self.psa_si: self.calculate_sensitivity() for i, v in enumerate(self.objnames): fig, (ax1, ax2) = plt.subplots(1, 2) horizontal_bar_plot(ax1, self.psa_si.get(i), {}, sortby='mu_star') covariance_plot(ax2, self.psa_si.get(i), {}) save_png_eps(plt, self.cfg.psa_outpath, 'mu_star_%s' % v) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def sample_histograms(input_sample, names, levels, outpath, outname, param_dict): """Plot histograms as subplot. Args: input_sample: names: levels: outpath: outname: param_dict: Returns: subplot list. """ fig = plt.figure() num_vars = len(names) row, col = cal_row_col_num(num_vars) for var_idx in range(num_vars): ax = fig.add_subplot(row, col, var_idx + 1) print('%s: %.3f - %.3f, mean: %.3f' % (names[var_idx], min(input_sample[:, var_idx]), max(input_sample[:, var_idx]), numpy.average(input_sample[:, var_idx]))) ax.hist(input_sample[:, var_idx], bins=levels, normed=False, label=None, **param_dict) ax.get_yaxis().set_major_locator(LinearLocator(numticks=5)) ax.get_xaxis().set_major_locator(LinearLocator(numticks=5)) ax.set_title('%s' % (names[var_idx])) ax.tick_params(axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='on', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='on') # labels along the bottom edge are off) ax.tick_params(axis='y', # changes apply to the y-axis which='major', # both major and minor ticks are affected length=3, right='off') if var_idx % col: # labels along the left edge are off ax.tick_params(axis='y', labelleft='off') plt.tight_layout() save_png_eps(plt, outpath, outname) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def generate_plots(self): """Generate hydrographs of discharge, sediment, nutrient (amount or concentrate), etc.""" # set ticks direction, in or out plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = self.plot_cfg.font_name plt.rcParams['mathtext.fontset'] = 'custom' plt.rcParams['mathtext.it'] = 'STIXGeneral:italic' plt.rcParams['mathtext.bf'] = 'STIXGeneral:italic:bold' obs_str = 'Observation' sim_str = 'Simulation' cali_str = 'Calibration' vali_str = 'Validation' pcp_str = 'Precipitation' pcpaxis_str = 'Precipitation (mm)' xaxis_str = 'Date time' if self.plot_cfg.plot_cn: plt.rcParams['axes.unicode_minus'] = False obs_str = u'观测值' sim_str = u'模拟值' cali_str = u'率定期' vali_str = u'验证期' pcp_str = u'降水' pcpaxis_str = u'降水 (mm)' xaxis_str = u'时间' sim_date = list(self.sim_data_dict.keys()) for i, param in enumerate(self.plot_vars): # plt.figure(i) fig, ax = plt.subplots(figsize=(12, 4)) ylabel_str = param if param in ['Q', 'QI', 'QG', 'QS']: ylabel_str += ' (m$^3$/s)' elif 'CONC' in param.upper(): # Concentrate if 'SED' in param.upper(): ylabel_str += ' (g/L)' else: ylabel_str += ' (mg/L)' elif 'SED' in param.upper(): # amount ylabel_str += ' (kg)' obs_dates = None # type: List[datetime] obs_values = None # type: List[float] if self.sim_obs_dict and param in self.sim_obs_dict: obs_dates = self.sim_obs_dict[param][DataValueFields.utc] obs_values = self.sim_obs_dict[param]['Obs'] # append validation data if self.vali_sim_obs_dict and param in self.vali_sim_obs_dict: obs_dates += self.vali_sim_obs_dict[param][DataValueFields.utc] obs_values += self.vali_sim_obs_dict[param]['Obs'] if obs_values is not None: # TODO: if the observed data is continuous with datetime, plot line, otherwise, bar. # bar graph p1 = ax.bar(obs_dates, obs_values, label=obs_str, color='none', edgecolor='black', linewidth=0.5, align='center', hatch='//') # # line graph # p1, = ax.plot(obs_dates, obs_values, label=obs_str, color='black', marker='+', # markersize=2, linewidth=1) sim_list = [v[i + 1] for v in self.sim_data_value] p2, = ax.plot(sim_date, sim_list, label=sim_str, color='red', marker='+', markersize=2, linewidth=0.8) plt.xlabel(xaxis_str, fontdict={'size': self.plot_cfg.axislabel_fsize}) # format the ticks date axis date_fmt = mdates.DateFormatter('%m-%d-%y') # autodates = mdates.AutoDateLocator() # days = mdates.DayLocator(bymonthday=range(1, 32), interval=4) # months = mdates.MonthLocator() # ax.xaxis.set_major_locator(months) ax.xaxis.set_major_formatter(date_fmt) # ax.xaxis.set_minor_locator(days) ax.tick_params('both', length=5, width=2, which='major', labelsize=self.plot_cfg.tick_fsize) ax.tick_params('both', length=3, width=1, which='minor', labelsize=self.plot_cfg.tick_fsize) ax.set_xlim(left=self.sim_data_value[0][0], right=self.sim_data_value[-1][0]) fig.autofmt_xdate(rotation=0, ha='center') plt.ylabel(ylabel_str, fontdict={'size': self.plot_cfg.axislabel_fsize}) # plt.legend(bbox_to_anchor = (0.03, 0.85), loc = 2, shadow = True) if obs_values is not None: ymax = max(max(sim_list), max(obs_values)) * 1.6 ymin = min(min(sim_list), min(obs_values)) * 0.8 else: ymax = max(sim_list) * 1.8 ymin = min(sim_list) * 0.8 ax.set_ylim(float(ymin), float(ymax)) ax2 = ax.twinx() ax.tick_params(axis='x', which='both', bottom=True, top=False, labelsize=self.plot_cfg.tick_fsize) ax2.tick_params(axis='y', length=5, width=2, which='major', labelsize=self.plot_cfg.tick_fsize) ax2.set_ylabel(pcpaxis_str, fontdict={'size': self.plot_cfg.axislabel_fsize}) pcp_date = [v[0] for v in self.pcp_date_value] preci = [v[1] for v in self.pcp_date_value] p3 = ax2.bar(pcp_date, preci, label=pcp_str, color='blue', linewidth=0, align='center') ax2.set_ylim(float(max(preci)) * 1.8, float(min(preci)) * 0.8) # draw a dash line to separate calibration and validation period delta_dt = (self.sim_data_value[-1][0] - self.sim_data_value[0][0]) // 9 delta_dt2 = (self.sim_data_value[-1][0] - self.sim_data_value[0][0]) // 35 # by default, separate time line is the end of calibration period sep_time = self.etime time_pos = [sep_time - delta_dt] ymax, ymin = ax2.get_ylim() yc = abs(ymax - ymin) / 4. order = 1 # By default, calibration period is before validation period if self.plot_validation: sep_time = self.vali_stime if self.vali_stime >= self.etime else self.stime cali_vali_labels = [cali_str, vali_str] if self.vali_stime < self.stime: order = 0 cali_vali_labels = [vali_str, cali_str] time_pos = [sep_time - delta_dt, sep_time + delta_dt2] ax.axvline(sep_time, color='black', linestyle='dashed', linewidth=2) plt.text(time_pos[0], yc, cali_vali_labels[0], fontdict={ 'style': 'italic', 'weight': 'bold', 'size': self.plot_cfg.label_fsize }, color='black') plt.text(time_pos[1], yc, cali_vali_labels[1], fontdict={ 'style': 'italic', 'weight': 'bold', 'size': self.plot_cfg.label_fsize }, color='black') # set legend and labels if obs_values is None or len(obs_values) < 2: leg = ax.legend([p3, p2], [pcp_str, sim_str], ncol=2, bbox_to_anchor=(0., 1.02, 1., 0.102), borderaxespad=0.2, loc='lower left', fancybox=True, fontsize=self.plot_cfg.legend_fsize) else: leg = ax.legend([p3, p1, p2], [pcp_str, obs_str, sim_str], bbox_to_anchor=(0., 1.02, 1., 0.102), borderaxespad=0., ncol=3, loc='lower left', fancybox=True, fontsize=self.plot_cfg.legend_fsize) try: nse = self.sim_obs_dict[param]['NSE'] # type: float r2 = self.sim_obs_dict[param]['R-square'] # type: float pbias = self.sim_obs_dict[param]['PBIAS'] # type: float rsr = self.sim_obs_dict[param]['RSR'] # type: float cali_txt = '$\mathit{NSE}$: %.2f\n$\mathit{RSR}$: %.2f\n' \ '$\mathit{PBIAS}$: %.2f%%\n$\mathit{R^2}$: %.2f' % \ (nse, rsr, pbias, r2) print_msg_header = 'Cali-%s-NSE,Cali-%s-RSR,' \ 'Cali-%s-PBIAS,Cali-%s-R2,' % (param, param, param, param) print_msg = '%.3f,%.3f,%.3f,%.3f,' % (nse, rsr, pbias, r2) cali_pos = time_pos[0] if order else time_pos[1] plt.text(cali_pos, yc * 2.5, cali_txt, color='red', fontsize=self.plot_cfg.label_fsize - 1) if self.plot_validation and self.vali_sim_obs_dict: nse = self.vali_sim_obs_dict[param]['NSE'] r2 = self.vali_sim_obs_dict[param]['R-square'] pbias = self.vali_sim_obs_dict[param]['PBIAS'] rsr = self.vali_sim_obs_dict[param]['RSR'] vali_txt = '$\mathit{NSE}$: %.2f\n$\mathit{RSR}$: %.2f\n' \ '$\mathit{PBIAS}$: %.2f%%\n$\mathit{R^2}$: %.2f' % \ (nse, rsr, pbias, r2) print_msg_header += 'Vali-%s-NSE,Vali-%s-RSR,' \ 'Vali-%s-PBIAS,' \ 'Vali-%s-R2' % (param, param, param, param) print_msg += '%.3f,%.3f,%.3f,%.3f' % (nse, rsr, pbias, r2) vali_pos = time_pos[1] if order else time_pos[0] plt.text(vali_pos, yc * 2.5, vali_txt, color='red', fontsize=self.plot_cfg.label_fsize - 1) print('%s\n%s\n' % (print_msg_header, print_msg)) except ValueError or Exception: pass plt.tight_layout() leg.get_frame().set_alpha(0.5) timerange = '%s-%s' % (self.sim_data_value[0][0].strftime( '%Y-%m-%d'), self.sim_data_value[-1][0].strftime('%Y-%m-%d')) save_png_eps(plt, self.ws, param + '-' + timerange, self.plot_cfg)
def calculate_95ppu(sim_obs_data, sim_data, outdir, gen_num, vali_sim_obs_data=None, vali_sim_data=None, plot_cfg=None # type: Optional[PlotConfig] ): """Calculate 95% prediction uncertainty and plot the hydrographs.""" if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = plot_cfg.font_name plt.rcParams['timezone'] = 'UTC' plt.rcParams['mathtext.fontset'] = 'custom' plt.rcParams['mathtext.it'] = 'STIXGeneral:italic' plt.rcParams['mathtext.bf'] = 'STIXGeneral:italic:bold' if len(sim_data) < 2: return var_name = sim_obs_data[0]['var_name'] for idx, var in enumerate(var_name): plot_validation = False if vali_sim_obs_data and vali_sim_data and var in vali_sim_obs_data[0]['var_name']: plot_validation = True ylabel_str = var if var in ['Q', 'QI', 'QG', 'QS']: ylabel_str += ' (m$^3$/s)' elif 'CONC' in var.upper(): # Concentrate if 'SED' in var.upper(): ylabel_str += ' (g/L)' else: ylabel_str += ' (mg/L)' elif 'SED' in var.upper(): # amount ylabel_str += ' (kg)' cali_obs_dates = sim_obs_data[0][var]['UTCDATETIME'][:] if is_string(cali_obs_dates[0]): cali_obs_dates = [StringClass.get_datetime(s) for s in cali_obs_dates] obs_dates = cali_obs_dates[:] order = 1 # By default, the calibration period is before the validation period. if plot_validation: vali_obs_dates = vali_sim_obs_data[0][var]['UTCDATETIME'] if is_string(vali_obs_dates[0]): vali_obs_dates = [StringClass.get_datetime(s) for s in vali_obs_dates] if vali_obs_dates[-1] <= cali_obs_dates[0]: order = 0 obs_dates = vali_obs_dates + obs_dates else: obs_dates += vali_obs_dates obs_data = sim_obs_data[0][var]['Obs'][:] if plot_validation: if order: obs_data += vali_sim_obs_data[0][var]['Obs'][:] else: obs_data = vali_sim_obs_data[0][var]['Obs'][:] + obs_data cali_sim_dates = list(sim_data[0].keys()) if is_string(cali_sim_dates[0]): cali_sim_dates = [StringClass.get_datetime(s) for s in cali_sim_dates] sim_dates = cali_sim_dates[:] if plot_validation: vali_sim_dates = list(vali_sim_data[0].keys()) if is_string(vali_sim_dates[0]): vali_sim_dates = [StringClass.get_datetime(s) for s in vali_sim_dates] if order: sim_dates += vali_sim_dates else: sim_dates = vali_sim_dates + sim_dates sim_data_list = list() caliBestIdx = -1 caliBestNSE = -9999. for idx2, ind in enumerate(sim_data): tmp = numpy.array(list(ind.values())) tmp = tmp[:, idx] if sim_obs_data[idx2][var]['NSE'] > caliBestNSE: caliBestNSE = sim_obs_data[idx2][var]['NSE'] caliBestIdx = idx2 tmpsim = tmp.tolist() if plot_validation: tmp_data = numpy.array(list(vali_sim_data[idx2].values()))[:, idx].tolist() if order: tmpsim += tmp_data else: tmpsim = tmp_data + tmpsim sim_data_list.append(tmpsim) sim_best = numpy.array(list(sim_data[caliBestIdx].values()))[:, idx] sim_best = sim_best.tolist() if plot_validation: tmp_data = numpy.array(list(vali_sim_data[caliBestIdx].values()))[:, idx].tolist() if order: sim_best += tmp_data else: sim_best = tmp_data + sim_best sim_data_list = numpy.array(sim_data_list) ylows = numpy.percentile(sim_data_list, 2.5, 0, interpolation='nearest') yups = numpy.percentile(sim_data_list, 97.5, 0, interpolation='nearest') def calculate_95ppu_efficiency(obs_data_list, obs_dates_list, sim_dates_list): # type: (...) -> (float, float) count = 0 ylows_obs = list() yups_obs = list() for oi, ov in enumerate(obs_data_list): try: si = sim_dates_list.index(obs_dates_list[oi]) ylows_obs.append(ylows[si]) yups_obs.append(yups[si]) if ylows[si] <= ov <= yups[si]: count += 1 except Exception: continue p = float(count) / len(obs_data_list) ylows_obs = numpy.array(ylows_obs) yups_obs = numpy.array(yups_obs) r = numpy.mean(yups_obs - ylows_obs) / numpy.std(numpy.array(obs_data_list)) return p, r # concatenate text p_value, r_value = calculate_95ppu_efficiency(sim_obs_data[0][var]['Obs'], cali_obs_dates, list(sim_data[0].keys())) txt = 'P-factor: %.2f\nR-factor: %.2f\n' % (p_value, r_value) txt += u'某一最优模拟\n' if plot_cfg.plot_cn else 'One best simulation:\n' txt += ' $\mathit{NSE}$: %.2f\n' \ ' $\mathit{RSR}$: %.2f\n' \ ' $\mathit{PBIAS}$: %.2f%%\n' \ ' $\mathit{R^2}$: %.2f' % (sim_obs_data[caliBestIdx][var]['NSE'], sim_obs_data[caliBestIdx][var]['RSR'], sim_obs_data[caliBestIdx][var]['PBIAS'], sim_obs_data[caliBestIdx][var]['R-square']) # concatenate text of validation if needed vali_txt = '' if plot_validation: p_value, r_value = calculate_95ppu_efficiency(vali_sim_obs_data[0][var]['Obs'], vali_obs_dates, list(vali_sim_data[0].keys())) vali_txt = 'P-factor: %.2f\nR-factor: %.2f\n\n' % (p_value, r_value) vali_txt += ' $\mathit{NSE}$: %.2f\n' \ ' $\mathit{RSR}$: %.2f\n' \ ' $\mathit{PBIAS}$: %.2f%%\n' \ ' $\mathit{R^2}$: %.2f' % (vali_sim_obs_data[caliBestIdx][var]['NSE'], vali_sim_obs_data[caliBestIdx][var]['RSR'], vali_sim_obs_data[caliBestIdx][var]['PBIAS'], vali_sim_obs_data[caliBestIdx][var]['R-square']) # plot fig, ax = plt.subplots(figsize=(12, 4)) ax.fill_between(sim_dates, ylows.tolist(), yups.tolist(), color=(0.8, 0.8, 0.8), label='95PPU') observed_label = u'实测值' if plot_cfg.plot_cn else 'Observed points' ax.scatter(obs_dates, obs_data, marker='.', s=20, color='g', label=observed_label) besesim_label = u'最优模拟' if plot_cfg.plot_cn else 'Best simulation' ax.plot(sim_dates, sim_best, linestyle='--', color='red', linewidth=1, label=besesim_label) ax.set_xlim(left=min(sim_dates), right=max(sim_dates)) ax.set_ylim(bottom=0.) date_fmt = mdates.DateFormatter('%m-%d-%y') ax.xaxis.set_major_formatter(date_fmt) ax.tick_params(axis='x', bottom=True, top=False, length=5, width=2, which='major', labelsize=plot_cfg.tick_fsize) ax.tick_params(axis='y', left=True, right=False, length=5, width=2, which='major', labelsize=plot_cfg.tick_fsize) plt.xlabel(u'时间' if plot_cfg.plot_cn else 'Date time', fontsize=plot_cfg.axislabel_fsize) plt.ylabel(ylabel_str, fontsize=plot_cfg.axislabel_fsize) # plot separate dash line delta_dt = (sim_dates[-1] - sim_dates[0]) // 9 delta_dt2 = (sim_dates[-1] - sim_dates[0]) // 35 sep_time = sim_dates[-1] time_pos = [sep_time - delta_dt] time_pos2 = [sep_time - 2 * delta_dt] ymax, ymin = ax.get_ylim() yc = abs(ymax - ymin) * 0.9 if plot_validation: sep_time = vali_sim_dates[0] if vali_sim_dates[0] >= cali_sim_dates[-1] \ else cali_sim_dates[0] cali_vali_labels = [(u'验证期' if plot_cfg.plot_cn else 'Calibration'), (u'率定期' if plot_cfg.plot_cn else 'Validation')] if not order: cali_vali_labels.reverse() time_pos = [sep_time - delta_dt, sep_time + delta_dt2] time_pos2 = [sep_time - 2 * delta_dt, sep_time + delta_dt2] ax.axvline(sep_time, color='black', linestyle='dashed', linewidth=2) plt.text(time_pos[0], yc, cali_vali_labels[0], fontdict={'style': 'italic', 'weight': 'bold', 'size': plot_cfg.label_fsize}, color='black') plt.text(time_pos[1], yc, cali_vali_labels[1], fontdict={'style': 'italic', 'weight': 'bold', 'size': plot_cfg.label_fsize}, color='black') # add legend handles, labels = ax.get_legend_handles_labels() figorders = [labels.index('95PPU'), labels.index(observed_label), labels.index(besesim_label)] ax.legend([handles[idx] for idx in figorders], [labels[idx] for idx in figorders], fontsize=plot_cfg.legend_fsize, loc=2, framealpha=0.8) # add text cali_pos = time_pos[0] if order else time_pos[1] plt.text(cali_pos, yc * 0.5, txt, color='red', fontsize=plot_cfg.label_fsize - 1) if plot_validation: vali_pos = time_pos[1] if order else time_pos[0] plt.text(vali_pos, yc * 0.5, vali_txt, color='red', fontsize=plot_cfg.label_fsize - 1) # fig.autofmt_xdate(rotation=0, ha='center') plt.tight_layout() save_png_eps(plt, outdir, 'Gen%d_95ppu_%s' % (gen_num, var), plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def plot_3d_scatter(xlist, # type: List[float] # X coordinates ylist, # type: List[float] # Y coordinates zlist, # type: List[float] # Z coordinates title, # type: AnyStr # Main title of the figure xlabel, # type: AnyStr # X-axis label ylabel, # type: AnyStr # Y-axis label zlabel, # type: AnyStr # Z-axis label ws, # type: AnyStr # Full path of the destination directory filename, # type: AnyStr # File name without suffix (e.g., jpg, eps) subtitle='', # type: AnyStr # Subtitle cn=False, # type: bool # Use Chinese or not xmin=None, # type: Optional[float] # Left min X value xmax=None, # type: Optional[float] # Right max X value ymin=None, # type: Optional[float] # Bottom min Y value ymax=None, # type: Optional[float] # Up max Y value zmin=None, # type: Optional[float] # Min Z value zmax=None, # type: Optional[float] # Max Z value xstep=None, # type: Optional[float] # X interval ystep=None, # type: Optional[float] # Y interval zstep=None, # type: Optional[float] # Z interval plot_cfg=None # type: Optional[PlotConfig] ): # type: (...) -> None """Scatter plot of 3D points. """ if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['font.family'] = plot_cfg.font_name fig = plt.figure() ax = fig.add_subplot(111, projection='3d') plt.suptitle('%s\n' % title, color='red', fontsize=plot_cfg.title_fsize) ax.set_xlabel(xlabel, fontsize=plot_cfg.axislabel_fsize) ax.set_ylabel(ylabel, fontsize=plot_cfg.axislabel_fsize) ax.set_zlabel(zlabel, fontsize=plot_cfg.axislabel_fsize) ax.scatter(xlist, ylist, zlist, c='r', s=12) for xticklabel in ax.xaxis.get_ticklabels(): xticklabel.set_fontsize(plot_cfg.tick_fsize) for yticklabel in ax.yaxis.get_ticklabels(): yticklabel.set_fontsize(plot_cfg.tick_fsize) for zticklabel in ax.zaxis.get_ticklabels(): zticklabel.set_fontsize(plot_cfg.tick_fsize) if xmax is not None: ax.set_xlim(right=xmax) if xmin is not None: ax.set_xlim(left=xmin) if xstep is not None: xmin, xmax = ax.get_xlim() ax.set_xticks(numpy.arange(xmin, xmax + xstep * 0.99, step=xstep)) if ymax is not None: ax.set_ylim(top=ymax) if ymin is not None: ax.set_ylim(bottom=ymin) if ystep is not None: ymin, ymax = ax.get_ylim() ax.set_yticks(numpy.arange(ymin, ymax + ystep * 0.99, step=ystep)) if zmax is not None: ax.set_zlim3d(top=zmax) if zmin is not None: ax.set_zlim3d(bottom=zmin) if zstep is not None: zmin, zmax = ax.get_zlim() ax.set_zticks(numpy.arange(zmin, zmax + zstep * 0.99, step=zstep)) if subtitle != '': plt.title(subtitle, color='green', fontsize=plot_cfg.label_fsize, loc='right') plt.tight_layout() save_png_eps(plt, ws, filename, plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def plot_hypervolume_single(hypervlog, ws=None, cn=False, plot_cfg=None): # type: (AnyStr, Optional[AnyStr], bool, Optional[PlotConfig]) -> bool """Plot hypervolume and the newly executed models of each generation. Args: hypervlog: Full path of the hypervolume log. ws: (Optional) Full path of the destination directory cn: (Optional) Use Chinese. Deprecated! plot_cfg: (Optional) Plot settings for matplotlib """ x, hyperv, nmodel = read_hypervolume(hypervlog) if not x or not hyperv: print('Error: No available hypervolume data loaded!') return False if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = plot_cfg.font_name generation_str = (u'进化代数' if plot_cfg.plot_cn else 'Generation') hyperv_str = (u'Hypervolume 指数' if plot_cfg.plot_cn else 'Hypervolume index') nmodel_str = (u'新运行模型次数' if plot_cfg.plot_cn else 'New model evaluations') linestyles = ['-', '--', '-.', ':'] markers = ['o', 's', 'v', '*'] fig, ax = plt.subplots(figsize=(10, 6)) mark_idx = 0 p1 = ax.plot(x, hyperv, linestyle=linestyles[0], marker=markers[mark_idx], color='black', label=hyperv_str, linewidth=2, markersize=4) mark_idx += 1 plt.xlabel(generation_str, fontsize=plot_cfg.axislabel_fsize) plt.ylabel(hyperv_str, fontsize=plot_cfg.axislabel_fsize) ax.set_xlim(left=0, right=ax.get_xlim()[1]) legends = p1 plt.tight_layout() if ws is None: ws = os.path.dirname(hypervlog) save_png_eps(plt, ws, 'hypervolume', plot_cfg) if nmodel: # Add right Y-axis ax2 = ax.twinx() ax.tick_params(axis='x', which='both', bottom=True, top=False, labelsize=plot_cfg.tick_fsize) ax2.tick_params(axis='y', length=5, width=2, which='major', labelsize=plot_cfg.tick_fsize) ax2.set_ylabel(nmodel_str, fontsize=plot_cfg.axislabel_fsize) p2 = ax2.plot(x, nmodel, linestyle=linestyles[0], marker=markers[mark_idx], color='black', label=nmodel_str, linewidth=2, markersize=4) legends += p2 legends_label = [l.get_label() for l in legends] ax.legend(legends, legends_label, fontsize=plot_cfg.legend_fsize, loc='center right') plt.tight_layout() save_png_eps(plt, ws, 'hypervolume_modelruns', plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close() return True
def plot_pareto_fronts(pareto_data, # type: Dict[AnyStr, Dict[Union[AnyStr, int], Union[List[List[float]], numpy.ndarray]]] xname, # type: List[AnyStr, Optional[float], Optional[float]] yname, # type: List[AnyStr, Optional[float], Optional[float]] gens, # type: List[Union[AnyStr, int]] ws, # type: AnyStr plot_cfg=None # type: Optional[PlotConfig] ): # type: (...) -> None """ Plot Pareto fronts of different methods at a same generation for comparision. Args: pareto_data(OrderedDict) xname(list): the first is x-axis name of plot, the second and third values are low and high limits (optional). yname(list): see xname gens(list): generation to be plotted ws(string): workspace for output files plot_cfg(PlotConfig): Plot settings for matplotlib """ if plot_cfg is None: plot_cfg = PlotConfig() if len(xname) < 1 or len(yname) < 1: xname = ['x-axis'] yname = ['y-axis'] ylabel_str = yname[0] xlabel_str = xname[0] file_name = '-'.join(list(pareto_data.keys())) plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = plot_cfg.font_name # Deprecated code for detecting Chinese characters. # # Check if xname or yname contains Chinese characters # zhPattern = re.compile(u'[\u4e00-\u9fa5]+') # if zhPattern.search(xname[0]) or zhPattern.search(yname[0]): # plt.rcParams['font.family'] = 'SimSun' # 宋体 markers = ['.', '*', '+', 'x', 'd', 'h', 's', '<', '>'] colors = ['r', 'b', 'g', 'c', 'm', 'y', 'k', 'k', 'k'] # plot comparision of Pareto fronts # Get max. and mix. values max_x = None min_x = None max_y = None min_y = None for method, cur_pareto_data in viewitems(pareto_data): if 'min' in cur_pareto_data: if min_x is None or min_x > cur_pareto_data['min'][0]: min_x = cur_pareto_data['min'][0] if min_y is None or min_y > cur_pareto_data['min'][1]: min_y = cur_pareto_data['min'][1] if 'max' in cur_pareto_data: if max_x is None or max_x < cur_pareto_data['max'][0]: max_x = cur_pareto_data['max'][0] if max_y is None or max_y < cur_pareto_data['max'][1]: max_y = cur_pareto_data['max'][1] newxname = xname[:] newyname = yname[:] if min_x is not None and max_x is not None and len(newxname) < 2: newxname += get_optimal_bounds(min_x, max_x) if min_y is not None and max_y is not None and len(newyname) < 2: newyname += get_optimal_bounds(min_y, max_y) for gen in gens: fig, ax = plt.subplots(figsize=(9, 8)) mark_idx = 0 gen_existed = True xdata_list = list() ydata_list = list() marker_list = list() method_list = list() for method, gen_data in viewitems(pareto_data): if gen not in gen_data: gen_existed = False break xdata_list.append(numpy.array(gen_data[gen])[:, 0]) ydata_list.append(numpy.array(gen_data[gen])[:, 1]) marker_list.append(mark_idx) method_list.append(method) mark_idx += 1 if not gen_existed: plt.cla() plt.clf() plt.close() continue xdata_list.reverse() ydata_list.reverse() marker_list.reverse() method_list.reverse() for xdata, ydata, markeridx, method in zip(xdata_list, ydata_list, marker_list, method_list): plt.scatter(xdata, ydata, marker=markers[markeridx], s=100, color=colors[markeridx], label=method) xaxis = plt.gca().xaxis yaxis = plt.gca().yaxis for xticklabel in xaxis.get_ticklabels(): xticklabel.set_fontsize(plot_cfg.tick_fsize) for yticklabel in yaxis.get_ticklabels(): yticklabel.set_fontsize(plot_cfg.tick_fsize) plt.xlabel(xlabel_str, fontsize=plot_cfg.axislabel_fsize) plt.ylabel(ylabel_str, fontsize=plot_cfg.axislabel_fsize) # set xy axis limit curxlim = ax.get_xlim() if len(newxname) >= 3: ax.set_xlim(left=newxname[1]) ax.set_xlim(right=newxname[2]) if len(newxname) >= 4: ax.xaxis.set_ticks(numpy.arange(newxname[1], newxname[2] + newxname[3], newxname[3])) curylim = ax.get_ylim() if len(newyname) >= 3: ax.set_ylim(bottom=newyname[1]) ax.set_ylim(top=newyname[2]) if len(newyname) >= 4: ax.yaxis.set_ticks(numpy.arange(newyname[1], newyname[2] + newyname[3], newyname[3])) handles, labels = ax.get_legend_handles_labels() handles.reverse() labels.reverse() plt.legend(handles, labels, fontsize=plot_cfg.legend_fsize, loc=4) # loc 2: upper left, 4: lower right plt.tight_layout() save_png_eps(plt, ws, 'gen%d' % gen, plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def plot_pareto_fronts_multigenerations(data, # type: Dict[Union[AnyStr, int], Union[List[List[float]], numpy.ndarray]] labels, # type: List[AnyStr] # Labels (axis names) with length of ncols ws, # type: AnyStr # Full path of the destination directory gen_ids, # type: List[int] # Selected generation IDs title, # type: AnyStr # Main title of the figure lowers=None, # type: Optional[numpy.ndarray, List[float]] # Lower values of each axis uppers=None, # type: Optional[numpy.ndarray, List[float]] # Higher values of each axis steps=None, # type: Optional[numpy.ndarray, List[float]] # Intervals of each axis cn=False, # type: bool # Use Chinese or not. Deprecated! plot_cfg=None # type: Optional[PlotConfig] # Plot settings for matplotlib ): # type: (...) -> None """Plot Pareto fronts of selected generations.""" filename = 'Pareto_Generations_%s' % ('-'.join(repr(i) for i in gen_ids)) if plot_cfg is None: plot_cfg = PlotConfig() plt.rcParams['font.family'] = plot_cfg.font_name if plot_cfg.plot_cn: filename += '_cn' fig, ax = plt.subplots(figsize=(9, 8)) # ColorMaps: https://matplotlib.org/tutorials/colors/colormaps.html cmap = cm.get_cmap('gist_heat') # one of the sequential colormaps for idx, gen in enumerate(gen_ids): if gen not in data: continue xdata = numpy.array(data[gen])[:, 0] # first column ydata = numpy.array(data[gen])[:, 1] # second column plt.scatter(xdata, ydata, marker='.', s=100, color=cmap(0.8 * (len(gen_ids) - idx) / len(gen_ids)), label=(u'第 %d 代' if plot_cfg.plot_cn else 'Generation %d') % gen) xaxis = plt.gca().xaxis yaxis = plt.gca().yaxis for xticklabel in xaxis.get_ticklabels(): xticklabel.set_fontsize(plot_cfg.tick_fsize) for yticklabel in yaxis.get_ticklabels(): yticklabel.set_fontsize(plot_cfg.tick_fsize) plt.xlabel(labels[0], fontsize=plot_cfg.axislabel_fsize) plt.ylabel(labels[1], fontsize=plot_cfg.axislabel_fsize) # set xy axis limit if lowers is not None: ax.set_xlim(left=lowers[0]) ax.set_ylim(bottom=lowers[1]) if uppers is not None: ax.set_xlim(right=uppers[0]) ax.set_ylim(top=uppers[1]) if steps is not None: xmin, xmax = plt.xlim() plt.xticks(numpy.arange(xmin, xmax + steps[0] * 0.99, step=steps[0])) ymin, ymax = plt.ylim() plt.yticks(numpy.arange(ymin, ymax + steps[1] * 0.99, step=steps[1])) plt.legend(fontsize=plot_cfg.legend_fsize, loc=2) # loc 2: upper left, 4: lower right, 0: best plt.tight_layout() save_png_eps(plt, ws, filename, plot_cfg) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def empirical_cdf(out_values, subsections, input_sample, names, levels, outpath, outname, param_dict): """Visualize the empirical cumulative distribution function(CDF) of the given variable (x) and subsections of y. """ # prepare data if not isinstance(out_values, numpy.ndarray): out_values = numpy.array(out_values) out_max = numpy.max(out_values) out_min = numpy.min(out_values) if isinstance(subsections, int): if subsections <= 0: raise ValueError('subsections MUST be a integer greater than 0, or list.') step = (out_max - out_min) / subsections subsections = numpy.arange(out_min, out_max + step, step) if isinstance(subsections, list) and len(subsections) == 1: # e.g., [0] section_pt = subsections[0] if out_min < section_pt < out_max: subsections = [out_min, section_pt, out_max] else: subsections = [out_min, out_max] labels = list() new_input_sample = list() for i in range(1, len(subsections)): decimal1 = 0 if int(subsections[i - 1]) == float(subsections[i - 1]) else 2 decimal2 = 0 if int(subsections[i]) == float(subsections[i]) else 2 if out_max == subsections[i] and out_min == subsections[i - 1]: labels.append('%s=<y<=%s' % ('{0:.{1}f}'.format(subsections[i - 1], decimal1), '{0:.{1}f}'.format(subsections[i], decimal2))) zone = numpy.where((subsections[i - 1] <= out_values) & (out_values <= subsections[i])) elif out_max == subsections[i]: labels.append('y>=%s' % '{0:.{1}f}'.format(subsections[i - 1], decimal1)) zone = numpy.where(subsections[i - 1] <= out_values) elif out_min == subsections[i - 1]: labels.append('y<%s' % ('{0:.{1}f}'.format(subsections[i], decimal2))) zone = numpy.where(out_values < subsections[i]) else: labels.append('%s=<y<%s' % ('{0:.{1}f}'.format(subsections[i - 1], decimal1), '{0:.{1}f}'.format(subsections[i], decimal2))) zone = numpy.where((subsections[i - 1] <= out_values) & (out_values < subsections[i])) new_input_sample.append(input_sample[zone, :][0]) fig = plt.figure() num_vars = len(names) row, col = cal_row_col_num(num_vars) for var_idx in range(num_vars): ax = fig.add_subplot(row, col, var_idx + 1) for ii in range(len(labels) - 1, -1, -1): ax.hist(new_input_sample[ii][:, var_idx], bins=levels, normed=True, cumulative=True, label=labels[ii], **param_dict) ax.get_yaxis().set_major_locator(LinearLocator(numticks=5)) ax.set_ylim(0, 1) ax.set_title('%s' % (names[var_idx])) ax.get_xaxis().set_major_locator(LinearLocator(numticks=3)) ax.tick_params(axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='on', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='on') # labels along the bottom edge are off) ax.tick_params(axis='y', # changes apply to the y-axis which='major', # both major and minor ticks are affected length=3, right='off') if var_idx % col: # labels along the left edge are off ax.tick_params(axis='y', labelleft='off') if var_idx == 0: ax.legend(loc='lower right', fontsize='xx-small', framealpha=0.8, bbox_to_anchor=(1, 0), borderaxespad=0.2, fancybox=True) plt.tight_layout() save_png_eps(plt, outpath, outname) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()
def plot_pareto_fronts( pareto_data, # type: Dict[AnyStr, Dict[Union[AnyStr, int], Union[List[List[float]], numpy.ndarray]]] xname, # type: List[AnyStr, Optional[float], Optional[float]] yname, # type: List[AnyStr, Optional[float], Optional[float]] gens, # type: List[int] ws # type: AnyStr ): # type: (...) -> None """ Plot Pareto fronts of different methods at a same generation for comparision. Args: pareto_data(OrderedDict) xname(list): the first is x-axis name of plot, the second and third values are low and high limits (optional). yname(list): see xname gens(list): generation to be plotted ws: workspace for output files """ if len(xname) < 1 or len(yname) < 1: xname = ['x-axis'] yname = ['y-axis'] ylabel_str = yname[0] xlabel_str = xname[0] file_name = '-'.join(list(pareto_data.keys())) plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['font.family'] = 'Palatino Linotype' # 'Times New Roman' # Check if xname or yname contains Chinese characters zhPattern = re.compile(u'[\u4e00-\u9fa5]+') if zhPattern.search(xname[0]) or zhPattern.search(yname[0]): plt.rcParams['font.family'] = 'SimSun' # 宋体 markers = ['.', '*', '+', 'x', 'd', 'h', 's', '<', '>'] colors = ['r', 'b', 'g', 'c', 'm', 'y', 'k', 'k', 'k'] # linestyles = ['-', '--', '-.', ':'] # # plot accumulate pop size # fig, ax = plt.subplots(figsize=(9, 8)) # mark_idx = 0 # for method, gen_popsize in acc_pop_size.items(): # xdata = gen_popsize[0] # ydata = gen_popsize[1] # print(ydata) # print('Evaluated pop size: %s - %d' % (method, ydata[-1])) # plt.plot(xdata, ydata, linestyle=linestyles[mark_idx], color='black', # label=method, linewidth=2) # mark_idx += 1 # plt.legend(fontsize=24, loc=2) # xaxis = plt.gca().xaxis # yaxis = plt.gca().yaxis # for xlebal in xaxis.get_ticklabels(): # xlebal.set_fontsize(20) # for ylebal in yaxis.get_ticklabels(): # ylebal.set_fontsize(20) # plt.xlabel('Generation count', fontsize=20) # plt.ylabel('Total number of simulated individuals', fontsize=20) # ax.set_xlim(left=0, right=ax.get_xlim()[1] + 2) # plt.tight_layout() # fpath = ws + os.path.sep + file_name + '_popsize' # plt.savefig(fpath + '.png', dpi=300) # plt.savefig(fpath + '.eps', dpi=300) # print('%s saved!' % fpath) # # close current plot in case of 'figure.max_open_warning' # plt.cla() # plt.clf() # plt.close() # plot Pareto points of all generations # mark_idx = 0 # for method, gen_popsize in pareto_data.items(): # fig, ax = plt.subplots(figsize=(9, 8)) # xdata = list() # ydata = list() # for gen, gendata in gen_popsize.items(): # xdata += gen_popsize[gen][xname[0]] # ydata += gen_popsize[gen][yname[0]] # plt.scatter(xdata, ydata, marker=markers[mark_idx], s=20, # color=colors[mark_idx], label=method) # mark_idx += 1 # xaxis = plt.gca().xaxis # yaxis = plt.gca().yaxis # for xlebal in xaxis.get_ticklabels(): # xlebal.set_fontsize(20) # for ylebal in yaxis.get_ticklabels(): # ylebal.set_fontsize(20) # plt.xlabel(xlabel_str, fontsize=20) # plt.ylabel(ylabel_str, fontsize=20) # # set xy axis limit # curxlim = ax.get_xlim() # if len(xname) >= 3: # if curxlim[0] < xname[2]: # ax.set_xlim(left=xname[2]) # if len(xname) >= 4 and curxlim[1] > xname[3]: # ax.set_xlim(right=xname[3]) # curylim = ax.get_ylim() # if len(yname) >= 3: # if curylim[0] < yname[2]: # ax.set_ylim(bottom=yname[2]) # if len(yname) >= 4 and curylim[1] > yname[3]: # ax.set_ylim(top=yname[3]) # plt.tight_layout() # fpath = ws + os.path.sep + method + '-Pareto' # plt.savefig(fpath + '.png', dpi=300) # plt.savefig(fpath + '.eps', dpi=300) # print('%s saved!' % fpath) # # close current plot in case of 'figure.max_open_warning' # plt.cla() # plt.clf() # plt.close() # plot comparision of Pareto fronts # Get max. and mix. values max_x = None min_x = None max_y = None min_y = None for method, cur_pareto_data in viewitems(pareto_data): if 'min' in cur_pareto_data: if min_x is None or min_x > cur_pareto_data['min'][0]: min_x = cur_pareto_data['min'][0] if min_y is None or min_y > cur_pareto_data['min'][1]: min_y = cur_pareto_data['min'][1] if 'max' in cur_pareto_data: if max_x is None or max_x < cur_pareto_data['max'][0]: max_x = cur_pareto_data['max'][0] if max_y is None or max_y < cur_pareto_data['max'][1]: max_y = cur_pareto_data['max'][1] newxname = xname[:] newyname = yname[:] if min_x is not None and max_x is not None and len(newxname) < 2: newxname += get_optimal_bounds(min_x, max_x) if min_y is not None and max_y is not None and len(newyname) < 2: newyname += get_optimal_bounds(min_y, max_y) for gen in gens: fig, ax = plt.subplots(figsize=(9, 8)) mark_idx = 0 gen_existed = True for method, gen_data in viewitems(pareto_data): if gen not in gen_data: gen_existed = False break xdata = numpy.array(gen_data[gen])[:, 0] # first column ydata = numpy.array(gen_data[gen])[:, 1] # second column plt.scatter(xdata, ydata, marker=markers[mark_idx], s=100, color=colors[mark_idx], label=method) mark_idx += 1 if not gen_existed: plt.cla() plt.clf() plt.close() continue xaxis = plt.gca().xaxis yaxis = plt.gca().yaxis for xlebal in xaxis.get_ticklabels(): xlebal.set_fontsize(20) for ylebal in yaxis.get_ticklabels(): ylebal.set_fontsize(20) plt.xlabel(xlabel_str, fontsize=20) plt.ylabel(ylabel_str, fontsize=20) # set xy axis limit curxlim = ax.get_xlim() if len(newxname) >= 3: ax.set_xlim(left=newxname[1]) ax.set_xlim(right=newxname[2]) curylim = ax.get_ylim() if len(newyname) >= 3: ax.set_ylim(bottom=newyname[1]) ax.set_ylim(top=newyname[2]) plt.legend(fontsize=16, loc=4) # loc 2: upper left, 4: lower right plt.tight_layout() save_png_eps(plt, ws, 'gen%d' % gen) # close current plot in case of 'figure.max_open_warning' plt.cla() plt.clf() plt.close()