Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
 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()
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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()